Статьи

Как использовать виджет автозаполнения пользовательского интерфейса jQuery

В этом уроке мы рассмотрим один из новейших компонентов jQuery UI 1.8 — виджет автозаполнения. Автозаполнение текстовых полей может быть популярным выбором для посетителей вашего сайта, поскольку они значительно упрощают ввод информации. Их можно использовать, например, в полях поиска товаров, или когда посетитель должен ввести страну, город или что-либо еще, что может быть выбрано из общего набора данных. Помимо того, что jQuery UI Autocomplete пользуется популярностью среди посетителей, он популярен среди разработчиков, поскольку он прост в использовании, мощен и гибок.

Я не большой поклонник Facebook, я предпочитаю Twitter ( @danwellman btw ), но мне нравится одна функция Facebook — это функция обмена сообщениями, которая позволяет отправлять сообщения друзьям или друзьям. Мне нравится, как автозаполнение используется для облегчения выбора имен вашего друга, и как имена форматируются после того, как они выбраны и добавлены в поле «to», например, у каждого из них есть близкая ссылка, которая позволяет имени быть легко удаляется без необходимости выделять какой-либо текст.

В этом руководстве мы будем использовать виджет автозаполнения пользовательского интерфейса jQuery для репликации этого аспекта системы обмена сообщениями Facebook. Однако мы не будем рассматривать фактическую отправку сообщений. Вот что мы собираемся создать:


Нам нужно будет создать пользовательский интерфейс jQuery, содержащий только те компоненты, которые нам нужны; перейдите к сборщику загрузок по адресу http://jqueryui.com/download . Нам нужно будет использовать следующие основные компоненты:

  • ядро
  • Виджет
  • Позиция

Нам также понадобится сам виджет автозаполнения, поэтому убедитесь, что только перечисленные выше элементы, а также автозаполнение, отмечены в разделе «Компоненты» слева. Используйте тему по умолчанию (UI Lightness) и убедитесь, что версия 1.8 выбрана справа.

После загрузки создайте новую папку на своем компьютере и назовите ее автозаполнением . Затем откройте архив и скопируйте папки css и js в новую папку, которую вы только что создали. Это даст вам все библиотечные файлы, необходимые для этого примера, включая сам jQuery, поэтому его не нужно загружать отдельно.


Давайте сначала посмотрим на HTML для <form> :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
<div id=»formWrap»>
    <form id=»messageForm» action=»#»>
        <fieldset>
            <legend>New message form</legend>
            <span>New Message
            <label id=»toLabel»>To:</label>
            <div id=»friends» class=»ui-helper-clearfix»>
                <input id=»to» type=»text»>
            </div>
            <label>Subject:</label>
            <input id=»subject» name=»subject» type=»text»>
            <label>Message:</label>
            <textarea id=»message» name=»message» rows=»5″ cols=»50″></textarea>
            <button type=»button» id=»cancel»>Cancel</button>
            <button type=»submit» id=»send»>Send</button>
        </fieldset>
    </form>
</div>

Это довольно стандартная форма; есть внешний контейнер <div>, который мы можем использовать для стилизации, а <input> , к которому будет добавлено автозаполнение, также находится внутри элемента <div> ; мы будем стилизовать <input> так, чтобы он был немного скрыт, и мы будем стилизовать <div> так, чтобы он выглядел как другие поля в форме. Мы даем контейнеру для <input> имя класса ui-helper-clearfix, чтобы использовать этот служебный класс из CSS-структуры jQuery UI.

Нам также понадобится ссылка на файлы, которые мы распаковали из архива пользовательского интерфейса jQuery, а также пользовательскую таблицу стилей; следующие файлы должны перейти в <head> страницы:

1
2
<link rel=»stylesheet» type=»text/css» href=»css/ui-lightness/jquery-ui-1.8.custom.css»>
<link rel=»stylesheet» type=»text/css» href=»css/autocomplete.css»>

Следующие файлы должны идти в конце <body> :


