Grunt + Bower: Ajax v Nette

Mám projekt v Nette ve kterém potřebuji rozjet Ajax. Na projektu mám již připraven Grunt (jak nainstalovat Grunt) a Bower (slibuji to dlouho ale o tom zase někdy příště).

Pro Ajax v Nette doporučuji nette.ajax.js (od Vojtěcha Dobeše). Nette.ajax.js samozřejmě nainstalujeme přes Bower:

bower install nette.ajax.js --save-dev

Pro automatizaci používám Grunt (jak nainstalovat Grunt), do kterého existuje nepřeberné množství doplňků.

Pro spojení více .js souborů do jednoho používám doplněk grunt-contrib-concat kde mám vytvořený následující task:

        concat: {
            js: {
                src: ['bower_components/jquery/dist/jquery.min.js',
                    'bower_components/nette.ajax.js/nette.ajax.js',
                    'vendor/nette/forms/src/assets/netteForms.js',
                    'www/js/main.js'],
                dest: 'www/js/compiled.js',
                nonull: true
            }
        },

V souboru compiled.js máme potřebné js soubory. Můžeme se pustit do další fáze.

Nette + Ajax

Ajaxace již funkčních částí je v Nette velice jednoduchá. Nyní mám vytvořený formulář který odesílá data. Po odeslání formuláře se znovu načte kompletně celá stránka. Tento skript vylepšíme, aby se po odeslání formuláře nemusela načítat komplet celá stránka ale pouze odeslaný formulář (u mne to je formulář s rezervací).

Pojďme si připravit inicializace knihovny nette.ajax.js do souboru main.js:

$(function () {
    $.nette.init();// And you fly... 
});

Mému formuláři stačí přidat class ajax:

$form = new Form;
$form->getElementPrototype()->class( 'ajax' );

V presenteru nyní máme funkci isAjax, která nám vrací TRUE pokud se jedná o Ajaxový požadavek.

Po odeslání formuláře se přesvědčíme zda byl odeslán Ajaxem:

    public function selectWorkshopFormSucceeded( $form, $values )
    {
        if ($this->isAjax()) {
            echo "fomulář odeslán AJAXem";
        }
        else
        {
            echo "fomulář nebyl odeslán AJAXem";
        }
        exit();
    }

V latte můžeme jednotlivé bloky zabalit do snippetu a nechat překreslit pouze tento snippet:

{snippet workshop}
   {control selectWorkshopForm}
{/snippet}
    public function selectWorkshopFormSucceeded( $form, $values )
    {
        if ($this->isAjax()) {
            $this->redrawControl( 'workshop' );//znovu vykresli snippet workshop
        }
        else
        {
            $this->redirect( 'this' );//znovu vykresli celou stranku
        }
    }

Proto Nette miluju!