Po ajax isModal: true a modal(‚show‘) přestane fungovat modal

pavelinnuendo
Člen | 31
+
0
-

Ahoj,
potřebuji otevřít modal okno po ajaxovém požadavku.

V presenteru zavolám:

$this->payload->isModal = TRUE;

provede se ajax požadavek v němž je isModal: true a zpracuje se js kód:

$.nette.ext("modals", {
    success: function(payload) {
        if(payload.isModal) {
            console.log('modal ok');
            $('.modal-ajax').modal('show');
        }
    }
});

Tedy až sem vše ok (v konzoli i vidím ten log „modal ok“), ale to modal okno se neotevře a od té chvíle jej nelze otevřít ani tlačítkem. Přestanou fungovat obě varianty:

<button onclick="$('.modal-ajax').modal('toggle');">modal</button>
<button type="button" data-toggle="modal" data-target="#gridSystemModal">modal</button>

Pokud ten modal(‚show‘) zakomentuji, tlačítka fungují i po načtení toho ajaxu.

Čím by to mohlo být a jak bych to mohl debugovat?

Díky.

Petr Parolek
Člen | 443
+
+1
-

Ahoj,

taky jsem se nedáívno trápil s modalem a AJAXem, tady máš ukázkový projekt https://github.com/…test-project .

P.S. nette.ajax.js je mrtvé velmi dlouho

Editoval ppar (23. 12. 2020 18:45)

Petr Parolek
Člen | 443
+
0
-

Pro budoucí generace posílám ukázky:

app/Presenters/BasePresenter.php

public function beforeRender()
{
    if ($this->isAjax() && (bool)$this->getParameter('isModal')) {
        $this->payload->showModal = true;
        $this->payload->modalId = 'myModal';
        $this->redrawControl("modal");
    }
}

app/Presenters/HomepagePresenter.php

public function createComponentTestForm()
{
    $form = new Form();

    $form->addText('test', 'Test foo');

    $form->onSuccess[] = [$this, 'testFormSucceeded'];

    return $form;
}

@layout.latte:

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="{$basePath}/node_modules/bootstrap/dist/css/bootstrap.css">

    <title>{ifset title}{include title|stripHtml} | {/ifset}Nette Web</title>
</head>
<body>

<main role="main" class="flex-shrink-0">
	<div class="container">
		<div class="jumbotron mt-3">
			{include #content}
		</div>
	</div>
</main>

{snippet modal}
    {if $presenter->isAjax()}
        {ifset #modal}
            <!-- Modal -->
            <div class="modal fade modal-ajax" id="myModal" tabindex="-1" role="dialog"
                 aria-labelledby="myModalLabel" aria-hidden="true">
                <div class="modal-dialog modal-lg" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h4 class="modal-title">{block |stripHtml}{include #title}{/block}</h4>

                            <button class="close" type="button" data-dismiss="modal" aria-label="Close">
                                <span aria-hidden="true">×</span>
                            </button>
                        </div>
                        <div class="modal-body">
                            {include #modal}
                        </div>
                        {ifset #modalFooter}
                            <div class="modal-footer">
                                {include #modalFooter}
                            </div>
                        {/ifset}
                    </div>
                    <!-- /.modal-content-->
                </div>
                <!-- /.modal-dialog-->
            </div>
            <!-- /.modal-->
        {/ifset}
    {/if}
{/snippet}

<script src="{$basePath}/node_modules/jquery/dist/jquery.min.js"></script>
<script src="{$basePath}/node_modules/popper.js/dist/umd/popper.min.js"></script>
<script src="{$basePath}/node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="{$basePath}/node_modules/naja/dist/Naja.min.js"></script>
<script src="{$basePath}/js/modal.ext.js"></script>
<script type="module">
    naja.registerExtension(new ModalExtension());
    document.addEventListener('DOMContentLoaded', () => naja.initialize());
</script>
</body>
</html>

www/js/modal.ext.js:

/* global naja, $, intervalFunction */
class ModalExtension {
    initialize(naja) {
        naja.addEventListener('complete', this.openModal.bind(this));
    }

    openModal(event) {
        let payload = event.detail.payload;

        if (payload === null || !payload.hasOwnProperty('modalId')) {
            return;
        }
        let modalId = payload.modalId;
        let showModal = payload.showModal;
        if (showModal === undefined || showModal === false) {
            return;
        }
        $("#" + modalId).modal('show');
    }
}

app/Presenters/templates/Homepage/edit.latte

{block content}

<h1 n:block="title">Edit form</h1>

{block modal}
    {control testForm}
{/block}

Editoval ppar (23. 12. 2020 18:44)

pavelinnuendo
Člen | 31
+
0
-

Díky moc za super demo! Sice přesně tomu jsem se chtěl zatím vyhnout, ale vyměnil jsem nette.ajax.js za naja.js a hned to začalo fungovat správně. Tak snad to pro změnu nerozbilo nic jiného. :)

jval
Člen | 36
+
0
-

@PetrParolek díky moc, tohle mi pomohlo. Form do modalu už mi pěkně vyskakuje. K dokonalosti tomu chybí už jen to aby po úspěšné serverové validaci se modal zavřel a při neúspěšné se zobrazili chyby přímo v tom modalu nad formem.

Petr Parolek
Člen | 443
+
0
-

@jval nudu rád, když pošleš pull request s řešením..

jval
Člen | 36
+
0
-

@PetrParolek to bych strašně rád, ale s JS zas takovej kámoš nejsem.