В этом примере мы используем очень простую, нейтральную тему, большая часть которой приведена исключительно в качестве примера. Требуется очень мало стилей, и большинство из них можно изменить при необходимости. Следующий CSS используется в таблице стилей autocomplete.css (все стили пользовательского интерфейса jQuery находятся в таблице стилей jquery-ui-1.8.custom.css ):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#formWrap {
    padding:10px;
    background:rgba(0,0,0,.5);
    -webkit-border-radius:10px;
}
#messageForm {
 width:326px;
}
#messageForm fieldset {
    padding:0;
    background-color:#eee;
}
#messageForm legend { visibility:hidden;
#messageForm span {
    display:block;
    text-indent:20px;
    border-bottom:1px solid #333;
}
#friends {
    width:274px;
    border:1px solid #aaa;
}
#messageForm #to {
    width:30px;
    position:relative;
}
#messageForm input, #messageForm textarea {
    display:block;
    border:1px solid #aaa;
}
#messageForm label {
    display:block;
    font:bold 11px Verdana, Sans-serif;
}
#messageForm #toLabel { margin-top:0;
#messageForm button { float:right;
#messageForm #cancel { margin-right:20px;
#friends span {
    display:block;
    position:relative;
    border:1px solid #333;
    -webkit-border-radius:7px;
    font:normal 11px Verdana, Sans-serif;
}
#friends span a {
    position:absolute;
    font:bold 12px Verdana, Sans-serif;
}
#friends span a:hover { color:#ff0000;
.ui-menu .ui-menu-item { white-space:nowrap;

Чтобы придать форме красивую прозрачную границу с закругленными углами, мы используем правило CSS3 RGBa и правила -moz-border-radius , -webkit-border-radius и border-radius ; большинство популярных браузеров теперь поддерживают эти правила, включая Firefox, Safari, Chrome и Opera. IE не поддерживает ни один из них, и хотя он может использовать фильтр для реализации элементарной непрозрачности, закругленные углы должны поддерживаться за счет использования изображений. Эффективность прозрачности RGBa не показана в полной мере в этом примере; но этот тип формы, вероятно, будет использоваться как плавающее модальное наложение в полной реализации, которая будет находиться над реальным содержимым на странице.

Контейнеру <div> вокруг поля <input> , к которому будет присоединено текстовое поле Autocomplete, назначается такое же расположение и стилизация, как и для элементов <input> , но у <input> в этом контейнере удалена его граница, поэтому скрытый. Мы также уменьшаем его ширину и перемещаем его влево. Это сделано для того, чтобы при добавлении отформатированных получателей в <div> <input> не переполнялся и не увеличивал высоту <div> без необходимости.

Мы также стилизуем получателей, которые будут добавлены к элементам <div> как <span>, содержащим ссылку. В основном они разработаны в соответствии с основной темой, а также имеют закругленные углы. Важно, чтобы эти элементы делались на уровне блоков и плавали, чтобы они правильно складывались. Нам также необходимо переопределить некоторые стили Automcomplete, предоставляемые темой пользовательского интерфейса jQuery, которую мы используем; последний селектор просто предотвращает разрыв отдельных предложений в меню между словами, что происходит потому, что мы сделали так, чтобы <input> ассоциировался с ним так мало.

На этом этапе форма должна выглядеть так:


Далее нам нужно прикрепить виджет автозаполнения к <input> внутри <div> ; Для этого мы можем использовать следующий скрипт:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<script type=»text/javascript»>
    $(function(){
             
        //attach autocomplete
        $(«#to»).autocomplete({
                     
            //define callback to format results
            source: function(req, add){
                     
                //pass request to server
                $.getJSON(«friends.php?callback=?», req, function(data) {
                             
                    //create array for response objects
                    var suggestions = [];
                             
                    //process response
                    $.each(data, function(i, val){
                    suggestions.push(val.name);
                });
                             
                //pass array to callback
                add(suggestions);
            });
        },
                     
        //define select handler
        select: function(e, ui) {
                         
            //create formatted friend
            var friend = ui.item.value,
                span = $(«<span>»).text(friend),
                a = $(«<a>»).addClass(«remove»).attr({
                    href: «javascript:»,
                    title: «Remove » + friend
                }).text(«x»).appendTo(span);
                         
                //add friend to friend div
                span.insertBefore(«#to»);
            },
                     
            //define select handler
            change: function() {
                         
                //prevent ‘to’ field being updated and correct position
                $(«#to»).val(«»).css(«top», 2);
            }
        });
    });
</script>

Виджет присоединяется к <input> с помощью метода autocomplete () . Мы предоставляем объектный литерал в качестве аргумента метода, который настраивает опцию источника и обратные вызовы событий select и change .

Опция источника используется, чтобы указать виджету, откуда взять предложения для меню автозаполнения. В качестве значения этой опции мы используем функцию, которая принимает два аргумента; первый — это термин, введенный в <input> , второй — функция обратного вызова, которая используется для передачи предложений обратно в виджет.

В этой функции мы используем метод getJSON () jQuery для передачи термина в файл PHP на стороне сервера. Файл PHP будет использовать термин для извлечения совпадающих имен контактов из базы данных MySql. Мы используем обратный вызов JSONP для обработки данных, возвращаемых с сервера; функция обратного вызова, которая передается в качестве второго аргумента опции источника, ожидает получения данных в массиве, поэтому сначала мы создаем пустой массив, а затем используем метод каждому () jQuery для обработки каждого элемента в массиве JSON, возвращаемого сервером , Мы просто перебираем каждый элемент в этом массиве и добавляем каждое предложение в наш новый массив. Как только наш новый массив построен, мы передаем его в функцию обратного вызова для отображения виджета в меню.

Затем мы определяем обработчик для пользовательского события выбора автозаполнения; эта функция будет выполняться виджетом каждый раз, когда в меню автозаполнения будет выбрано предложение. Эта функция автоматически передает два аргумента — объект события и объект пользовательского интерфейса, содержащий выбранное предложение. Мы используем эту функцию для форматирования имени получателя и добавления его в <div> . Мы просто создаем элемент <span> для хранения текста и элемент привязки, который можно использовать для удаления получателя. Как только отформатированный получатель был создан, мы просто вставляем его непосредственно перед закамуфлированным <input> .

Наконец, мы добавляем обработчик для события изменения ; эта функция будет вызываться всякий раз, когда значение <input>, которое автозаполнение связано с изменениями. Мы просто используем его для удаления значения из <input>, потому что мы уже добавили отформатированную версию в наш контейнер <div> . Карат выглядит немного высоко после добавления отформатированного имени контакта в <div>, поэтому мы также используем этот обработчик событий, чтобы исправить это.

Это все настройки, которые нам нужны для этой конкретной реализации, но есть еще пара дополнительных функций, которые нам нужно добавить, чтобы немного привести в порядок вещи. После метода autocomplete () добавьте следующий код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
//add click handler to friends div
$(«#friends»).click(function(){
                     
    //focus ‘to’ field
    $(«#to»).focus();
});
                 
//add live handler for clicks on remove links
$(«.remove», document.getElementById(«friends»)).live(«click», function(){
                 
    //remove current friend
    $(this).parent().remove();
                     
    //correct ‘to’ field position
    if($(«#friends span»).length === 0) {
        $(«#to»).css(«top», 0);
    }
});

Элемент <input>, к которому присоединено наше автозаполнение, частично скрыт, а его контейнер <div> стилизован так, что он выглядит как другие поля формы; чтобы завершить обман, мы добавляем обработчик кликов в контейнер <div>, чтобы щелчок в любом месте внутри него фокусировал фактический <input> . Визуально и функционально теперь <div> должен быть неотличим от обычного поля.

Нам также нужно обрабатывать щелчки на привязке, которая добавляется к каждому отформатированному получателю; мы используем метод live () jQuery, потому что эти элементы могут существовать или не существовать на странице в любой момент времени, и это проще, чем привязывать функцию-обработчик каждый раз, когда мы создаем один из этих якорей. Всякий раз, когда мы нажимаем на один из этих якорей, мы переходим к родителю того якоря, на который щелкнули, а затем удаляем его со страницы. Помните, когда мы исправили положение карата ранее в сценарии? Нам просто нужно проверить, все ли получатели были удалены, и, если это так, сбросить его позицию обратно на значение по умолчанию.


Я использовал базу данных MySql, содержащую таблицу, в которой перечислены все имена получателей, и следующий файл PHP, чтобы принимать данные, отправленные методом getJSON (), и извлекать совпадающих получателей из базы данных:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
 
    //connection information
    $host = «localhost»;
    $user = «root»;
    $password = «your_mysql_password_here»;
    $database = «test»;
    $param = $_GET[«term»];
     
    //make connection
    $server = mysql_connect($host, $user, $password);
    $connection = mysql_select_db($database, $server);
 
    //query the database
    $query = mysql_query(«SELECT * FROM friends WHERE name REGEXP ‘^$param'»);
     
    //build array of results
    for ($x = 0, $numrows = mysql_num_rows($query); $x < $numrows; $x++) {
        $row = mysql_fetch_assoc($query);
     
        $friends[$x] = array(«name» => $row[«name»]);
    }
     
    //echo JSON to page
    $response = $_GET[«callback»] .
    echo $response;
     
    mysql_close($server);
     
?>

Для запуска загружаемых файлов примеров вам понадобится веб-сервер разработки с установленным и настроенным PHP, а также MySql и соответствующая база данных и таблица. Когда буква вводится в поле «to», эта буква передается на сервер и используется для извлечения каждого имени, которое начинается с набранной буквы. Соответствующие имена затем передаются обратно на страницу в формате JSON и отображаются в меню предложений:

В этом руководстве показано, как реплицировать форму отправки сообщений Facebook, в частности, как друзья добавляются в форму обмена сообщениями в качестве получателей с помощью автозаполнения, и как имена друзей форматируются после добавления, чтобы их можно было легко удалить. Наш пример формы на самом деле ничего не делает, но нам нужно было бы на самом деле отправить форму, чтобы передать содержимое формы в файл на стороне сервера для отправки с использованием AJAX, который можно легко подключить к отправке. событие кнопки отправки, используемой в форме.

Конечно, получатели должны иметь какое-то значение для внутренней системы и, вероятно, будут сопоставлены с адресами электронной почты в базе данных. Нам нужно извлечь текстовое содержимое каждого из элементов <span> перед тем, как вернуться на сервер, хотя это было бы довольно тривиальным вопросом.

Виджет автозаполнения пользовательского интерфейса jQuery позволяет легко подключаться к любому источнику данных и содержит богатый набор обработчиков событий, которым мы можем предоставить функции, чтобы реагировать на ввод текста в соответствующее поле или выбор в меню. Стилизация виджета осуществляется с использованием обширной CSS-инфраструктуры пользовательского интерфейса jQuery, и его можно легко изменить, чтобы он соответствовал существующей теме сайта. В общем, это отличный виджет, который прост в использовании и обеспечивает отличную функциональность.