Webové rozhraní je již téměř ekvivalentní standardnímu desktopovému rozhraní. Je možné, že formuláře budou brzy založené především na AJAX komunikaci se serverem a současný způsob jejich zpracování postupně ustoupí? Nároky na uživatelská rozhraní se stále zvyšují. Cení se také rychlost odezvy a snižování nároků na server. Jediný problém by mohl být ve zdánlivé komplikovanosti tohoto způsobu zpracování formulářů. V následujícím příspěvku uvádím skripty pro obsluhu formuláře AJAXem, avšak s validací na straně serveru.
Ukázka AJAX formuláře
index.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
<!doctype html> <html lang="cs"> <head> <meta charset="utf-8"> <title></title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <script> $(document).ready(function() { $('form').submit(function(event) { event.preventDefault(); // zamezení odeslání formuláře standardním způsobem $("div").remove(".err"); $("div").remove(".msg"); var formData = { 'kod_produktu' : $('input[name=kod_produktu]').val(), 'nazev_produktu' : $('input[name=nazev_produktu]').val() }; // odeslání dat formuláře na server $.ajax({ type : 'POST', //data zašleme způsobem POST url : 'ajax-form-update.php', // jaký php skript bude volán data : formData, //data z formuláře dataType : 'json', //jaká data očekáváme nazpět ze serveru encode : true }) // success .done(function(data) { $("form").after('<div class="msg">' + data.message + '</div>'); if(data.success == true) { $(".msg").css("color", "green"); console.log(data.message); } else { $.each(data.errors, function(index, value) { $('form :text[name="'+index+'"]').after('<div class="err">'+value+'</div>'); }); } }) //error ... spustí se pokud přijde ze serveru cokoliv kromě 200 .fail(function( jqXHR, textStatus, errorThrown ){ console.log('Status: '+textStatus+', Error: '+errorThrown); }); }); }); </script> <style> <!-- .err {color:red;} //--> </style> </head> <body> <div> <form id="formular1"> <input type="text" name="kod_produktu" size="5" value="" /><br /> <input type="text" name="nazev_produktu" size="15" value="" /><br /> <input type="submit" id="tlacitko_ulozit" name="submit" value=" Uložit " /> </form> </div> </body> </html> |
Validaci jsem v našem případě umístil do volaného php skriptu. Je to poněkud netradiční, ale jinak velmi spolehlivý způsob jak kontrolovat data z odeslaného formuláře. Alespoň máte ještě pocit, že je nějaký prostor pro php.
ajax-form-update.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?php $errors = array(); $data = array(); //data, která budeme posílat nazpět if (empty($_POST['kod_produktu'])){ $errors['kod_produktu'] = 'Kód produktu je nutné vyplnit.'; } if (empty($_POST['nazev_produktu'])){ $errors['nazev_produktu'] = 'Název produktu je nutné vyplnit.'; } if (empty($errors)) { //zde zpracujeme $_POST['kod_produktu'] a $_POST['nazev_produktu'] $output = "Kód produktu: ".$_POST['kod_produktu'].PHP_EOL."Název produktu:".$_POST['nazev_produktu'].PHP_EOL; //tzn. například je uložíme do databáze. //Nyní však pro jednoduchost uložíme data do souboru: $dataFileHandler = fopen('data.txt', 'a'); fprintf ($dataFileHandler, "%s", $output); //potom připravíme zprávu pro skript, který provedl volání této rutiny $data['success'] = true; $data['message'] = 'Update proběhl úspěšně'; } else { $data['success'] = false; $data['errors'] = $errors; $data['message'] = 'Při ukládání dat se vyskytly chyby!'; } echo json_encode($data); ?> |
Jak oba skripty fungují?
Po stisknutí tlačítka sumbit dojde ke spuštění javascriptu:
1 2 3 4 |
$('form').submit(function(event) { event.preventDefault(); ... |
Ve druhém řádku vidíte způsob jak zajistit, aby nedošlo ke standardnímu odeslání formuláře.
Data z formuláře načteme funkcí val() a sice do pole formData.
1 2 3 4 |
var formData = { 'kod_produktu' : $('input[name=kod_produktu]').val(), 'nazev_produktu' : $('input[name=nazev_produktu]').val() }; |
Data formData odešleme metodou POST a sice php skriptu ajax-form-update.php. Ten poté pracuje přímo s $_POST[‚kod_produktu‘] a $_POST[‚nazev_produktu‘].
Z php odešleme zprávu ve formátu json, což bude javascript očekávat díky uvedení v položce dataType. JSON = JavaScript Object Notation a vypadá např. takto:
1 |
{"a":1,"b":2,"c":3,"d":4,"e":5} |
1 2 3 4 5 6 7 |
$.ajax({ type : 'POST', //data zašleme způsobem POST url : 'ajax-form-update.php', // jaký php skript bude volán data : formData, //data z formuláře dataType : 'json', //jaká data očekáváme nazpět ze serveru encode : true }) |
JSON je všude a dle mého názoru kvalitně vytlačí XML, kterému jsem nikdy nepřišel na chuť.
Dříve se pro vyhodnocení odezvy serveru používaly funkce success: a error:. Nyní jsou nahrazené funkcemi done() a fail(). (Můžete je zřetězit i s funkcí always(), která se vykonává vždy.) Funkce done() je volána při úspěšném vykonání php skriptu ajax-update-form.php. Funkce fail se vykoná pokud přijde jakákoliv jiná odezva než 200.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// success .done(function(data) { $("form").after('<div class="msg">' + data.message + '</div>'); if(data.success == true) { $(".msg").css("color", "green"); console.log(data.message); } else { $.each(data.errors, function(index, value) { $('form :text[name="'+index+'"]').after('<div class="err">'+value+'</div>'); }); } }) //error ... spustí se pokud přijde ze serveru cokoliv kromě 200 .fail(function( jqXHR, textStatus, errorThrown ){ console.log('Status: '+textStatus+', Error: '+errorThrown); }); |
Je nutné správně rozlišovat mezi chybami způsobenými komunikací se serverem a chybami způsobenými při vyplňování formuláře. Pole errors, které generuji ve skriptu ajax-form-update.php nemá s chybami na které reaguje funkce fail() naprosto nic společného!
Povšimněte si zejména, jak lze zobrazovat chybně zadané hodnoty do formuláře pomocí jednoduché iterace pole errors:
1 2 3 |
$.each(data.errors, function(index, value) { $('form :text[name="'+index+'"]').after('<div class="err">'+value+'</div>'); }); |
Chyby způsobené komunikací se serverem se snažím poslat na výstup do konzole a mohu je sledovat pomocí FireBug.
1 2 3 |
.fail(function( jqXHR, textStatus, errorThrown ){ console.log('Status: '+textStatus+', Error: '+errorThrown); }); |
Balíček s výše uvedenými skripty obsahuje také soubor data.txt, do kterého zapisuje ajax-form-update.php vstupní data při úspěšné obsluze formuláře.
Na otázku zda AJAXem obsluhované formuláře vytlačí standardně zpracovávané formuláře neznám samozřejmě odpověď, ale každopádně vnímám poměrně velký tlak na postupné zavádění takto obsluhovaných formulářů.