fbpx
Fele annyi validáló kód szükséges mint eddig ShiwaForce Admin 2015. február 25

Fele annyi validáló kód szükséges mint eddig

Ezt elkerülendő: minden adatot ellenőrizni, validálni kell, legtöbbször valamilyen formai szabályrendszer alapján. Az alábbi fejtegetésünket megfontolva akár fele annyi kódsorból is megvalósíthatjuk a validációt mint korábban.

A példa látványossága érdekében képzeljünk el egy nagy, több tucat beviteli mezőt tartalmazó form-ot, melybe a bevitt adatokat validálnunk kell. Ilyen méretű űrlapokkal gyakran több oldalra bontva találkozhatunk, ahol viszont fölösleges és nem felhasználóbarát  újra és újra betölteni az oldalkeretet és a láblécet. Ezért gyakori megoldás, hogy a teljes form-ot tulajdonképpen egy oldalra helyezzük, és a Tovább gombokra való kattintás elrejti, illetve megjeleníti ennek egyes részeit.

A klasszikus, régi vágású megvalósítás szerint ha a felhasználó kitöltöti a mezőket, majd a Submit gombra kattint, az adatokat elküldjük a szervernek, ami validálja az adatokat és visszaad egy csokor hibaüzenetet a felhasználó legnagyobb “örömére”. Az ellenőrzés elkerülhetetlen, de ez a megoldás távolról sem nevezhető felhasználóbarátnak. Ezen úgy javíthatunk, hogy a hibát lehetőleg azonnal jelezzük a user-nek, anélkül, hogy indokolatlanul sok kérést küldenénk a szervernek (pl.: validálás AJAX segítségével). Ezért aztán adja magát a megoldás: kliens oldalon is validálni kell. Ez azonban felveti a kérdést: hogyan tudjuk szinkronban tartani a kliens és szerver oldali validáló kódokat, illetve milyen nyelven írjuk meg azokat.

Az első kérdés megoldása roppant egyszerű:  szinkronban lesz, ha ugyanaz a file csinálja. De hogyan csinálhatja ugyanaz, ha szerver oldalon Javat, vagy PHP-t használunk? Ha csak nem akarjuk a felhasználót pluginok telepítésére kényszeríteni (NEM, NEM AKARJUK! 🙂 ), akkor a megoldás a JavaScriptben rejlik. Kliens oldalon talán ez az egyik leggyorsabb, legkényelmesebb megoldás, és így adja magát, hogy szerver oldalon is JavaScriptet használjunk. Itt jön képbe a nodejs, melynek segítségével ugyanaz a kód validálhat kliens és szerver oldalon is.

Lássunk egy rendkívül egyszerű példát, a teljesség igénye nélkül:

Példa néhány formai ellenőrzésre:

var validacio={

email:function(address){
//http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
return /^(([^<>()[]\.,;:s@"]+(.[^<>()[]\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/.test(address);
},

username:function(name){
  var validCaharacters=/^[a-z]+$/i.test(name);
  var nameString=''+name;
  var validLength=nameString.length<50 && nameString.length>3;
  return validCaharacters && validLength;
},

zipCode:function(code){
  return /^d{4}$/.test(code);
  }
};

if(module && module.exports){
  module.exports=validacio;
}

Ez HTML oldalon az őt futtató kód ilyesmi lehet, például jQuery-t használva, egy input mező esetében:

var invalidCssClass='invalid';

$('#email').keyup(function(e){
  var element=$(this);
  var valid=validacio.email(element.val());
  if(valid){
    element.removeClass(invalidCssClass);
  } else {
    element.addClass(invalidCssClass);
}
});

Ugyanez nodejs-ben, például express-t használva:

var validacio=require('./validalo');
app.post('/send-form',function(request,response,next){
  var email=request.body.email;
  var valid=validacio.email(email);
  if(valid){
    response.send('thanks');
  } else {
    response.send('email address isn't correct');
}
});

Természetesen a fenti kód csak szemléltetésre szolgál, a profi működéshez tovább kellene szervezni a használt fájlokat. Azt viszont jól mutatja, hogy maga a validáló kód csak egyszer került megírásra, és több helyen került felhasználásra.

Végül pedig plusz egy hasznos tény:  ha a fenti módon szervezzük a fájljainkat szét,  maga a validáció tesztelhető lesz.  Ha a tesztek hiba nélkül futnak rajta, akkor nagy magabiztossággal jelenthetjük ki:  a kódunk helyes.

A teljesség kedvéért álljon itt egy példa, hogyan lehet a fentihez hasonló kódot megoldani  “hagyományos” eszközkészlettel:

$('#email').keyup(function(e){

var element=$(this);
//http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
var emailRegex=/^(([^<>()[]\.,;:s@"]+(.[^<>()[]\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/;

var valid=emailRegex.test(element.val());
if(valid){
  element.removeClass(invalidCssClass);
} else {
  element.addClass(invalidCssClass);
}
});
boolean valid=org.apache.commons.validator.routines.EmailValidator.isValid(email);

Viszont felmerül pár elgondolkodtató kérdés:

  • Ránézésre ugyan rövidebbnek tűnik, de mi a helyzet, ha egy régi apache commons-t használunk?
  • Frissítés után hogy tartjuk szintkronban a kliens oldali kóddal?
  • Mi a helyzet, ha az ügyfelünk kéri hogy az „admin@intranet” vagy a „()<>[]:,;@\”!#$%&’*+-/=?^_`{}| ~.a”@example.org (amúgy rfc szerint helyes [link]) email címet is fogadja el a kódunk?
  • Ilyen esetben mi alapján becsülnénk meg a módosítás várható  időtartamát?
  • Vajon szerver oldalon is hozzá kell-e nyúlni?
  • Kliens oldalon hozzá kell nyúlni?

Persze ebben az egyszerű esetben ez nem túl nagy tétel, de emlékezzünk csak vissza, ha igazán nagy formunk van,  sok mezővel, akkor nehézkes lesz reális becslést végezni.

  • Mi a helyzet a unit tesztekkel?
  • Kétszer annyi tesztet kell írnunk, vagy valamelyik oldalt nem fogjuk letesztelni?

Mielőtt késznek tekintünk egy ilyen fejlesztést, fussuk át újra a fenti felvetéseket, és mindenképpen tegyük fel magunknak a kérdéseket. Ha mindenre meggyőző válaszunk van, akkor a megrendelő is elégedett lesz.