Diskuze: Nette Ajax form, nette.ajax.js

PHP Nette Framework Nette framework Nette Ajax form, nette.ajax.js

Aktivity (1)
Avatar
Frederik Fako:9. března 21:43

Dobrý den, používám nette.ajax.js a potřebuji odeslat formulář pomocí ajaxu aby se nerefreshla stránka.
V prezenteru jsem si vytvořil formulář:

    public function createComponentEditForm(){
      return new Multiplier(function ($itemId) {
      $aktivni = $this->cesty->PathActive($itemId)->fetch();
      $dodavatele = $this->dodavatel->byPathID($itemId)->fetchPairs('DodavateleID', 'DodavateleNazev');
      $aktivniDodavatele = $this->dodavatel->byPathIDActive($itemId)->fetchPairs();
      $form = new Form;
      $form->getElementPrototype()->class = 'ajax';
      $form->setMethod('POST');
      $form->addText('naves','Návěs pro cestu:')
           ->setDefaultValue($aktivni->CestyNaves)
           ->setHtmlAttribute('placeholder','Návěs');
      $form->addCheckbox('RouteActive', 'Aktvní cesta:');
      $form->setDefaults(['RouteActive'=>$aktivni->CestyAktivni]);
      $form->addCheckboxList('dodavatele', NULL,$dodavatele);
      $form->setDefaults(array('dodavatele' => $aktivniDodavatele ));
      $form->addHidden('CestaID', $itemId);
      $form->addHidden('newDod');
      $form->addSubmit('Zmenit','Uložit změny pro routu')
               ->setHtmlAttribute('class','ajax');
      $form->addProtection(); // Ochrana proti Cross-Site Request Forgery
          $form->onSuccess[]=[$this,'EditFormSucceeded'];
          return $form;
    });
  }
public function editFormSucceeded($form,$values){
    $this->database->query('UPDATE Cesty SET CestyAktivni = ? WHERE CestyID = ?',$values->RouteActive,$values->CestaID);
   }

Nyní jej potřebuji přes Ajax odeslat a dostat se do editFormSucceeded metody. Četl jsem, že stačí přidat submit inputu ->setHtmlAttri­bute('class','a­jax'); ** Nebo jej přidat přímo formuláři přes ** $form->getElementPro­totype()->class = 'ajax'; Přímo formuláři. Vše jsem udělal, ale stránka se při odeslání stále refreshne.. Nevíte co s tím?

 
Odpovědět 9. března 21:43
Avatar
Odpovídá na Frederik Fako
Martin Konečný (pavelco1998):9. března 22:03

Ahoj, zkontroluj si, jestli máš někde na začátku (nejlíp hned za <body>) zavoláno

$.nette.init();

případně když odešleš formulář, tak jestli konzole nepíše nějakou chybu.

Nahoru Odpovědět 9. března 22:03
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Frederik Fako:9. března 22:17

Hází to totu chybu:
Screenshot
Jinak

$.nette.init();

Mám vloženo v @layout.latte

{**
 * @param string   $basePath web base path
 * @param array    $flashes  flash messages
 *}
<!DOCTYPE html>
<html>
        {block head}
        <title>Project </title>
        <link href = "{$basePath}/LOGOs.png" rel="icon">
        <meta name="author" content="Frederik Fako">
    <link href="{$basePath}/css/style.less" rel="stylesheet/less" type="text/css">
    <link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet'  type='text/css'>
    <meta charset="UTF-8">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script src="{$basePath}/js/nette-aj/nette.ajax.js"></script>

        <meta name=viewport content="width=device-width, initial-scale=0.8, user-scalable=yes">
        <meta name="viewport" content="width=650">
        {/block}


<body>

        <div n:foreach="$flashes as $flash" n:class="flash, $flash->type">{$flash->message}</div>
        <div id="wrapp">
        <div id="content">
                <div id="header">
                        <img src="{$basePath}/LOGO.png" id="logo">
                </div>
                <hr>
        {include content}
                </div>

</div>

</body>
<script>
$.nette.init();
</script>
{block scripts}

        <script src="{$basePath}/js/less.js"></script>
        {/block}
        <div style="display:none;">
</html>
 
Nahoru Odpovědět 9. března 22:17
Avatar
Frederik Fako:9. března 23:04

Tak jsem koukal na dokumentaci a upravil Latte:

<div id="routeInfo">
{snippet routeContainer}
   {foreach $cesty as $item}
   <div class="routewrapp hidden" id="Route-{$item->CestyID}">
   {snippet route-$item->CestyID}
      {form editForm-$item->CestyID}
      <div>{$item->CestyNazev}</div>
      <div>{label RouteActive:0}{input RouteActive:1} <br>
      <a class="my-link" onclick="return confirm('Opravdu chcete smazat cestu?')" n:href="deletePath! $item->CestyID">Smazat cestu</a>
      </div>
      <div>
      {label naves} {input naves}
      </div>
      <div>
     <div>
         <table rules="all">
            <tr>
               <td></td>
               <td>Název dodavatele</td>
               <td>Aktivní</td>
            </tr>
            {foreach $form[dodavatele]->items as $key => $label}
            <tr id="{$key},{$item->CestyID}">
               <td><a onclick="OdebratDodavatele({$key},{$item->CestyID},this);">Odebrat</a></td>
               <td>{$label}</td>
               <td><input n:name="dodavatele:$key"></td>
            </tr>
            {/foreach}
         </table>
     </div>
         {input Zmenit}
      </div>
      {/form}
      {/snippet}
   </div>
   {/foreach}
   {/snippet}
