{"id":181,"date":"2008-10-11T10:09:25","date_gmt":"2008-10-11T09:09:25","guid":{"rendered":"http:\/\/eriz.pcinside.pl\/weblog\/jquery-i-prosta-walidacja-formularzy-181.html"},"modified":"2008-10-11T19:09:22","modified_gmt":"2008-10-11T18:09:22","slug":"jquery-i-prosta-walidacja-formularzy","status":"publish","type":"post","link":"https:\/\/eriz.pcinside.pl\/weblog\/jquery-i-prosta-walidacja-formularzy-181.html","title":{"rendered":"jQuery i prosta walidacja formularzy"},"content":{"rendered":"<p>Tworz\u0105c formularz kontaktowy &#8211; opr\u00f3cz oczywistej walidacji po stronie serwera &#8211; warto sprawdza\u0107 jego poprawno\u015b\u0107 r\u00f3wnie\u017c po stronie klienta. Pozwala to oszcz\u0119dzi\u0107 nie tylko czas, ale r\u00f3wnie\u017c i nerwy &#8211; przyk\u0142adowo, w przypadku korzystania z IE i wypisaniu tylko komunikatu <em>wype\u0142nij wszystkie pola<\/em>, spowodujemy drastyczne podirytowanie go\u015bcia, gdy\u017c jego &#8222;przegl\u0105darka&#8221; nie przywr\u00f3ci mu poprzednio wpisanych danych do formularza. Wiem, \u017ce IE traci na popularno\u015bci (i dobrze!), ale pani Jadzia z sekretariatu te\u017c powinna by\u0107 zadowolona z odwiedzin na naszej stronie.<\/p>\n<p>Klasycznie, zaczniemy od studium przypadku.<\/p>\n<p><!--more--><\/p>\n<h3>Prolog<\/h3>\n<p>Z racji tego, i\u017c nie b\u0119dziemy sprawdza\u0107 poprawno\u015bci jakich\u015b formularzy aplikacyjnych, pos\u0142u\u017cymy si\u0119 naprawd\u0119 prostym i stosunkowo \u0142atwo rozbudowywalnym skryptem. Za\u0142\u00f3\u017cmy, \u017ce korzystamy z formularza tego typu:<\/p>\n<p><code lang=\"html\"><\/p>\n<form id=\"contact\" method=\"post\" action=\"\/contact\">\n<dl>\n<dt><label for=\"fsender\">imi\u0119 i nazwisko<\/label><\/dt>\n<dd><input type=\"text\" name=\"sender\" id=\"fsender\" \/><\/dd>\n<dt><label for=\"fmail\">adres e-mail<\/label><\/dt>\n<dd><input type=\"text\" name=\"mail\" id=\"fmail\" \/><\/dd>\n<dt><label for=\"frecipient\">odbiorca<\/label><\/dt>\n<dd>\n\t\t\t<select name=\"recipient\" id=\"frecipient\"><option value=\"\">wybierz<\/option><option value=\"redaktor1\">Redaktor 1<\/option><option value=\"redaktor2\">Redaktor 2<\/option><option value=\"redaktor3\">Redaktor 3<\/option><\/select>\n\t\t<\/dd>\n<dt><label for=\"fmessage\">wiadomo\u015b\u0107<\/label><\/dt>\n<dd><textarea cols=\"100%\" rows=\"20\" name=\"message\" id=\"message\"><\/textarea><\/dd>\n<\/dl>\n<p><label for=\"fsubmit\" title=\"wy\u015blij\"><\/label><input type=\"submit\" value=\"wy\u015blij\" \/><\/p>\n<\/form>\n<p><\/code><\/p>\n<p>Nadawca, adres e-mail, odbiorca i tre\u015b\u0107 wiadomo\u015bci. Mo\u017cna, oczywi\u015bcie, pomin\u0105\u0107 odbiorc\u0119, ale to nie jest problem. <img src=\"https:\/\/eriz.pcinside.pl\/weblog\/wp-includes\/images\/smilies\/e_wink.png\" alt=\";)\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\" \/><\/p>\n<p>Id\u0105c z duchem nowoczesno\u015bci, skorzystamy z frameworka (<a href=\"http:\/\/jquery.com\">jQuery<\/a>) oraz nieinwazyjnego podpinania zdarze\u0144. Do sekcji <em>&lt;head&gt;<\/em> do\u0142\u0105czamy odwo\u0142anie do biblioteki oraz naszego skryptu, kt\u00f3ry umie\u015bcimy w pliku <em>contact.js<\/em>.<\/p>\n<p><code lang=\"html\"><script type=\"text\/javascript\" src=\"js\/jquery.js\"><\/script><br \/>\n<script type=\"text\/javascript\" src=\"js\/contact.js\"><\/script><\/code><\/p>\n<p>To tyle, je\u015bli chodzi o dodawanie jakichkolwiek innych skrypt\u00f3w w pliku HTML. <em>onclick\/blur\/focus<\/em> precz!<\/p>\n<h3>walidacja<\/h3>\n<p>I tu zaczniemy tzw. poezj\u0119, kt\u00f3r\u0105 pocz\u0105tkuje ju\u017c sam slogan <cite>write less, do more<\/cite>. Zak\u0142adamy sobie na pocz\u0105tku taki scenariusz. W przypadku, gdy wszystkie pola s\u0105 poprawnie wype\u0142nione, skrypt nie &#8222;powie&#8221; nic. Natomiast, je\u015bli b\u0119dzie cho\u0107 jedno niewype\u0142nione pole (<em>value=&#8221;&#8221;<\/em>), zostanie dodana klasa <em>invalid<\/em>, kt\u00f3ra mo\u017ce oznaczy\u0107 pole np. czerwon\u0105 obw\u00f3dk\u0105. To ju\u017c zale\u017cy od regu\u0142ek, jakie umie\u015bcimy w CSS. <img src=\"https:\/\/eriz.pcinside.pl\/weblog\/wp-includes\/images\/smilies\/e_wink.png\" alt=\";)\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\" \/><\/p>\n<p>Skorzystamy z konstrukcji <a href=\"http:\/\/docs.jquery.com\/Tutorials:Introducing_$(document).ready()\">$(document).ready()<\/a>, kt\u00f3ra uruchamia zdarzenia zaraz po wczytaniu &#8222;newralgicznych&#8221; element\u00f3w strony, czyli <a href=\"http:\/\/pl.wikipedia.org\/wiki\/Obiektowy_model_dokumentu\">drzewa DOM<\/a>. W przeciwie\u0144stwie do czas\u00f3w Netscape&#8217;a i konstrukcji <em>window.onload<\/em>\/<em>&lt;body onload=&#8221;&#8221;&gt;<\/em> przegl\u0105darka nie czeka na np. wczytanie wszystkich obrazk\u00f3w i uruchamia skrypty wtedy, gdy tego potrzebujemy. Owszem, mog\u0105 by\u0107 potrzebne wszystkie elementy (np. jaka\u015b efektowna animacja), wtedy mo\u017cna skorzysta\u0107 z kombinacji <em>ready()<\/em> i <em>onload<\/em>, lecz nie zawsze jest to potrzebne (czytaj: prawie wcale ;P). Korzystajanie ze starego rozwi\u0105zania spowodowa\u0142oby, \u017ce np. odno\u015bnik do obrazka systemu statystyk drastycznie op\u00f3\u017ani\u0142oby dzia\u0142anie ca\u0142ego oskryptowania.<\/p>\n<p>To tyle nt. teorii, pora na praktyk\u0119:<\/p>\n<p><code lang=\"javascript\">$(document).ready(function(){<br \/>\n\t\/\/ ju\u017c jeste\u015bmy w \u015brodku ;)<br \/>\n});<\/code><\/p>\n<p>Trudne? <img src=\"https:\/\/eriz.pcinside.pl\/weblog\/wp-includes\/images\/smilies\/e_wink.png\" alt=\";)\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\" \/> Teraz pod\u0142\u0105czymy odpowiednie funkcje do sprawdzania poprawno\u015bci formularza:<\/p>\n<p><code lang=\"javascript\">$('#contact').bind('submit', function(){<br \/>\n\t\/\/ regu\u0142ki sprawdzaj\u0105ce<br \/>\n});<\/code><\/p>\n<p>Oczywi\u015bcie, to wszystko wewn\u0105trz bloku <em>$(document).ready()<\/em>. Teraz pozostaje nam przej\u015bcie przez wszystkie elementy formularza i odpowiednie ich oznaczenie:<\/p>\n<p><code lang=\"javascript\">\/\/ \"flaga\" poprawno\u015bci<br \/>\nvar valid = true;<br \/>\n\/\/ dla wszystkich element\u00f3w (input, textarea, select) nale\u017c\u0105cych do bie\u017c\u0105cego fomularza (wskazuje tu na\u0144 \"this\")<br \/>\n$(':input', this).each(function(){<br \/>\n\t\/\/ je\u015bli pole jest puste<br \/>\n\tif($(this).val()==''){<br \/>\n\t\t\/\/ oznacz jako \u017ale wype\u0142niony<br \/>\n\t\t$(this).addClass('invalid');<br \/>\n\t\t\/\/ ...i formularz do poprawki<br \/>\n\t\tvalid = false;<br \/>\n\t}else{<br \/>\n\t\t\/\/ wszystko ok, je\u015bli pole zosta\u0142o poprawione, usu\u0144 oznaczenie<br \/>\n\t\t$(this).removeClass('invalid');<br \/>\n\t}<br \/>\n});<\/code><\/p>\n<p>W\u0142a\u015bciwie to tyle z walidacji. Wystarczy tylko za <em>$.each()<\/em> doda\u0107 kilka linijek:<\/p>\n<p><code lang=\"javascript\">if(!valid){<br \/>\n\talert('Wype\u0142nij wszystkie oznaczone pola i spr\u00f3buj ponownie.');<br \/>\n\treturn false;<br \/>\n}<\/code><\/p>\n<p><em>return false<\/em> &#8222;m\u00f3wi&#8221; przegl\u0105darce, aby ta nie przetwarza\u0142a formularza dalej, czyli nie wysy\u0142a\u0142a go do serwera. Je\u015bli u\u017cytkownik poprawi pola i kliknie jeszcze raz na <em>wy\u015blij<\/em>, formularz zostanie wys\u0142any. To wszystko. <img src=\"https:\/\/eriz.pcinside.pl\/weblog\/wp-includes\/images\/smilies\/e_wink.png\" alt=\";)\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\" \/><\/p>\n<h3>epilog<\/h3>\n<p>Ca\u0142y kod zawarty w pliku <em>contact.js<\/em> wygl\u0105da tak:<\/p>\n<p><code lang=\"javascript\">$(document).ready(function(){<br \/>\n\t$('#contact').bind('submit', function(){<br \/>\n        var valid = true;<\/p>\n<p>        $(':input', this).each(function(){<br \/>\n            if($(this).val()==''){<br \/>\n                $(this).addClass('invalid');<br \/>\n                valid = false;<br \/>\n            }else{<br \/>\n                $(this).removeClass('invalid');<br \/>\n            }<br \/>\n        });<\/p>\n<p>        if(!valid){<br \/>\n            alert('Wype\u0142nij wszystkie oznaczone pola i spr\u00f3buj ponownie.');<br \/>\n            return false;<br \/>\n        }<\/p>\n<p>    });<br \/>\n});<\/code><\/p>\n<p>Powy\u017cszy kod nie jest jednak ograniczony tylko do jednego formularza. Dodanie walidacji do innego jest bardzo \u0142atwe. Wystarczy u\u017cy\u0107 selektor\u00f3w, <a href=\"http:\/\/docs.jquery.com\/Selectors\">jakie oferuje jQuery<\/a>, przyk\u0142adowo, sprawdzamy formularze, kt\u00f3re maj\u0105 nadan\u0105 klas\u0119 <em>validate<\/em>. Wystarczy zmiana jednej linijki:<\/p>\n<p><code lang=\"javascript\">$('#contact').bind('submit', function(){<\/code><\/p>\n<p>na<\/p>\n<p><code lang=\"javascript\">$('form.validate').bind('submit', function(){<\/code><\/p>\n<p>Zalet\u0105 tego rozwi\u0105zania jest fakt, i\u017c nie musimy tworzy\u0107 osobnej regu\u0142ki dla ka\u017cdego elementu formularza. Wystarczy, \u017ce nieprawid\u0142owe wype\u0142nienie b\u0119dzie jednoznaczne z jego pust\u0105 warto\u015bci\u0105. Oczywi\u015bcie, nic nie stoi na przeszkodzie, \u017ceby sprawdza\u0107 jakie\u015b bardziej z\u0142o\u017cone regu\u0142ki, np. poprawno\u015b\u0107 wpisanego adresu e-mail, ale o tym w nast\u0119pnej cz\u0119\u015bci. <img src=\"https:\/\/eriz.pcinside.pl\/weblog\/wp-includes\/images\/smilies\/e_wink.png\" alt=\";)\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Tworz\u0105c formularz kontaktowy &#8211; opr\u00f3cz oczywistej walidacji po stronie serwera &#8211; warto sprawdza\u0107 jego poprawno\u015b\u0107 r\u00f3wnie\u017c po stronie klienta. Pozwala to oszcz\u0119dzi\u0107 nie tylko czas, ale r\u00f3wnie\u017c i nerwy &#8211; przyk\u0142adowo, w przypadku korzystania z IE i wypisaniu tylko komunikatu wype\u0142nij wszystkie pola, spowodujemy drastyczne podirytowanie go\u015bcia, gdy\u017c jego &#8222;przegl\u0105darka&#8221; nie przywr\u00f3ci mu poprzednio wpisanych [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[93,74],"_links":{"self":[{"href":"https:\/\/eriz.pcinside.pl\/weblog\/wp-json\/wp\/v2\/posts\/181"}],"collection":[{"href":"https:\/\/eriz.pcinside.pl\/weblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/eriz.pcinside.pl\/weblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/eriz.pcinside.pl\/weblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/eriz.pcinside.pl\/weblog\/wp-json\/wp\/v2\/comments?post=181"}],"version-history":[{"count":0,"href":"https:\/\/eriz.pcinside.pl\/weblog\/wp-json\/wp\/v2\/posts\/181\/revisions"}],"wp:attachment":[{"href":"https:\/\/eriz.pcinside.pl\/weblog\/wp-json\/wp\/v2\/media?parent=181"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eriz.pcinside.pl\/weblog\/wp-json\/wp\/v2\/categories?post=181"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eriz.pcinside.pl\/weblog\/wp-json\/wp\/v2\/tags?post=181"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}