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:
- <link rel="stylesheet" href="./jq-ac/jquery.autocomplete.css" type="text/css" />
- <script type="text/javascript" src="./jq-ac/lib/jquery.js"></script>
- <script type="text/javascript" src="./jq-ac/lib/jquery.dimensions.js"></script>
- <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:
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:
- <script type="text/javascript">
- $(document).ready(
- function (){
- $("input#urzadzenia").autocomplete("jq_urzadzenia.php",
- {width: 200,max: 10,selectFirst: false, cacheLength: 1});
- }
- );
- </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
- <?php
- $q = $_GET['q'];
- if(!$q) return;
- $i = 0;
- foreach ($dane as $id => $wartosc) {
- echo $wartosc.PHP_EOL;
- $i++;
- }
- }
- ?>
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:
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.
11 paź 2008 o 11:30
Ciekawa opcja

Nie myślałem, że przez jQuery można coś takiego stworzyć
Dzięki za wpis
14 paź 2008 o 12:42
Oj można jeszcze więcej. Zobaczysz w drugim odcinku
16 lis 2008 o 22:35
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))
17 lis 2008 o 11:01
Przyślij mi na e-mail cały kod w którym pobierasz dane i przygotowujesz je do autouzupełniania. Spróbuję rzucić okiem.
17 kwi 2009 o 13:10
Ciekawy artykuł, oby więcej takich
1 sie 2009 o 20:39
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
1 sie 2009 o 21:05
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.
1 kwi 2010 o 10:52
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 !
1 kwi 2010 o 23:00
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/
2 kwi 2010 o 8:59
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
15 maj 2010 o 17:49
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’
15 maj 2010 o 18:05
A co to jest “osoby”?
15 maj 2010 o 18:11
nazwa tabeli
wycinek:
var osoby = [
{id:"00136", imie:"Anna"},
{id:"00145", imie:"Adam"},
{id:"00118", imie:"Zygmunt"},
]
15 maj 2010 o 19:00
Może problem tkwi w deklaracji tej tablicy? A czy to nie powinno być bez cudzysłowa?
15 maj 2010 o 19:10
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’
15 maj 2010 o 19:28
Na temat formatItem naskrobię w wolnej chwili, ale tymczasem zwróć uwagę, że nazwę tablicy wstawia się bez cudzysłowu.
16 maj 2010 o 11:52
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
16 maj 2010 o 15:15
Odkryłem co było nie tak. Dwa razy wrzucałem samo jQuery.