AJAX in forme

3 minute read

AJAX tehnologija postaja vedno bolj popularna, vedno več ljudi skače na ta vlak in se kiti z novo kratico, ki jo lahko dodajo v svoj CV. Poleg vseh tistih (X)HTML, CSS, DOM, JS, XML in ostalih, ki naj bi impresionirali bodočega delodajalca ali mogoče celo naročnika, se je sedaj pojavil tudi AJAX. Trese se gora, rodi se miš.

Neko obliko AJAXa sem uporabljal že vrsto let nazaj, vendar zadeve takrat pač nismo znali, niti se nam je ni zdelo vredno poimenovati. Resnici na ljubo si tudi ne bi zaslužila imena AJAX, ker za komunikacijo s strežnikom nisem uporabljal XMLa, ampak navaden GET zahtevek s parametri v query stringu, ki sem ga sprožil v nevidnem IFRAMEu. Podoben trik se zadnje čase uporablja predvsem za simulacijo AJAXa pri prenosu datotek na strežnik, nekatere implementacije AJAXa pa ga uporabljajo tudi, če browser ne podpira XMLHttpRequest objekta.

Zakaj sem prejle omenil tresenje gore in rojstvo miši? Ker AJAX ni nič takega, kar ne bi poznali že leta, le nekdo (Jesse James Garrett) se je spomnil, kako bi zadevo krajše poimenoval. AJAX ni nič drugega kot asinhrona komunikacija s strežnikom s pomočjo JavaScripta in XMLa, torej Asynchronous JavaScript And XML, krajše AJAX.

S tem govorjenjem ne želim zbijati vrednosti tehnologiji, nasprotno, mislim, da je na moč uporabna, le bati se je ni treba tako zelo, kot se je bojijo (ali pa jo tako strašno le želijo prikazati) nekateri. Če znate JavaScript in XML, znate AJAX. No, nikakor pa poleg teh dveh znanj ne škodi niti nekaj znanja (X)HTML, CSS in DOM, res.

Forme

Pa k problemu. Vedno sem klel, kadar sem za vsako submitanje forme moral čakati, da se stran spet naloži in mi prikaže vse napake, ki sem jih naredil pri vnosu. Nekateri so zadevo celo tako dobro izvedli, da so javili vse napake, ampak mi niso samodejno napolnili polj, pa sem moral celo formo še enkrat izpolniti. Back button je včasih delal, včasih pa tudi ne. Nerodna zadeva skratka.

Pri rešitvi tega problema je uporaba AJAXa več kot smotrna, pa si poglejmo, kako sem zadevo rešil jaz. Uporabljam knjižnico XAJAX, z malo spremembami se da vse skupaj prenesti v vsako drugo implementacijo.

Primer forme za prijavo:

<form
    action="#"
    onsubmit="return formSubmit('login', this);">
<div id="username_container" class="inputDefault">
    Username:
    <input name="username" type="text" />
    <div id="username_message" class="inputMessage"></div>
</div>
<div id="password_container" class="inputDefault">
    Password:
    <input name="password" type="password" />
    <div id="password_message" class="inputMessage"></div>
</div>
<div class="inputSubmit">
    <input type="submit" value="Login" />
</div>
</form>

Še JavaScript funkcija formSubmit():

function formSubmit(action,frm) {
    return !xajax.call(
        'login',
        new Array(xajax.getFormValues(frm))
      );
}

Pa še nekaj CSSja:

form .inputDefault .inputMessage {
    display: none;
}
form .inputError .inputMessage {
    display: block;
    color: red;
    font-weight: bold;
}

Na client strani smo pripravili vse, sedaj moramo le zagotoviti, da se ob submitanju forme preveri pravilnost polja in da ustrezno ukrepamo. Če bo karkoli narobe s poljem username, bomo napolnili DIV z IDjem username_message z ustreznim sporočilom, ki bo povedal nekaj več o napaki, in DIVu z IDjem username_container bomo spremenili class v inputError, da se sporočilo prikaže in to v rdeči barvi, kar smo določili s CSSjem. Enako bomo storili tudi s poljem password.

Ob dodatnem igranju s CSSjem, bi lahko drugače obarvali tudi samo vnosno polje ali pa spremenili karkoli drugega. Prepuščeno seveda vaši domišljiji.

Ampak, kako to naredimo? Gremo na server stran.

require_once('xajax.inc.php');
$xajax = new xajax();
$xajax->registerFunction('login');
$xajax->processRequests();

Kreirali smo XAJAX objekt, registrirali funkcijo login in procesirali zahtevek. No, nismo ga, potrebujemo še funkcijo login, kajne?

function login($args) {
    $response = new xajaxResponse();
    if (check_username($args['username'])) {
        $response->addAssign(
            'username_message',
            'innerHTML',
            'neveljavno uporabniško ime'
          );
        $response->addAssign(
            'username_container',
            'className',
            'inputError'
          );
    }
    else {
        $response->addAssign(
            'username_container',
            'className',
            'inputDefault'
          );
        $response->addAssign(
            'username_message',
            'innerHTML',
            ''
          );
    }
    if (check_password($args['password'])) {
        $response->addAssign(
            'password_message',
            'innerHTML',
            'napačno geslo'
          );
        $response->addAssign(
            'password_container',
            'className',
            'inputError'
          );
    }
    else {
        $response->addAssign(
            'password_container',
            'className',
            'inputDefault'
          );
        $response->addAssign(
            'password_message',
            'innerHTML',
            ''
          );
    }
    return $response;
}

Manjkata nam seveda še funkciji check_user() in check_password(), ampak sta tukaj povsem brezpredmetni, implementirajte ju sami. Potrebujemo tudi še mehanizem, ki bo uporabnika ob pravilni kombinaciji uporabniškega imena in gesla še prijavil v sistem, ampak je tudi ta za naš primer povsem brezpredmeten.

Nekaj zelo podobnega uporabljam tudi pri komentarjih na mojem blogu, le da je vse skupaj implementirano v večji sistem in izvedeno bolj objektno.

Updated: