Jednak tak jak się spodziewałem, z powodu braku czasu, nie udaje mi się pisać tyle ile bym chciał. Może po obronie pracy inżynierskiej czas pozwoli na większą aktywność.
Ale do rzeczy, dzisiaj chciałbym zainteresować wszystkich kolejnym pluginem do jQuery – jQuery.Autocomplete. Jeśli zastanawialiście się jak wykonać podpowiedzi w stylu Googla, to w tej notce znajdziecie namiastkę odpowiedzi na to pytanie.
Osobiście z wspomnianą już wtyczką spotkałem się kiedy chciałem uzyskać efekt podpowiedzi w tworzonym formularzu, tak aby potencjalnemu użytkownikowi tworzonego właśnie serwisu podpowiedzieć wpisywaną miejscowość (jedno z wymaganych pół w tymże formularzu).
Efekt ten można wykorzystać w wielu miejscach by podpowiedzieć użytkownikowi dokończenie wpisywanej przez niego frazy, kiedy to tworzymy różnego rodzaju formularze, czy to rejestracji, czy też wyszukiwania.
Aby uzyskać efekt autopodpowiedzi na naszej stronie, potrzebne nam będą:
- biblioteka jQuery – do pobrania ze strony http://jquery.com/
- wtyczka jQuery.Autocomplete – do pobrania ze strony autora http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/
- i jak zawsze – odrobina czasu i dobrych chęci
Przyjrzyjmy się działaniu wtyczki w akcji:
Jak widać na powyższym przykładzie, jednym z parametrów jaki trafia do f-cji autocomplete() są dane w postaci spreparowanej tablicy z miastami. Nie jest to jedyny sposób zaserwowania zestawu danych, które zostaną wykorzystane przez ten plugin. O pozostałych sposobach przeczytasz nieco niżej. Wcześniej jednak zapoznajmy się z pozostałymi parametrami tej f-cji i przeanalizujmy jej możliwości.
Jak podaje dokumentacja pełne wywołanie f-cji autocomplete() ma postać:
$(uchwyt).autocomplete( url or data, [options] );
Podkreślone wartości, są wartościami domyślnymi.
- autoFill – true/false – w trakcie wpisywania, nasz input zostanie automatycznie wypełniony pierwszą z pasujących wartości
- cacheLength – 10 – ten parametr określa ile wyników z zewnętrznego źródła zostanie zapamiętanych w pamięci podręcznej skryptu
- delay – 400 ms dla źródeł zdalnych i 10 ms dla źródeł lokalnych – definiujemy czas (w milisekundach) po którym podpowiedzi są aktywowane (czas liczony od wciśnięcia klawisza)
- extraParams – tej opcji używamy gdy chcemy przekazać jakieś dodatkowe parametry do skryptu za pomocą, którego będziemy pobierać dane z zewnętrznego źródła, np.: ustawienie wartości tego pola na: {zmienna: 4} spowoduje takie wywołanie: nasz_skrypt.php?q=fraza&zmienna1=4 – „fraza” to szukane przez nas słowo, parametry przekazywane są poprzez $_GET, ale o tym nieco niżej
- formatItem, formatMatch, formatResult – 3 funkcje które pozwalają sformatować kolejno: pozycję na liście z podpowiedziami, zapytanie, dane które trafią do naszego input’a, jako rezultat zapytania
- highlight – false/function – podświetla szukaną przez nas frazę, w zwracanym ciągu, domyślnie powoduje pogrubienie danej frazy, możemy nadać jej wartość, albo zdefiniować w tym miejscu zupełnie nową funkcję
- max – 10 – określa max liczbę pasujących elementów jaka zostanie pobrana / wyświetlona jako podpowiedź, wartość określona przez ten parametr wysyłana jest do zewnętrznego źródła, jako limit, np.: miasta.php?limit=10
- minChars – 1 – oznaczą, ile znaków należy wpisać, aby aktywować nasze podpowiedzi
- multiple – true/false – pozwala na wprowadzenie do danego pola, więcej niż jednej wartości
- multipleSeparator – przecinek , – znak, który zostanie wstawiony między wiele wartości (jeśli poprzednia opcja jest aktywna)
- mustMatch – true/false – możemy nakazać aby fraza wpisywana do naszego inputa była zgodna z jedną z podpowiadanych wartości
- scroll – true/false – włącza pasek przewijania kiedy wyników jest więcej, tak że nie mieszczą się w szerokości zdefiniowanej w scrollHeight
- scrollHeight – 180 – wysokość listy z podpowiedziami
- selectFirst – true/false – ustawia automatycznie podświetlenie na pierwszym z sugerowanych elementów, zanim jeszcze zdążymy wykonać jakąś reakcję klawiaturą lub myszką
- width – auto – szerokość listy z podpowiedziami, domyślnie lista przyjmuje szerokość elementu do którego jest przypisana
A teraz prześledźmy niektóre z powyższych opcji na przykładach:
Aby zademonstrować użycie opcji formatItem, formatMatch, formatResult najłatwiej będzie posłużyć się źródłem zewnętrznym. Przekazujemy wówczas do funkcji adres www, spod którego będziemy pobierać dane na potrzeby naszych podpowiedzi, np.:
$(uchwyt).autocomplete('miasta.php', [options] );
Na potrzeby tego przykładu utworzymy sobie prostą bazę SQLite, z miastami (oczywiście w tym miejscu możemy skorzystać z dowolnego silnika bazy danych):
// php
$db = new SQLiteDatabase('baza.sqlite');
$db->query("
CREATE TABLE miasta (
miasto_id INTEGER PRIMARY KEY,
miasto_nazwa VARCHAR(50),
miasto_wojewodztwo VARCHAR(50)
);
INSERT INTO miasta VALUES (NULL, 'Wadowice','woj. małopolskie');
INSERT INTO miasta VALUES (NULL, 'Wałbrzych','woj. dolnośląskie');
INSERT INTO miasta VALUES (NULL, 'Wałcz','woj. zachodniopomorskie');
INSERT INTO miasta VALUES (NULL, 'Warka','woj. mazowieckie');
INSERT INTO miasta VALUES (NULL, 'Warszawa','woj. mazowieckie');
INSERT INTO miasta VALUES (NULL, 'Warta','woj. łódzkie');
INSERT INTO miasta VALUES (NULL, 'Wasilków','woj. podlaskie');
");
Następnie utworzymy prosty skrypt miasta.php, który będzie pobierał nam odpowiedni fragment tej bazy:
// php
@$q = $_GET['q'];
$db = new SQLiteDatabase('baza.sqlite');
$result = $db->query("SELECT * FROM miasta WHERE miasto_nazwa LIKE '%$q%';");
while ($result->valid()) {
$row = $result->current();
echo $row['miasto_id']."|".$row['miasto_nazwa']."|".$row['miasto_wojewodztwo']."\n";
$result->next();
}
Skrypt ten zwróci nam dane w postaci:
1|Wadowice|woj. małopolskie 2|Wałbrzych|woj. dolnośląskie 3|Wałcz|woj. zachodniopomorskie 4|Warka|woj. mazowieckie 5|Warszawa|woj. mazowieckie 6|Warta|woj. łódzkie 7|Wasilków|woj. podlaskie
I jeszcze kilka przykładów na koniec:
W opisie celowo pominąłem opis parametrów matchCase, matchContains oraz matchSubset, używa się ich w połączeniu z cachowaniem zapytań do zewnętrznych źródeł, jednak do tej pory nie znalazłem dla nich żadnego ciekawego zastosowania.
Uwaga! Ważna informacja dotycząca parametru minChars.
Aż do wersji 1.1 skryptu (w chwili pisania tej notki, wersja aktualna) występuje problem z parametrem minChars, aby działał prawidłowo należy znaleźć w skrypcie fragment:
for (var i = q.length - 1; i >= options.minChars; i--) {
i zamienić go na:
for (var i = q.length - 1; i >= 1; i--) {
Po kolejne przykłady odsyłam wszystkich zainteresowanych: – tutaj – .
20 komentarzy
Witam,
Artykuł OK. Ale mam jeden problem, jak wybieram z podpowiedzi jakąś propozycje do wyszukiwarki to muszę dwa razy klikać enter czyli najpierw wybieram a później raz jeszcze muszę potwierdzić enterem(bo automatycznie do inputa nie wpada). A oczywiście bym chciał by po wyborze automatycznie wyszukiwało bez podwójnego potwierdzenia.
Jakaś podpowiedź?
Jeśli dobrze Ciebie zrozumiałem Łukaszu, to tutaj masz przykład:
http://dev.baczyk.net/snippet/js/jquery-autocomplete-result.php
No dokładnie oto chodzi, użyłem twojego artykułu by rozbudować wyszukiwarkę w oscommerce o taką opcję jak (MAGICZNE PODPOWIEDZI) i naprawdę jest świetny ale tego nie widzę czego mi brakuje:
$().ready(function() {
$(„#targetDiv”).autocomplete(„mysql.php”, {
width: 560,
scrollHeight: 350,
minChars: 2,
selectFirst: true,
formatItem: function(row, i, max) {
return row[1] + ” (nr indeksu: ” + row[0] + „)„;
},
formatMatch: function(row, i, max) {
return row[1];
},
formatResult: function(row) {
return row[1];
}
});
});
I w indexie html:
<form name="quick_find" action="” method=”get”>
Jak byś miał chwile zajrzeć i wskazać mi błąd będę wdzięczny po 4 godz nad nie wiele widzę, a na forach jakoś nie bardzo są w temacie
A i to jeszcze w indexie html bo ucieło mi:
input type=”text” name=”keywords” size=”10″ maxlength=”30″ id=”targetDiv” style=”width: 195px”
No to posługując się przykładem, który Ci przygotowałem brakuje Ci chyba tego fragmentu:
$(„input[name='miasto1']„).result(function(){
$(„#formularz”).submit();
});
Co dla kodu, który tutaj wkleiłeś powinno wyglądać tak:
$(„#targetDiv”).result(function(){
$(„form[name=quick_find]„).submit();
});
Wielkie dzięki!
W którym momencie jest przesyłana zmienna wykorzystana w zapytaniu do bazy danych, w przykładzie z SQLite? NIe bardzo rozumiem skąd się bierze $_GET['q']
Ok, cofam pytanie
Mam pytanie pewnie banalne ale czy np gdy robi zapytanie do bazy po 3 znakach np takie :
SELECT * FROM `miasto` WHERE miasto Like ‘Wro%’
to czy po wpisaniu 4 znaku robi kolejne zapyatnie :
SELECT * FROM `miasto` WHERE miasto Like ‘Wroc%’
?? czy cachuje w pamięci wyniki z pierwszego zapytania i tylko już z pośród nich przeszukuje ??
Jeśli dobrze pamiętam, to wyniki są keszowane, i potem następuje jedynie zawężenie wokół danych, które już zostały pobrane.
Jak przekazać dane z
foreach ($this->dane as $entry):
echo $entry->miasto.’,’.$entry->miasto_id; echo „\n”;
endforeach;
do
formatItem: function(row, i, max) {
return row[1] + ” (ID: ” + row[0] + „)”;
},
?
Wszystkie dane wyświetlają mi się w row[0].
@Jarek: zamień przecinek na | tak jak jest w przykładzie i powinno działać.
Faktycznie działa.
Jeszcze zastanawiam się nad jednym, otóż chciałbym przesłać :
formatResult: function(row) {
return row[0] + „, ” + row[4];
}
Jednak w polu input chciałbym aby użytkownik widział tylko to co w row[0], bez row[4]
@Jarek no to tak w formatItem(), jak i formatResult() zwracasz tylko row[0]
Niestety nowy firefox 3.6, ma buga i autocomplete raz działa raz nie
.
Bardzo fajny tutorial, dzięki! Mam jednak pytanie: chciałbym zrobic autocomplete takie jak w Zumi – najpierw miasto, potem ulica. Używam $(‘#nazwa’).result(function(event, data, formatted) { } i podmieniam $(„#nazwa”).autocomplete () na inną tablice (wszystkie miasta i ulice są na razie statyczne). Problem w tym, że po flushu przestaje działać poprawnie autocomplete – wyswietla prawidłowe match’e ale niestety nie wkleja ich do inputa – tylko pierwsze litery, ktore wpisalem. Zeby się poprawnie wkleilo – musze zaczac znow wpisywac pierwsze litery ulicy.
Rozwiązane: ustawiłem multipleSeparator: „” zamiast na multipleSeparator: ” ” (spacja w środku). Teraz pomimo zmiany źródła danych działa jak trzeba.
Fajny tutorial, znalazłem rozwiązanie
starałem się zrobić wg podanego wzoru, ale coś mi nie wychodzi….
plik dane.php
valid()) {
$row = $result->current();
echo $row['id_book']."|".$row['imie_nazwisko']."\n";
$result->next();
}
?>
oraz plik z html
jQuery Autocomplete
$(function(){
$("input[name='miasto1']").autocomplete('dane.php',{
width:300,
formatItem: function(row, i, max) {
return row[1] + " (ID: " + row[0] + ")";
},
formatMatch: function(row, i, max) {
return row[1];
},
formatResult: function(row) {
return row[1];
}
});
});
/*demo page css*/
body { font: 62.5% "Tahoma", sans-serif; margin: 10px 0px; color:#111111; }
h1,h2,h3,h4,h5 { color: #555555; }
h1 { font-size: 17px; font-weight: bold; }
h2 { font-size: 13px; font-weight: bold; }
h3 { font-size: 11px; font-weight: bold; }
img { vertical-align: middle; }
pre { font-size: 11px; margin: 10px 0px; }
div.c { margin: 10px 0px; font-size: 11px; }
.ac_results {
padding: 0px;
border: 1px solid black;
background-color: white;
overflow: hidden;
z-index: 99999;
}
.ac_results ul {
width: 100%;
list-style-position: outside;
list-style: none;
padding: 0;
margin: 0;
}
.ac_results li {
margin: 0px;
padding: 2px 5px;
cursor: default;
display: block;
/*
if width will be 100% horizontal scrollbar will apear
when scroll mode will be used
*/
/*width: 100%;*/
font: menu;
font-size: 12px;
/*
it is very important, if line-height not setted or setted
in relative units scroll will be broken in firefox
*/
line-height: 16px;
overflow: hidden;
}
.ac_loading {
background: white url('indicator.gif') right center no-repeat;
}
.ac_odd {
background-color: #eee;
}
.ac_over {
background-color: #0A246A;
color: white;
}
Przykład 4. Użycie opcji formatItem, formatMatch, formatResult.
4.1 formatujemy sposób prezentacji listy, do naszego inputa przesyłamy nazwę miasta
Miejscowość: ( Naciśnij "W", aby wywołać podpowiedzi. )
proszę o pomoc
Napisz komentarz