Widżet Autocompleter dla Mootools
Łatwy w instalacji, szybki i wygodny widżet z podpowiadaniem wyników
06 Maj 2011
Autor: Tomasz Wójcik / Weeby.pl
Jednym z najczęściej stosowanych w dzisiejszych aplikacjach webowych widżetów jest pole tekstowe z podpowiadaniem wyników w menu. Ze względu na brak zadowalającego nas widżetu tego typu dla frameworka Mootools, stworzyliśmy go sami, wzorując się na kontrolce wchodzącej w skład biblioteki jQuery UI.

Plugin do działania wymaga użycia Mootools w wersji 1.2.x lub 1.3.x (w wersji kompatybilnej z 1.2). Przetestowaliśmy widżet we wszystkich nowoczesnych przeglądarkach WWW (Internet Explorer 7 i 8, Opera 11, Firefox 3.6 i 4, Google Chrome oraz Apple Safari) pod systemami operacyjnymi Windows i Mac OS X.
Przykład zastosowania widżetu
Online Demo | Widżet na Google Code
Zaczynamy od przygotowania bazowego dokumentu XHTML, w którym umieszczamy element <input>:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Mootools Autocompleter</title>
<script type="text/javascript" src="static/js/mootools-core-1.3-full-compat.js"></script>
<script type="text/javascript" src="static/js/mootools-autocompleter-1.1-yc.js"></script>
<link rel="stylesheet" type="text/css" href="static/css/style.css" />
</head>
<body>
<div class="input text">
<label>Wybierz ikonę</label>
<input id="inputIcon" type="text" name="icon" />
</div>
<div class="input">
<p>ID wybranego elementu: <span id="itemId">?</span></p>
</div>
</body>
</html>
W tej chwili pole tekstowe jest standardowym elementem HTMLa. Pliki JavaScript z frameworkiem i pluginem są załadowane, więc pora na podpięcie widżetu do pola:
window.addEvent('domready', function() {
var input = $('inputIcon');
var options = { 'source': dataSource };
input.autocompleter(options);
});
Metoda inicjująca widżet jako parametr przyjmuje obiekt zawierający opcje. Kod ten należy dodać do nowego tagu <script> w sekcji <head> dokumentu.
Źródło danych
Pole source obiektu options definiuje źródło danych. Jest nim funkcja, którą widżet wywołuje gdy zaczyna szukać, jako parametr podając wpisany przez użytkownika ciąg znaków. Źródło danych albo szuka synchronicznie (np. w elementach <option> elementu <select>) i zwraca wynik albo szuka asynchronicznie (np. wysyła żądanie przez AJAX do backendu) i po zakończeniu komunikacji wywołuje metodę suggest widżetu przekazując do niej wynik wyszukiwania.
Przykładowa funkcja wyszukująca asynchronicznie wygląda tak:
var dataSource = function(ui, term) {
var ajaxComplete = function(data) {
ui.autocompleter('suggest', data);
} // eof ajaxComplete()
var ajaxError = function() {
alert('Błąd połączenia!');
} // eof ajaxError()
var request = new Request.JSON({
url: 'filter.php',
method: 'GET',
data: { 'term': term },
onSuccess: ajaxComplete,
onFailure: ajaxError
}).send();
return true;
};
Interakcja
Jeśli chcemy, żeby widżet był bardziej interaktywny, możemy wykorzystać do tego celu zdarzenie onChange. W funkcji obsługującej to zdarzenie będziemy zmieniali tekst wewnątrz elementu #itemId:
input.autocompleter('option', 'onChange', function(ui) {
$('itemId').set('html', (ui.autocompleter('value') == '') ? '?' : ui.autocompleter('value'));
} // eof onChange()
);
Kod JavaScript przykładu
window.addEvent('domready', function() {
var input = $('inputIcon');
var dataSource = function(ui, term) {
var ajaxComplete = function(data) {
ui.autocompleter('suggest', data);
} // eof ajaxComplete()
var ajaxError = function() {
alert('Błąd połączenia!');
} // eof ajaxError()
var request = new Request.JSON({
url: 'filter.php',
method: 'GET',
data: { 'term': term },
onSuccess: ajaxComplete,
onFailure: ajaxError
}).send();
return true;
} // eof autoComplete()
var options = { 'source': dataSource };
input.autocompleter(options);
input.autocompleter('option', 'onChange', function(ui) {
$('itemId').set('html', (ui.autocompleter('value') == '') ? '?' : ui.autocompleter('value'));
} // eof onChange()
);
});
Widżet jest teraz w pełni funkcjonalny – wyszukuje korzystając z backendu, wyświetla listę podpowiedzi i pozwala wybrać z niej jedną wartość.
Podsumowanie
Dodanie funkcjonalności podpowiedzi do pola tekstowego z użyciem naszego widżetu jest bardzo proste. Ten krótki artykuł nie przedstawia wszystkich możliwości naszego pluginu. Więcej informacji na ten temat można znaleźć na stronie Google Code projektu.
Witam,
jak zmodyfikować kod żeby używać HTML Request do scenariuszu na PHP (chcę szukać podpowiedzi w bazie danych).
Dziękuję z góry,
widżet wygląda i działa ślicznie
Piotrek
Witam,
metoda suggest widżetu oczekuje tablicy, więc przekazanie HTMLa nie jest możliwe. Mój przykładowy kod wykorzystuje AJAX (funkcja dataSource w ostatnim fragmencie kodu) do pobrania danych z backendu, który wyszukuje w tablicy danych. Tak działa przykład. W środowisku produkcyjnym wystarczy przefiltrować DB i odpowiedzeć na żądanie tablicą wyników zakodowaną w JSON. Więcej o strukturze danych przekazywanych do metody suggest można znaleźć w dokumentacji projektu na stronie Google Code.
Pozdrawiam,
Tomek.
Hi,
Nice piece of work.
can i know whether if it’s possible to modify the mootools-autocompleter.js to accept 2 hidden values instead of just one?
Thanks & Regards,
Jacky
Hi Jacky,
I’ve updated the widget to support additional data sent from data source. Please check out the project’s Google Code page for more information about that feature and to get the 1.2 version which supports it.
Best regards,
Tomasz.
Hi Tomasz,
thanks for the update. But i have a question. How will i be able to input the additional data to the hidden field? From what i understand, the value attribute now stores in the data-autocompleter-default.
This is what i have for my json data without the HTML:
[{"value":"1","label":"Apple","data":"5"}]
Inline Script:
input.autocompleter(‘option’, ‘onChange’, function(ui) {
$(‘data’).set(‘value’, (ui.autocompleter(‘value’) == ”) ? ‘?’ : ui.autocompleter(‘value’));
} // end of onChange()
Form input field:
<input type="text" name="fruit" id="fruitSelect" data-autocompleter-default="” value=”" class=”inputbox” />
I will need the additional data field to be store in the hidden input so that the form will send out as: value=1 , data=5
Form input field:
I will need the additional data field to be store in the hidden input so that the form will send out as: value=1 , data=5
Hi Jacky,
our solution is a bit different. The „data” field of response item is attached using Mootools’ storage to the hidden input once the item is selected. Then it’s available using the data method, similarly to value.
I’m not completely sure what you want to achieve, but if I understand you correctly you want to send a second value with the form. If so then:
input.autocompleter(‘option’, ‘onChange’, function(ui) {
$(‘data’).set(‘value’, (ui.autocompleter(‘data’) == ”) ? ‘?’ : ui.autocompleter(‘data’));
});
The idea is that you can pass any data (e.g. a JS object or array) then access the data whenever you want to do whetever you want with them. My code snippet will assign the arbitrary data from the item to another input. I guess that’s what you want to achieve.
Hi Tomasz,
i managed to figure it out. What i have set to change will be the inline script:
input.autocompleter(‘option’, ‘onChange’, function(ui) {
$(‘data’).set(‘value’, (ui.autocompleter(‘data’) == ”) ? ‘?’ : ui.autocompleter(‘data’));
} // end of onChange()
);
So now, i will be able to input in the additional data to be submitted with the form with the default value. Thanks for your help. Really appreciate.
Yup, that’s what i’m trying to achieve. Have managed to get it to work now. Thanks again for the help tomasz. Your version of the autocompleter is much easier to use and understand compare to any other mootools autocompleter which i have been trying to implement. Didn’t managed to get the rest to work other than your solution. It’s a headache working with joomla MVC for the json data. Yours is much simpler and easier.
Looks like we both came up with the same solution.
Thanks for kind words and good luck with your project.