</div>

Nyní však nevím jak se po odeslání dostat do editFormSucceeded metody :-(
Každopádně konzole stále hází stejnou chybu Chyba

 
Nahoru Odpovědět 9. března 23:04
Avatar
Odpovídá na Frederik Fako
Martin Konečný (pavelco1998):9. března 23:41

Zřejmě ti tam chybí nalinkované NetteForms. Pokud jsi Nette stahoval přes composer, měl bys tam ten JS soubor mít, případně můžeš externě nalinkovat https://nette.github.io/…Forms.min.js (doporučoval bych ale mít soubor u sebe).

A raději bych to přesunul hned za začátek <body>, ne až za konec. Tedy

<body>
<script src="{$basePath}/js/netteForms.js"></script>
<script src="{$basePath}/js/nette.ajax.js"></script>
<script>
$.nette.init();
</script>
Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
Nahoru Odpovědět  +1 9. března 23:41
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Frederik Fako:9. března 23:49

Tak jsem je tam přidal a chyba je pryč mockrát díky!
Teď už jen vyřeším to proč se to stále refreshuje a proč se nedostanu do editFormSucceeded

 
Nahoru Odpovědět 9. března 23:49
Avatar
Frederik Fako:10. března 0:02

Nakonec jsem to tedy zkusil udělat takto:

      public function createComponentEditForm(){
        return new Multiplier(function ($itemId) {
        $aktivni = $this->cesty->PathActive($itemId)->fetch();
        $dodavatele = $this->dodavatel->byPathID($itemId)->fetchPairs('DodavateleID', 'DodavateleNazev');
        $aktivniDodavatele = $this->dodavatel->byPathIDActive($itemId)->fetchPairs();
        $form = new Form;
        $form->setMethod('POST');
        $form->getElementPrototype()->class = 'ajax';
        $form->addText('naves','Návěs pro cestu:')
             ->setDefaultValue($aktivni->CestyNaves)
             ->setHtmlAttribute('placeholder','Návěs');
        $form->addCheckbox('RouteActive', 'Aktvní cesta:');
        $form->setDefaults(['RouteActive'=>$aktivni->CestyAktivni]);
        $form->addCheckboxList('dodavatele', NULL,$dodavatele);
        $form->setDefaults(array('dodavatele' => $aktivniDodavatele ));
        $form->addHidden('CestaID', $itemId);
        $form->addHidden('newDod');
        $form->addSubmit('Zmenit','Uložit změny pro routu')
             ->onClick[] = [$this, 'send'];
        $form->addProtection(); // Ochrana proti Cross-Site Request Forgery
            return $form;
      });
    }
public function send(SubmitButton $button) {
        $values = $button->getForm()->getValues();
        bdump($this->isAjax());
        if ($this->isAjax()) {
            $button->getForm()->setValues(['naves' => NULL]);
            $this->flashMessage($values->naves);
            $this->redrawControl('flashes');
            $this->redrawControl('routeContainer');
        } else {
            $this->redirect('this');
        }
    }

A stránka se stále refreshe ( v konzoli už však žádná chyba nevyskakuje )
Protože

if ($this->isAjax()) {
...
}

Vrací False

Editováno 10. března 0:03
 
Nahoru Odpovědět 10. března 0:02
Avatar
Odpovídá na Frederik Fako
Martin Konečný (pavelco1998):10. března 0:39

Tak v tomhle upřímně nevím, protože nejsem zastánce automatizovaného posílání AJAX požadavků, tedy nevím přesně, kdy a jak to se třídou "ajax" funguje.

Případně můžeš zkusit umístit tuto část kódu někam na konec stránky (až za ty formuláře), tedy třeba těsně před konec </body>, jestli to bude fungovat:

$("form.ajax").on("submit", function() {
        var form = $(this);

        $.nette.ajax({
                url: form.attr("action"),
                method: "POST",
                data: form.serialize()
        });

        return false;
});

Edit: když tak prosím odpovídej skrze tlačítko "Odpovědět", jinak uživateli nepřijde notifikace na tvou reakci :D

Editováno 10. března 0:40
Nahoru Odpovědět 10. března 0:39
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Frederik Fako:10. března 0:57

Tak nakonec chybělo:

<script src="{$basePath}/js/main.js"></script>

Main.js:

$(function () {
        $.nette.init();
});

Nyní to vypadá nějak takto:

<body>
<script src="{$basePath}/js/netteForms.js"></script>
<script src="{$basePath}/js/nette-aj/nette.ajax.js"></script>
<script src="{$basePath}/js/main.js"></script>

Když jsem to měl normálně v tagu <script></script>
tak to nešlo.. Děkuji za všechny rady!

Editováno 10. března 0:59
 
Nahoru Odpovědět 10. března 0:57
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 9 zpráv z 9.