Autouzupełnianie w polach formularza. Odc.1.

PHP, jQuery Zostaw komentarz

Słowo wstępu o Autocomplete

Jak już pisałam w artykule Nadszedł czas na jQuery przyszło mi się zmagać z problemem podpowiedzi przy uzupełnianiu formularza. Oczywiście przy małej ilości danych można się pokusić o zastosowanie elementów typu <select> ale gdy w grę wchodzą podpowiedzi pochodzące z bazy danych zawierającej tysiące rekordów a w dodatku chcemy pozostawić użytkownikowi możliwość wpisania czegoś spoza tej puli danych, pozostaje nam już tylko autouzupełnianie.

Z takim właśnie przypadkiem się zetknęłam. W formularzu który przyszło mi obsłużyć były nazwy miejscowości, gmin i ulic z całej Polski. Żaden <select> by tego nie wytrzymał. Dlatego sięgnęłam po plugin Autocomplete dla JavaScriptowego frameworka jQuery

Oczywiście, żeby móc skorzystać z dobrodziejstw tego frameworka i pluginu trzeba je do swojego projektu dołączyć. To akurat najprostsze w naszym zadaniu.
Trzeba ściągnąć paczkę z pluginem Autocomplete i rozpakować w jakimś wygodnym katalogu (niech to będzie na przykład katalog ./jq-ac). W tej paczce jest już samo jQuery. Następnie w nagłówku dokumentu należy dopisać kilka linii:

  1. <link rel="stylesheet" href="./jq-ac/jquery.autocomplete.css" type="text/css" />
  2. <script type="text/javascript" src="./jq-ac/lib/jquery.js"></script>
  3. <script type="text/javascript" src="./jq-ac/lib/jquery.dimensions.js"></script>
  4. <script type="text/javascript" src="./jq-ac/jquery.autocomplete.js"></script>

Wpierw dołączamy arkusz stylów zdefiniowanych dla tego pluginu. Oczywiście można go modyfikować, albo stworzyć na jego wzór inny. Następnie dołączamy sam framework jQuery i dwa pliki w których zdefiniowany jest nasz plugin. I już po krzyku.

Uruchamiamy autouzupełnianie

W najprostszym przypadku sposób użycia tego pluginu jest banalny i nie powinien nastręczać problemów nikomu kto choćby odrobinę popróbował JavaScriptu. Aby wyjaśnić w czym rzecz zacznę od skonstruowania formularza:

  1. <form action="" method="post" name="ankieta">
  2.    <tr> <th colspan="2"> Formularz z podpowiedziami</th> </tr>
  3.    <tr>
  4.     <td> Urządzenia </td>
  5.     <td> <input type="text" name="urzadzenia" id="urzadzenia"> </td>
  6.    </tr>
  7.    <tr>
  8.     <th colspan="2"> <input type="submit" value="Akceptuj"> </th>    
  9.    </tr>
  10.   </table>
  11.  </form>

Nic szczególnego. Jedno pole typu <input/>, przycisk <submit/> i wszystko w tabli (nie jest to szczyt elegancji), żeby było równo. Aby podłączyć podpowiedzi do pola <input/> skorzystamy z funkcji autocomplete() W tym celu w nagłówku dokumentu dopisujemy następujący skrypt:

  1. <script type="text/javascript">
  2.  $(document).ready(
  3.   function (){ 
  4.    $("input#urzadzenia").autocomplete("jq_urzadzenia.php",
  5.     {width: 200,max: 10,selectFirst: false, cacheLength: 1});
  6.   }
  7.  );
  8. </script>

W lini nr 4 tego skryptu widzimy wywołanie funkcji autocomplete() dla elementu <input/> o id=”urzadzenia”, czyli dla jedynego elementu tego typu w naszym formularzu. Oczywiście jeśli jest tylko jedne nie musimy go szukać po id, ale lepiej wyrobić sobie taki nawyk. Przecież formularz rzadko składa się z jednego okienka <input/>.

W naszym przykładzie funkcja autocomplete() przyjmuje dwa parametry. Pierwszy z nich definiuje źródło danych, drugi to opcje. O opcjach nie będę się szczegółowo rozpisywać. Nie widzę sensu przepisywania dokumentacji , coś nieco tylko wspomnę o niektórych. Bardziej istotny jest pierwszy parametr. Może to być tablica z danymi, lub jak to jest w naszym przypadku plik, który dane będzie generował dynamicznie. Do takiego skryptu metogą get przekazywany jest niejawny parametr ‘q’, którym jest string wpisany do okienka <input/>. Cała sztuka więc polega na tym, żeby odebrać tę zmienną i sprawdzić które pozycje z listy pasują do wpisanego stringu. Poniżej najprostszy skrypt z pliku jq_urzadzenia.php

  1. <?php
  2. $q = $_GET['q'];
  3. if(!$q) return;
  4.  
  5. $dane = array('aparat','motor','rower','samochód','telefon','telewizor');
  6. $i = 0;
  7. foreach ($dane as $id => $wartosc) {
  8.   if(preg_match('/^'.$q.'/', $wartosc)){
  9.     echo $wartosc.PHP_EOL;
  10.     $i++;
  11.   }
  12. }
  13.  
  14. if(!$i) echo "urz±dzenie spoza listy\n";
  15.  
  16. ?>

