Ajax - 7. lekce
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Ajax - 7. lekceAjax - 7. lekce

 

Ajax - 7. lekce

Google       Google       6. 11. 2008       34 208×

V dnešním díle se naučíme validovat formuláře pomocí Ajaxu.

Validace formuláře pomocí Ajaxu

V knize Ajax - vytváříme vysoce interaktivní webové aplikace nám autor předkládá odpověď na otázku, kdy začít s webovými aplikacemi v Ajaxu. Doporučuje začít u kontroly vstupu uživatele ve formuláři a to si dnes také předvedeme.

Použitím Ajaxu u věcí typu ověření vstupu uživatele odstraníme nutnost opětovného načtení stránky při neúspěšné validaci na straně serveru a nebudeme také nuceni použít primitivní JavaScriptové funkce, které nám nikdy nezaručí 100% výsledek. Stále hrozí, že uživatel bude mít JavaScript vypnutý. Nyní se určitě ptáte, v čem je tedy ověření dat pomocí technologie Ajax tak světoborné. Pokud má klient vypnutý JavaScript, neměl by mu fungovat ani Ajax. Ano, je to sice pravdivé tvrzení, ale Ajax nám umožňuje provést kontrolu dat na straně serveru pomocí stejného scriptu, který můžeme použít k validaci dat i po odeslání formuláře. V případě, že má uživatel zapnutý JavaScript, se kontrola bude provádět asynchronně na straně serveru. Pokud uživatel má JavaScript vypnutý, kontrola se provede pouze po odeslání na straně serveru, v případě neúspěchu se uživatel nevyhne znovu načtení stránky. Pro demonstraci celého procesu slouží následující ilustrace.

V následující části se zaměříme na samotnou kontrolu dat Ajaxem. Pomocí objektu Just in time na straně serveru.

Tvorba kódu

Formulář, který chceme vytvořit, bude obsahovat tyto položky: přezdívku, jméno, příjmení a e-mail. Naše registrace bude používat tři JavaScriptové funkce:

  • vytvorXHR() - pro nás již známá funkce pro vytvoření objektu XMLHttpRequest
  • vytvorPozadavek() - funkce pro vytvoření požadavku objektu XMLHttpRequest s několika malými změnami
  • validace() - funkce, která pomocí XML zajistí komunikaci se scriptem na straně serveru

Kromě těchto tří funkcí využijeme také pole, které pojmenujeme cache. Toto pole nám bude sloužit jako fronta. V případě, že bude objekt XHR zaneprázdněný, uložíme požadavek do fronty a počkáme, až bude mít XHR na tyto požadavky čas.

var cache = new Array();

Jako první si vytvoříme HTML soubor s formulářem pro registraci. Stránka by mohla vypadat nějak takto:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="cs">
  <head>
    <meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
    <meta http-equiv="content-language" content="cs" />
    <meta http-equiv="pragma" content="no-cache" />
    <meta http-equiv="cache-control" content="no-cache, must-revalidate" />
    <meta http-equiv="expires" content="0" />
    <meta name="generator" content="PSPad editor, www.pspad.com" />
    <meta name="author" content="all: Petr 'plasmo' Láslo; mailto: plasmo@plasmo.cz; web: http://plasmo.cz" />
    <script src="js.js" type="text/javascript"></script>
    <title>Registrace uživatele</title>
  </head>
  <body onload="document.getElementById('nick').focus()">
    <fieldset>
      <legend>Registrace uživatele</legend>
      <form action="#" method="post">
        <table border="0">
          <tr>
            <td><label for="nick">Nick:</label></td>
            <td><input type="text" name="nick" id="nick" value="" onblur="vytvorPozadavek(this.id,this.value)" /></td>
            <td><div id="nickZprava"></div></td>
          </tr>
          <tr>
            <td><label for="jmeno">Jméno:</label></td>
            <td><input type="text" name="jmeno" id="jmeno" onblur="vytvorPozadavek(this.id, this.value)" /></td>
            <td><div id="jmenoZprava"></div></td>
          </tr>
          <tr>
            <td><label for="prijmeni">Přijmení:</label></td>
            <td><input type="text" name="prijmeni" id="prijmeni" onblur="vytvorPozadavek(this.id, this.value)" /></td>
            <td><div id="prijmeniZprava"></div></td>
          </tr>
          <tr>
            <td><label for="email">E-mail:</label></td>
            <td><input type="text" name="email" id="email" onblur="vytvorPozadavek(this.id, this.value)" /></td>
            <td><div id="emailZprava"></div></td>
          </tr>
        </table>   
      </form>
    </fieldset>
  </body>
</html>

Tvorba HTML souboru musí být všem jasná. Upozorním jen na pár drobností.

  1. Prohlížeči musíme zakázat ukládání dat do cache:
  2. ...
    <meta http-equiv="pragma" content="no-cache" />
    <meta http-equiv="cache-control" content="no-cache, must-revalidate" />
    <meta http-equiv="expires" content="0" />
    ...
  3. Ukazatel nastavíme na první položku formuláře:
  4. ...
    <body onload="document.getElementById('nick').focus()">
    ...
  5. K odpálení požadavku použijeme událost onblur:
  6. ...
    ... onblur="vytvorPozadavek(this.id, this.value)" />
    ...

Další soubor, který vytvoříme, bude obsahovat funkce JavaScriptu. Opět standartně pojmenovaný - js.js

  1. Jako první vytvoříme proměnné XHR a cache. Jak jsem se učili již na začátku kurzu, v proměnné xhr bude uložen odkaz na objekt XHR a proměnná cache bude obsahovat frontu požadavků.
  2. var xhr = vytvorXHR();
    var cache = new Array();
  3. Druhá funkce, kterou již nebudu ani popisovat (naučili jsme se ji tvořit v 1. lekci kurzu), je vytvorXHR():
  4. function vytvorXHR(){
      var xhr;
      try{
        xhr = new XMLHttpRequest();
      }catch(e){//pro případ starší verze prohlížeče
        var MSXmlVerze = new Array('MSXML2.XML.Http.6.0','MSXML2.XML.Http.5.0','MSXML2.XML.Http.4.0','MSXML2.XML.Http.3.0','MSXML2.XML.Http.2.0','Microsoft.XML.Http');
        for(var i = 0; i < MSXmlVerze.lenght; i ++){
          try{
            xhr = new ActiveXObject(MSXmlVerze[i]);
          }catch(e){
            //vzniklou chybu ignoruji a pokračuji nastavením další verze
          }
        }
      }
      if(!xhr)
        alert("Došlo k chybě při vytváření objektu XMLHttpRequest!");
      else
        return xhr;
    }
  5. Další funkce, kterou budeme tvořit, je vytvorPozadavek(). Funkci oproti předchozím dílům trochu upravíme. Bude přebírat dva parametry - id prvku a hodnotu prvku. První změnou je rozšíření o podmínku, která kontroluje existenci prvku id. Pokud se kontrola vyhodnotí jako pravda, přidá požadavek do fronty. Další drobnou změnou je přidání podmínky do části try, díky které vytvoříme požadavek jen v případě, že XHR nemá zrovna nic na práci a zároveň jen tehdy, když fronta není prázdná. Další změnou je použití metody xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); objektu XHR pro nastavení MIME typů. Poslední malou změnou je předání cache jako parametru metody xhr.send(cacheVstup);. Funkce bude vypadat následovně:
  6. function vytvorPozadavek(id,hodnota){
    if(xhr){
      if(id){
        //zakoduji hodnoty
        id = encodeURIComponent(id);
        hodnota = encodeURIComponent(hodnota);
        //vložím hodnoty do fronty
        cache.push("id="+id+"&hodnota="+hodnota);
      }
      try{
        //pokračovat budu jen v případě že cache není prázdná a objekt
        //XHR nemá co na práci
        if((xhr.readyState == 4 || xhr.readyState == 0)&& cache.length > 0){
          //z cache načtu další hodnotu
          var cacheVstup = cache.shift();
          xhr.open("POST","http://programujte.com/page/200808251506_validace.php",true);
          xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
          xhr.onreadystatechange = validace;
          xhr.send(cacheVstup);
        }
      }catch(e){
        alert("Nelze se připojik k serveru:\n" + e.toString());
      }
    }else{
      alert("Funkce \"precitSoubor()\": chybí objekt XMLHttpRequest");
    }
    }
  7. Třetí a poslední funkcí, kterou vytvoříme, je funkce validace(). Tato funkce je velmi podobná té z minulého dílu. Opět přečte dokument XML a zobrazí jej na webové stránce. Nyní vám ukáži, jak celá funkce vypadá, a následně Vás upozorním na odlišnost od funkce ctiOdpoved() z minulého dílu. Zde máte slíbenou funkci:
  8. function validace(){
      if(xhr.readyState == 4){
        if(xhr.status == 200){
          var XMLRes = xhr.responseXML;
            //zachycení chyb IE a Opery
            if(!XMLRes || !XMLRes.documentElement){
              throw("Chybná struktura XML:\n"+xhr.responseText);
            }
            //zachycení chyb ohnivé lišky :-)
            var rootNodeName = XMLRes.documentElement.nodeName;
            if(rootNodeName == "parsereerror"){
              throw("Chybná struktura XML:\n"+xhr.responseText);
            }
            //čtu dokument, jelikož je vše ok :-)
            xmlRoot = XMLRes.documentElement;
            odpoved = xmlRoot.getElementsByTagName("odpoved")[0].firstChild.data;
            stav = xmlRoot.getElementsByTagName("stav")[0].firstChild.data;
            id = xmlRoot.getElementsByTagName("id")[0].firstChild.data;
            zprava = document.getElementById(id+"Zprava");
            //alert(odpoved+" "+id+" "+zprava);
            if(odpoved == 0){          
              zprava.innerHTML = stav;
            }else{
              zprava.innerHTML = "";
            }
            
            setTimeout("vytvorPozadavek();", 500);
        }else{
          alert("Požadavek HTTP není v pořádku.")
        }
      }
    }
  9. Odlišnost, které si můžete všimnout, je podmínka, která vypisuje HTML kód na obrazovku. Pokud údaj neprojde validací, bude XML uzel stav obsahovat hodnotu 0. V tomto případě zobrazíme chybovou zprávu. V opačných případech nevypíšeme nic.
  10.  if(odpoved == 0){          
              zprava.innerHTML = stav;
            }else{
              zprava.innerHTML = "";
            }
  11. Poslední soubor, který vytvoříme, je validace.php. Jeho obsah bude totožný s podobnými soubory z minulých dílů. Jediné, co nám přibude, jsou hlavičky, které zamezí ukládání dat do cache, a logika pro ověření zadaných údajů. Kontrola probíhá následujícím způsobem: nejdřív dle id prvku rozhodneme, který prvek budeme vůbec kontrolovat (zda nick, jméno, přijmení atd.). Pomocí podmínky if/else přiřadíme hodnoty proměnným $hodnota2 a $zprava2.
  12. <?php
    header("Expires: Wed, 23 Dec 1980 00:30:00 GMT");
    header("Last-Modified:".gmdate("D, d M Y H:i:s")." GMT");
    header("Cache-Control: no-cache, must-revalidate");
    header("Pragma: no-cache");
    
    switch ($_REQUEST['id']) {
      case "nick":
        //pokud nick obsahuje hodnotu vracím 1 == true jinak 0 == false
        if($_REQUEST['hodnota']){
          $hodnota2 = 1;
          $zprava2 = " ";
        }else{
          $hodnota2 = 0;
          $zprava2 = "Musíte zadat nick!";
        }
    
        break;
      case "jmeno":
    	 if(empty($_REQUEST['hodnota'])){
         $hodnota2 = 0;
         $zprava2 = "Musíte zadat jméno!";
       }else{
         $hodnota2 = 1;
         $zprava2 = " ";
        }
    	 break;
    	case "prijmeni":
    	 if(empty($_REQUEST['hodnota'])){
         $hodnota2 = 0;
         $zprava2 = "Musíte zadat přijmení!";
       }else{
         $hodnota2 = 1;
         $zprava2 = " ";
       }
    	 break;
    	case "email":
      	if(!eregi("^[a-z0-9_.-]+@([a-z0-9_-]+\.)+[a-z]{2,4}$",$_REQUEST['hodnota'])){
      	       $hodnota2 = 0;
              $zprava2 = "E-mailová adresa musí být v platném tvaru!<br /> Příklad: pepa.nova@seznam.cz,pepa@seznam.cz,pepa-novak@seznam.cz<br />";
        }else{
         $hodnota2 = 1;
         $zprava2 = " ";
        }
      break;	
    }
    //výstup je XML dokument, proto odešlu správný mime-type
    header("Content-Type: text/xml");
    //tvořím nový XML
    $xml = new DOMDocument("1.0","utf-8");
    //vytvočím kořenový element zamesntanci
    $validace = $xml->createElement("validace");
    $xml->appendChild($validace);
    $vysledek = $xml->createElement("vysledek");
    //vytvorim element odpoved a vložím do něj data
    $odpoved = $xml->createElement("odpoved");
    $odpovedData = $xml->createTextNode($hodnota2);
    $odpoved->appendChild($odpovedData);
    //vytvorim element zprava a vložím do něj data
    $stav = $xml->createElement("stav");
    $stavData = $xml->createTextNode($zprava2);
    $stav->appendChild($stavData);
    //vytvorim element id a vložím do něj data
    $id = $xml->createElement("id");
    $idData = $xml->createTextNode($_REQUEST['id']);
    $id->appendChild($idData);
    
    $vysledek->appendChild($odpoved);
    $vysledek->appendChild($stav);
    $vysledek->appendChild($id);
    $validace->appendChild($vysledek);
    
    //uložím XML výstup
    $vystup= $xml->saveXML();
    //zobrazím
    echo $vystup;
    ?>

Závěr

Dnes jsme vytvořili druhou opravdu Ajaxovou webovou aplikaci. V dalším díle se můžete těšit na tvorbu okna s nápovědou.

Úkol

Pokuste se vylepšit naši Ajaxovou validaci tak, aby se v případě, kdy má uživatel vypnutý JavaScript, provedla na straně serveru.

×Odeslání článku na tvůj Kindle

Zadej svůj Kindle e-mail a my ti pošleme článek na tvůj Kindle.
Musíš mít povolený příjem obsahu do svého Kindle z naší e-mailové adresy kindle@programujte.com.

E-mailová adresa (např. novak@kindle.com):

TIP: Pokud chceš dostávat naše články každé ráno do svého Kindle, koukni do sekce Články do Kindle.

2 názory  —  2 nové  
Hlasování bylo ukončeno    
0 hlasů
Google
Student ČVUT FJFI katedry softwarového inženýrství v ekonomii. Mezi jeho zájmy patří programování a sport. Autor má zkušenosti s PHP 5, MySQL, XHTML a CSS. Zajímá se o platformu .NET, jazyk C#, ASP.NET a WPF.
Web    

Nové články

Obrázek ke článku Hybridní inteligentní systémy 2

Hybridní inteligentní systémy 2

V technické praxi využíváme často kombinaci různých disciplín umělé inteligence a klasických výpočtů. Takovým systémům říkáme hybridní systémy. V tomto článku se zmíním o určitém typu hybridního systému, který je užitečný ve velmi složitých výrobních procesech.

Obrázek ke článku Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Vedení týmu v oboru informačních technologií se nijak zvlášť neliší od jiných oborů. Přesto však IT manažeři čelí výzvě v podobě velmi rychlého rozvoje a tím i rostoucími nároky na své lidi. Udržet pozornost, motivaci a efektivitu týmu vyžaduje opravdu pevné manažerské základy a zároveň otevřenost a flexibilitu pro stále nové výzvy.

Obrázek ke článku Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Za poslední rok se podoba práce zaměstnanců změnila k nepoznání. Především plošné zavedení home office, které mělo být zpočátku jen dočasným opatřením, je pro mnohé už více než rok každodenní realitou. Co ale dělat, když se při práci z domova ztrácí motivace, zaměstnanci přestávají komunikovat a dříve fungující tým se rozpadá na skupinu solitérů? Odborníci na personalistiku dali dohromady několik rad, jak udržet tým v chodu, i když pracovní podmínky nejsou ideální.

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý