Modyfikacja formularza za pomocą jQuery

W poprzednim artykule pokazałam jak w kohana 2 stworzyć formularz za pomocą modułu formo. Nadmieniłam też, że w pewnych sytuacjach przydałoby się wykorzystać javascript, a ściślej mówiąc framework jQuery, żeby część formularza odpowiedzialna za ustalanie daty była bardziej funkcjonalna. Poza tym doszłam do wniosku, ze wykorzystanie jQuery może znacznie poprawić usability. Nie jestem miłośnikiem JavaScript, ale jeśli jakiś formularz może być przyjemniejszy i łatwiejszy w użyciu, to znaczy, że należy sięgnąć po to narzędzie. Mało rzeczy w internecie mnie tak irytuje jak duże, nieprzejrzyste formularze.

Przypomnienie formularza

Jest prosty, ale bez trudu można sobie wyobrazić bardziej skomplikowane formularze. Dla zilustrowania problemu wystarczy jednak taki. W tym miejscu chciałabym zwrócić uwagę czytelnika na część formularza obwiedzioną czerwoną ramką, bo to ją właśnie będziemy modyfikować za pomocą jQuery

Po co mi jQuery w tym formularzu?

Bez podpierania się JavaScriptem należałoby ten formularz wyświetlić w takim stanie jak na ilustracji powyżej. Trochę to bez sensu, bo przy wyborze opcji ‚Nieaktywny’ dostęp do dalszych opcji i w ogóle ich wyświetlanie jest bez sensu. Oczywiście przy przetwarzaniu formularza można pominąć dalsze opcje jeśli użytkownik wybierze opcję ‚Niekatywny’, ale przecież chodzi nam o poprawę funkcjonalności i przejrzystości formularza. Zatem, najlepiej by było, gdyby część oznaczona czerwoną ramką była niewidoczna albo wygrejowana i uaktywniała się dopiero gdy użytkownik wybierze opcję ‚Aktywny’. Tego bez pomocy JavaScript uzyskać się nie da.

Modyfikacja formularza

Nie możemy wyrzucić z formularza tych ‚ruchomych’ elementów i bazować tylko na dodawaniu ich przez skrypt jQuery, bo powstałby problem przy walidacji. Zatem lepiej te elementy pozostawić w obiekcie formularza a jedynie zadbać o to by były ukryte. Trzeba więc nieco zmodyfikować formularz. Do kodu formularza:

$objForm = Formo::factory('user')
->add('username')->label('Nazwa użytkownika')
->add('email')->label('E-mail')
->add('password')->label('Hasło')->type('password')
->add('password2')->label('Powtórz hasło')->type('password')
	->add_rule('password2', 'matches[password]')
->add_select('role',$arrRoles)->label('Uprawienia:')
->add_group('active', $arrActive)->label('&nbsp')->check('active', 'nieaktywny')
->add_group('active_to[]', array(1 => ' tak, do: '))
	->label('Ograniczenie ważności konta: ')
->add_select('year', $arrYear)
->add_select('month',$arrMonth)->value($strMoth)
->add_select('day',$arrDay)->value($strDay)
->add('submit')->value('Dodaj');

należy więc dodać:

objForm->set('year','disabled','disabled')
	->set('month','disabled','disabled')
	->set('day','disabled','disabled');

To spowoduje dezaktywację list rozwijanych odpowiedzialnych za daty, ale to trochę za mało. Najlepiej by było w ogóle ukryć tę sekcję. Można to osiągnąć wprowadzając niewielką modyfikację w pliku stylów. Oczywiście nie można wtedy korzystać z automatycznego generowania formularza. Zaglądając do wspomnianego na początku artykułu, można sobie przypomnieć jak wyglądała definicja widoku formularza. Interesująca nas sekcja znajduje się w jednym wierszu tabeli:

<tr id="to">
   <th><?php echo $active_to->label;?></th>
   <td><?php echo $active_to.'&nbsp;'.$year.' - '.$month.' - '.$day;?></td>
</tr>

Wystarczy zatem w pliku stylów dodać:

tr#to{
   display:none;
}

To zagwarantuje nam, że dane z tej sekcji w ogóle nie zostaną przesłane przez formularz, więc nie będziemy się musieli nimi przejmować a przy zapisywaniu do bazy przyjmą wartości domyślne, które musza być odpowiednio zdefiniowane.

Dodawanie skryptu jQuery w kohana

Dodanie skryptu jQuery do aplikacji stworzonej w Kohana nie jest kłopotliwe. Wystarczy wstawić odpowiednie wpisy w nagłówku, tak jak robi się to pisząc stronę po prostu w HTML. Dodajemy zatem dwa skrypty. Silnik jQuery i skrypt obsługujący nasz formularz, który opisze dalej:

<script type="text/javascript" src="/jq/lib/jquery.js"></script>
<script type="text/javascript" src="/jq/form_hide.js"></script>

Oczywiście jest to dodawanie skryptu „na sztywno”. W bardziej skomplikowanych aplikacjach skryptu potrzebne są na jednych podstronach a na innych nie, albo potrzebne są inne skryptu. W zasadzie to wolę dodawać skryptu dynamicznie, czyli zależnie od potrzeb. Jak to zgrabnie zrobić zapewne opiszę innym razem.

Dynamiczna obsługa formularza w jQuery

No i wreszcie przyszła pora na ujawnienie kodu, który powinien się znajdować w skrypcie form_hide.js. Skrypt ten musi zrobić dwie rzeczy. Po pierwsze, po wybraniu przez użytkownika opcji ‚Aktywny’ powinien pokazać ukrytą sekcję. Po drugie, po zaznaczeniu checkboxa ‚Ograniczenie ważności konta’, powinien odblokować listy rozwijane umożliwiające ustawienie odpowiedniej daty.

$(document).ready(
	function(){
		$('input[name=active]').change(function(){
			if($(this).val() == 1)
				$('tr#to').css('display','table-row');
			else
				$('tr#to').css('display','none');
		});

		$("input[name='active_to[]']").change(function(){
			if($(this+':checked').length == 2){
				$('select#year').removeAttr('disabled');
				$('select#month').removeAttr('disabled');
				$('select#day').removeAttr('disabled');
			}else{
				$('select#year').attr('disabled','disabled');
				$('select#month').attr('disabled','disabled');
				$('select#day').attr('disabled','disabled');
			}
		});
});

Linie od 3 do 8 odpowiedzialne są za obsługę kliknięcia w radiobox czyli wybrania przez użytkownika opcji ‚Aktywny’. lub ‚Nieaktywny’. W zależności od wyboru użytkownika wyświetla lub ukrywa ostatnią linię tabeli zawierająca dodatkowe opcje.

Linie od 10 do 20 odpowiadają za obsługę checkboxa ‚Ograniczenie ważności konta’. Przechwytują każdą zmianę i w zależności od tego, czy jest on zaznaczony, czy nie usuwają lub dodają atrybut ‚disabled’ wszystkim listom rozwijanym, odpowiedzialnym za ustalanie daty.

A teraz możesz sam sprawdzić jak to działa.

14 komentarzy do wpisu „Modyfikacja formularza za pomocą jQuery”

  1. Witaj!

    Jest tylko jedna rzecz, która nie została przez Ciebie przemyślana: są ludzie korzystający z NoScripta i dlaczego niektórzy mają głęboko w poważaniu czy tacy internauci będą mogli skorzystać z formularza? Wystarczy ukrywać i pokazywać wszystko w JS i problemu nie ma – dodaj `$(‚tr#to’).css(‚display’,’none’);` zaraz po rozpoczęciu ciała funkcji dla `$(document).ready();` i usunąć styl. Dodatkowo można w `change()` zmienić `$(‚tr#to’).css();` na `$(‚tr#to’).animate({opacity: hide}, 300);`, gdzie 300 to ilość milisekund przy ukrywaniu i… tadam: mamy ładnie animowany wiersz w tabeli. Odwrotnością do `hide` jest oczywiście `show`.

  2. Rzeczywiście sekcja powinna być ukryta za pomocą JS. Nie powiedziałabym, że mam w nosie czy ktoś używa NoScript, zwyczajnie zapomniałam, że jeszcze niektórzy tego używają. Kajam się.

    Na swoje usprawiedliwienie dodam, że chciałam przemycić jeszcze co nieco na temat modułu Formo.

    • Dlatego, że poprzedni wpis, na temat formularza napisany był gdy używałam kohana v2 a chciałam do niego nawiązać i go wykorzystać. Tak naprawdę sam opis tego jak zrobić w jQuery taka modyfikację jest niezależny od tego czy zrobisz to w Kv2, Kv3 czy jeszcze inaczej :)

  3. @megawebmaster

    Oczywiście, że takich ludzi mamy w nosie. Mam wiele stron, i ludzie nie korzystający z JS to nawet nie 1% wszystkich wchodzących na stronę.

    Jak mi klient zapłaci za dodatkowy czas spędzony na dostosowaniu strony pod „brak” javascriptu, to wtedy się tym zajmę :)

    Równie dobrze, mógłbyś powiedzieć, że mam w nosie ludzi korzystających z IE6 i dlaczego nie dostosowywać strony do tej przeglądarki ;) Jeżeli ktoś nie zauważył to mamy rok 2011, a javascript jest teraz wszędzie.

    • Nie przesadzaj. W tym konkretnym przypadku, to naprawdę żaden problem uwzględnić, że ktoś JS nie używa. Z resztą w każdej robionej przeze mnie aplikacji robiłam dwie wersje. W tym własnie sztuka, żeby to zrobić na tyle mądrze, by nie trzeba było szczególnie dużo czasu poświęcić na to, by działało zarówno z JS jak i bez.

  4. Aż napiszę komentarz. Popieram słowa Joanny odnośnie mądrego tworzenia aplikacji. Sprawa jest prosta: tworzysz portal nie wymagający JavaScriptu, a potem w pliku js przygotowujesz scenariusze wybajerzające to co można wybajerzyć.

    Ale by nie było, że powtarzam bez sensu treść cudzych komentarzy. Od siebie:

    W Twoim przykładzie disablujesz 3 pola, co wiąże się oczywiście z jedynie 6 liniami kodu. Zmieniasz też tylko jeden parametr. Teraz pomyśl, że zmieniasz kilkanaście pól, po kilka atrybutów. Skopiujesz każdą linię kodu? No przecież że nie. Proponowałbym dodać do pól objętych funkcją en/disablującą atrybut grupujący dzięki czemu wszystkie pola będą zmieniane jednocześnie. Poprzez

    $(‚form#formId’).find(‚[groupAtr]).each( tutaj );

    na przykład. Nie jest to oczywiście najważniejsze w tym wpisie, ale osobiście uważam, iż jak coś robić, to raz a dobrze, bo przyda się w przyszłości. Mam Ci ja rację? No mam :)

    Dobrze jest też ograniczać się do konkretnego formularza. Wyobraź sobie, że na jednej stronie masz formularz główny, logowania, szukania, subskrypcji, jakąś ankietę i parę innych które mi teraz nie przychodzą do głowy. Zbyt ogólne parametry spowodują oddziaływanie na pola, które na daną imprezę w ogóle nie dostały zaproszenia.

    Generalnie po innych wpisach widzę taką tendencję, że esencja jest ok, ale cała otoczka troszeczkę kosmetyki wymaga. A przecież ci, którzy pilnie się uczą chłoną wiedzę jak gąbka, przez co potem powtarzają takie różne pomysły, a inni nieszczęśnicy zaprzęgnięci do pracy na cudzym kodzie muszą trzymać się niewygodnego schematu.

    Owocnego dalszego blogowania :)

    Cze

  5. Dopiszę jeszcze jedną rzecz, o której warto pamiętać pisząc jakikolwiek kod: należy zastanowić się, co będzie gdy elementów, podgrup, ilości znaków, ilość wyświetleń, liczba czegokolwiek policzalnego – będzie dążyć do nieskończoności. To co się da, zamknąć w funkcje. Dwie funkcje są ze sobą związane tematyką? Zamknąć w klasę. I tak dalej.

    Przykład: tworzymy drzewo kategorii. Nie możemy się ograniczyć do powiedzmy czterech poziomów głębokości, bo gdy klient zażąda poziom piąty, to nas szlag trafi, a potem klienta że unikamy z nim kontaktu (a nie pójdzie gdzieś indziej bo jest z nami związany produktem).

    Wyższa szkoła jazdy zaczyna się, gdy trzeba też przewidzieć wyjątki. Czyli piszemy sobie uniwersalny kod, do którego można wstrzyknąć coś, co obsłuży nam naszą niecodzienną sytuację. Taki nawyk wyrabia się z czasem sam, ale po co czekać, skoro piszę to teraz? :)

    Ktoś może mnie wyśmiać: jasne, terminy gonią, dziecko płacze, wszystko jest na wczoraj, a ja mam się bawić w kombinowanie, jak przewidzieć nieprzewidywalne. Nie. Zapewniam, że wystarczy zapoznać się z listą wzorców projektowych, pisać kod dobrze od początku, a potem go kopiować. W krótkim czasie dochodzimy do momentu, gdy więcej rzeczy tworzymy poprzez ctrl+c i ctrl+v niż korzystając z reszty klawiatury.

    Hm, można by z tych kilku akapitów zmontować ciekawy wpis o dobrych nawykach.

  6. Oj Frost. Chyba czegoś nie zrozumiałeś. Ja na swoim blogu piszę wyłącznie o esencji. Otoczkę każdy musi sobie wypracować sam. Właśnie dlatego, żeby ci co ograniczają się do powielania cudzego kodu nie mieli za łatwo. Jako belfer oczekuję od studentów nie tylko chłonięcia wiedzy ale też samodzielnego myślenia.

    Co do drugiego Twojego komentarza, to nie bardzo rozumiem jaki on ma związek z tym artykułem, który nie jest ani o wzorcach projektowych, ani nawet o programowaniu obiektowym. Ale jeśli już zacząłeś o strukturach drzewiastych, to polecam inną serię artykułów, która zaczyna się tu: http://blog.joanna-siwiec.pl/struktura-drzewiasta-w-bazie-danych-odc-1/366/

    A ponieważ moje artykuły to nie są gotowce i nie mają służyć temu, żeby ktoś skopiował sobie klasę i ograniczył się tylko do jej używania to dalej będą zajmować się wyłącznie esencją zagadnienia, które uznam za ciekawe :) Może kiedyś za takie uznam projektowanie klas albo używanie wzorców. Kto wie?

    Tematem tego artykułu jest proste zastosowanie jQuery w formularzu i wszystko mi jedno gdzie i jak sobie to ktoś wkomponuje. Zapewniam Cię, że ja w swoich aplikacjach mam to zaprojektowane uniwersalnie i wygodnie, mimo, że terminy gonią a dziecko płacze :P

  7. W takim razie rzeczywiście nie zrozumiałem. Dla mnie cudowną sprawą byłoby właśnie, gdyby i ta esencja miała ładną otoczkę.

    Drugi komentarz był z rozpędu dla tych, co będą to czytać. W myśl zasady, szukasz „A” znajdujesz ciekawe „B”. Raz w życiu chciałem to napisać. Artykuły o strukturach drzewiastych czytałem już wcześniej, znam je.

    Co do gotowców, widzisz, zaobserwowałem takie cuś: dobrzy programiści i tak najczęściej przerabiają gotowce pod własne potrzeby, niezależnie od jakości podanego przykładu, tyle że mają o wiele łatwiej. Natomiast lenie kopiują jak leci i spamują pomoc techniczną, że im nie działa. Cierpią wszyscy. Dlatego tak się rozpisałem o tej esencji. Może teraz jest bardziej jasne, co miałem na myśli. Fakt, że po co takim ułatwiać sprawę, ale jak rozróżnisz jednych od drugich? Ech.

    Ad. Twój ostatni akapit. Kozacko. W takim razie z przyjemnością pracowałbym na Twoim kodzie.

  8. No dobra. To teraz i ja rozumiem Twoje intencje.

    A co do ostatniego Twojego akapitu, to kto wie? Może kiedyś przytrafi nam się jakaś współpraca.

Dodaj komentarz

%d bloggers like this: