Formų validacija: netrukdyk man!

Alanas Cooperis savo knygose pastoviai kartoja, kad blogiausias dalykas, kurį galima padaryti vartotojui, tai priversti jį jaustis kvailu. Bene lengviausia šį “tikslą” pasiekti yra validacijoje – kiekvienas bereikalingas klaidos pranešimas ir kiekviena sistema, kuri man trukdo daryti dalykus mano būdu, tiesiog ir verčia mane daužyti galvą į sieną su klausimu “Nu, kodėl šito reikia?” Šiandien aptikau puikų to pavyzdį:

function isNumberKey(evt)
{
     var charCode = (evt.which) ? evt.which : event.keyCode
     if (charCode > 31 && (charCode < 48 || charCode > 57))
        return false;

     return true;
}


Ši funkcija naudojama kaip onkeypress event handler. Ką ji daro iš tikro? Kai įvesties lauke paspaudžiamas klavišas, kuris nėra skaičius, ir nėra vienas iš kontrolinių klavišų (Enter, Backspace ir tt), klavišo paspaudimas yra sustabdomas ir ignoruojamas. Konkrečiu atveju, man reikėjo įvesti svetainėje savo 8 skaitmenų prisijungimo kodą, na ir lyg būtų logiška, kad man nereikia spausti kitų klavišų, tik skaičius, ir po to Tab, kad įvesti slaptažodį. Netiesa!

Visiškai galima kombinacija, kurią galiu įvesti yra Ctrl+V. Nes paprasčiausiai naudojuosi konkrečia svetaine kartą per metus, todėl prisijungimo vardą, kuris yra generuojamas automatiškai, galiu surasti tik el. pašto archyve. Ar tai veiks? Be abejo ne (išskyrus Chrome – nesigilinau kodėl), nes tokio paspaudimo atveju charCode bus lygus 118, t.y. “v” raidės ASCII kodas, ir mano Paste veiksmas bus sustabdytas.

Patarimas: leisk vartotojui elgtis kaip jis įpratęs

Galima, be abejo sakyti, kad prisijungimo formoje tokia validacija išvis nereikalinga, nes įvedus neteisingą vartotojo vardą (pvz. ' OR ''='), prisijungti tiesiog nepavyks, su pranešimu “Neteisingas vartotojo vardas ir/arba slaptažodis”. Tačiau lygiai taip pat galima teigti, kad siekiama vartotoją apsaugoti nuo to klaidos pranešimo, arba, kad toks validacijos veikimas kai kuriais atvejais gali būti pageidautinas. Netiesa!

Patarimas: nepasikliauk naršyklės API

Javascript palaikymas interneto naršyklėse yra labai ribotas. Jis negali suteikti standartinių OS galimybių, kaip pvz. garsinis signalas paspaudus netinkamą klavišą. Negana to, konkrečioje formoje nėra suteikiama jokių užuominų, kad “leidžiama įvesti tik skaičius” (tuo atveju galima būtų tiesiog keikti programuotoją, už neteisingą vykdymą). Tačiau net jeigu viso to implementacija būtų teisinga, o puslapis pateiktų visas užuominas apie tai, ką galima daryti ir ko negalima, vistiek aš pasisakyčiau prieš tokį dalyką, ir ne vien tik todėl, kad Nokia telefonai neteisingai perduoda keyCode.

Dar vienas pavyzdys būtų validacijos vykdymas, kai nuspaudžiamas Enter klavišas – ši problema mane nervuoja pragare, kuris vadinamas o2.ie kasdien. Kodėl? Ogi tiek Firefox, tiek Chrome (su Opera svetainė neveikia išvis) autocomplete pasirinkus reikšmę, ir paspaudus Enter, įvykis perduodamas į Javascript, todėl pasirinkęs iš sąrašo savo telefoną, gaunu malonų pranešimą, kad neįvedžiau slaptažodžio, nors dar net nespėjau prieiti iki to žingsnio!

Patarimas: nedėk apribojimų ten, kur jie visiškai nereikalingi

Problema slypi tame, kad ribojama mano veiksmų laisvė. Neverta to daryti. Štai pvz. textarea elementas neturi maxlength atributo – galima to palaikymą sukurti su JS, bet daug geresnis variantas yra tiesiog parodyti kiek yra likę galimų įvesti simbolių, o klaidos pranešimą rodyti tik tada, kai klaida yra tikrai padaryta. Įsivaizduokite, jei Twitter neleistų įvesti daugiau negu 140 simbolių ir nesuteiktų galimybės redaguoti tekstą tol, kol jis telpa į juos.

Lygiai taip ir šiuo validacijos atveju, derėtų leisti vartotojui spausti tuos klavišus, kuriuos jis nori spausti, o įvestus duomenis tikrinti tik tada, kai vartotojas pasako “taip, aš žinau, kad noriu tokius duomenis išsiųsti”, t.y. onsubmit įvykio metu, arba tiesiog server-side.

3 Responses to “Formų validacija: netrukdyk man!”

Komentarų RSS

Teisingas straipsnis. Būtent Opera kūrėjų viena iš pagrindinių idėjų ir yra ši mintis – neriboti vartotojo veiksmų.

Server-side validacija lėtoka (reikia išsiųsti duomenis).
Geriau prodingai validuoti javascriptu pirma leidžiant vartotojui įvesti ką jis nori, o tada pataisant klaidingai įvestus duomenis.
Digits-only laukeliams aš naudoju daugmaž tokią funkciją:

function validate_number(input) {
return input.replace(new RegExp(“[^0-9]“, “g”), ”);
}

užmeti šitą onblur ir būna visai ok =]

Chionsai, netiesa. Taisyti vartotojų duomenų pačiam, automatiniu būdu negalima. Visų pirma todėl, kad vartotojas lieka nežinioje, kodėl ir kas nutiko. Be to gali gautis visai netikėtas rezultatas. Kad ir pvz. klasikinė “decimal separator” problema.

Daryti tai onblur yra dar blogiau, nes nu klasikinis pavyzdys – pildau formą, atėjau į lauką A, kažką padariau, perėjau į lauką B, laukas A pasikeitė ar gavo klaidos pranešimą, grįžau į jį nebaigęs pildyti lauko B – laukas B irgi gavo klaidos pranešimą. Negalima gąsdinti ir bauginti vartotojo. Ypač kai jis nebūtinai kaltas dėl to kas įvyko.

Gera validacija perspėja apie tai ko ji tikisi iš anksto (neįkyriu būdu), tada negavusi tai ko nori – perspėja ramiu (ambient) būdu, kad ne viskas ok (onblur), o veiksmų stabdymas turi vykti tik onsubmit.