Skrypt pobiera wspomniany już parametr ‘q’, jeśli z jakiegoś powodu nie ma on wartości to kończy swoje działanie. W przeciwnym razie definiuje listę pozycji podpowiedzi. W tym przykładzie oczywiście statycznie, ale nic nie stoi na przeszkodzie, żeby w tym miejscu dokonać zapytania do bazy i stworzyć dynamicznie tę tablicę. Dlaczego to ma być tablica? Bo łatwo takie dane obsłużyć.

Po zdefiniowaniu tablicy zaczyna się pętla (linie 7-12), która szuka w niej wartości zgodnych wartością przekazaną w do skryptu. Pobiera kolejne łańcuchy znaków z tablicy i sprawdza, czy zawierają one łańcuch wpisany do okienka <input/>. Ja w tym celu wykorzystuję funkcję preg_match(), która korzysta z Perlowych wyrażeń regularnych a w dodatku wymuszam (poprzez zastosowanie metaznaku ^) aby wybrana pozycja zaczynała się od zadanego ciągu. Oczywiście tak skonstruowany skrypt jest czuły na wielkość liter. Można wykorzystać funkcję strtolower() na przykład modyfikując warunek w ten sposób:

  1. if(preg_match('/^'.strtolower($q).'/', strtolower($wartosc))){

ale należy pamiętać, że ta funkcja sprawia poważne problemy w przypadku obecności polskich znaków w stringach i bezpieczniej by było samemu napisać odpowiednią funkcję. Wartości z tablicy, które spełniają zadany warunek (oczywiście może on być skonstruowany zupełnie inaczej, a ograniczeniem są tylko nasze potrzeby i wyobraźnia) są wyświetlane za pomocą funkcji echo. Ważne jest, aby zawsze na końcu znalazł się znak nowej linii, gdyż kolejne linie będą pojawiać się w okienku podpowiedzi jako niezależne pozycje.

W zaproponowanym tu skrypcie znajduje się dodatkowo licznik pozycji pasujących do wzorca. Dodałam go po to, żeby ułatwić zadanie użytkownikowi. Ponieważ jeśli w tablicy nie znajdzie się żadna pozycja pasująca do wzorca zostanie wyświetlony komunikat odpowiedni komunikat w tym wypadku: “urządzenie spoza listy”;

I to już tyle. Jeśli chcesz możesz zobaczyć jak to działa: demo

Lada moment opublikuję kolejny odcinek w którym pokażę co jeszcze można wydusić z tego pluginu.

Poleć wpis na:

  • Facebook
  • Technorati
  • Wykop

Podobne artykuły:

  1. Autouzupełnianie w polach formularza. Odc.3.
  2. Autouzupełnianie w polach formularza. Odc.2.
  3. Nadszedł czas na jQuery

Komentarze (18) do “Autouzupełnianie w polach formularza. Odc.1.”

  1. prz-emo Says:

    Ciekawa opcja :)
    Nie myślałem, że przez jQuery można coś takiego stworzyć :)
    Dzięki za wpis

  2. Joanna Says:

    Oj można jeszcze więcej. Zobaczysz w drugim odcinku :)

  3. Bodzio Says:

    Witam
    Niestety nie mogę sobie poradzić z pobraniem danych z bazy mysql

    robie to w następujący sposób:

    while($dane = mysql_fetch_array($wynik))

  4. Joanna Says:

    Przyślij mi na e-mail cały kod w którym pobierasz dane i przygotowujesz je do autouzupełniania. Spróbuję rzucić okiem.

  5. Don Camillo Says:

    Ciekawy artykuł, oby więcej takich :D

  6. Maciek Says:

    Witam Panią bardzo fajnie to Pani pokazała na przykładzie a ja szukałem autouzupełnienia i proszę tu tak przyjaźnie napisane. Mam też i pytanie do Pani, w przykładzie pokazuje Pani autouzupełnianie na przykładzie danych wprowadzonych ręcznie do skryptu: “jq_urzadzenia.php” moje pytanie brzmi czy mogła by Pani pokazać jak np pobierać dane do autouzupełnienia z bazy danych i to np określone dane z określonych tabel to by było ciekawe bo np jakbyśmy chcieli zrobić taki trik dla kodów pocztowych albo miejscowości to wpisywanie ręcznie wszystkich tych danych do skryptu php było by koszmarem. Pozdrawiam serdecznie

  7. Joanna Says:

    To nic skomplikowanego. Zamiast:
    $dane = array(‘aparat’,'motor’,'rower’,’samochód’,'telefon’,'telewizor’);

    trzeba napisać:

    $dane = moja_funkcja();

    No i gdzieś trzeba tę funkcję zdefiniować tak, żeby zwracała tablicę.

    Oczywiście tablica kodów pocztowych byłaby koszmarnie długa. Są sposoby, aby pobierać tylko potrzebną część danych. Może faktycznie pokuszę się o stosowny tutorial.

  8. artvip Says:

    Witam,

    szkoda, że tak późno tutaj trafiłem :) W sumie przerobiłem skrypt aby pobierał informacje z bazy (MSSQL). Walczę teraz z kodowaniem :( Niestety mam krzaczki.. problem rozwiązuje częściowo:
    header(‘Content-Type: text/html; charset=windows-1250′);
    Częściowo ponieważ nie wyszukuje słów rozpoczynających się polskimi literami.. natomiast jak polska litera jest druga i kolejna to nie ma problemu. Przykład:
    maść -> i jest ok, prawidłowo sugeruje, prawidłowo rozpoznaje ść, wpisując maść widzi pl znaki
    natomiast słowo:
    ściana -> nie znajduje, nie daje żadnej sugestii do słów rozpoczynających się od polskich znaków śćźłż itd..
    Ma Pani jakiś pomysł na to?

    Dziękuję i pozdrawiam !

  9. Joanna Says:

    Ałć… A czemu stosujesz 1250? A feee.

    A czytałeś mój artykuł opolskich znakach w php? http://blog.bexlab.pl/polskie-znaki-w-php-dramat-w-czterech-aktach/65/

  10. artvip Says:

    Aha, czytałem :) Bazę MSSQL mam w Polish_CI_AS a strona kodowa dla tej kolacji to 1250. Wracając to mojego pytania -> problem nareszcie rozwiązałem. POST a nie GET :) Oto całe rozwiązanie :)

  11. Janusz Says:

    Przepisałem dosłownie cały kod zmieniając tylko nazwę inputa, ścieżki do js i danych (gotowa tabelka w js generowana phpem)
    wpisuję:

    $(document).ready(
    function (){
    $(“input#lista_osob”).autocomplete(“osoby”,
    {width: 200,max: 10,selectFirst: false, cacheLength: 1});
    }
    );

    i za każdym razem Firebug wypisuje mi: ‘autocomplete is not a function’

  12. Joanna Says:

    A co to jest “osoby”?

  13. Janusz Says:

    nazwa tabeli
    wycinek:
    var osoby = [
    {id:"00136", imie:"Anna"},
    {id:"00145", imie:"Adam"},
    {id:"00118", imie:"Zygmunt"},
    ]

  14. Joanna Says:

    Może problem tkwi w deklaracji tej tablicy? A czy to nie powinno być bez cudzysłowa?

  15. Janusz Says:

    w przykładach http://jquery.bassistance.de/autocomplete/demo/ był taki kod, ale nie za bardzo go rozumiem zwłaszcz formatItem :
    $(“#thickboxEmail”).autocomplete(emails, {
    minChars: 0,
    width: 310,
    matchContains: true,
    highlightItem: false,
    formatItem: function(row, i, max, term) {
    return row.name.replace(new RegExp(“(” + term + “)”, “gi”), “$1“) + “Email: <” + row.to + “>”;
    },
    formatResult: function(row) {
    return row.to;
    }
    });
    polami w tabeli emails były ‘to’ i ‘name’

  16. Joanna Says:

    Na temat formatItem naskrobię w wolnej chwili, ale tymczasem zwróć uwagę, że nazwę tablicy wstawia się bez cudzysłowu.

  17. Janusz Says:

    Kombinowałem już na wszelkie możliwe sposoby i nadal nic, a w dodatku muszę to mieć do wieczora :/ Może jest ktoś w stanie mi wyjaśnić gdzie mam błąd? (Uwaga strona stoi na powolnym serwerze)

    http://czacki.edu.pl/~janusz/af_test/panel_af/panel_af.php?czynnosc=dodawanie&tabela=rel_os_przedst_poz&zakl=baza&krok=1

  18. Janusz Says:

    Odkryłem co było nie tak. Dwa razy wrzucałem samo jQuery. :P

Zostaw komentarz

Silnik: Wordpress - Theme autorstwa N.Design Studio. Spolszczenie: Adam Klimowski.
RSS wpisów RSS komentarzy Zaloguj się