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

Ajax - 7. lekceAjax - 7. lekce

 

Ajax - 7. lekce

Google       Google       6. 11. 2008       29 031×

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

Reklama
Reklama

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 Delphi 10.1.2 (Berlin Update 2) – na co se můžeme těšit

Delphi 10.1.2 (Berlin Update 2) – na co se můžeme těšit

Touto roční dobou, kdy je zem pokrytá barevným listím a prsty křehnou v mrazivých ránech, se obvykle těšíme na zbrusu novou verzi RAD Studia. Letos si však ale budeme muset počkat na Godzillu a Linux až do jara. Vezměme tedy za vděk alespoň updatem 2 a jelikož dle vyjádření pánů z Embarcadero se budou nové věci objevovat průběžně, pojďme se na to tedy podívat.

Reklama
Reklama
Obrázek ke článku Konference: Moderní datová centra pro byznys dneška se koná už 24. 11.

Konference: Moderní datová centra pro byznys dneška se koná už 24. 11.

Stále rostoucí zájem o cloudové služby i maximální důraz na pružnost, spolehlivost a bezpečnost IT vedou k výrazným inovacím v datových centrech. V infrastruktuře datových center hraje stále významnější roli software a stále častěji se lze setkat s hybridními přístupy k jejich budování i provozu.

Obrázek ke článku Konference: Mobilní technologie mají velký potenciál pro byznys

Konference: Mobilní technologie mají velký potenciál pro byznys

Firmy by se podle analytiků společnosti Gartner měly  rychle přizpůsobit skutečnosti, že mobilní technologie už zdaleka nejsou horkou novinkou, ale standardní součástí byznysu. I přesto - nebo možná právě proto - tu nabízejí velký potenciál. Kde tedy jsou ty největší příležitosti? I tomu se bude věnovat již čtvrtý ročník úspěšné konference Mobilní řešení pro business.

Obrázek ke článku Hackerský kongres přiveze v září do Prahy špičky světové kryptoanarchie

Hackerský kongres přiveze v září do Prahy špičky světové kryptoanarchie

Hackerský kongres HCPP16 pořádá od 30. září do 2. října nezisková organizace Paralelní Polis již potřetí, a to ve stejnojmenném bitcoinovém prostoru v pražských Holešovicích. Letos přiveze na třídenní konferenci přes 40 většinou zahraničních speakerů – lídrů z oblastí technologií, decentralizované ekonomiky, politických umění a aktivismu. Náměty jejich přednášek budou také hacking, kryptoměny, věda, svoboda nebo kryptoanarchie.

loadingtransparent (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })();
Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý