css, html, php, javascript, jQuery, ajax … – решения, примеры, рецепты
26 Фев
Если Вы пробовали что-то найти в Google, то наверняка знаете, что после ввода символа в текстовое поле появляется выпадающий список, который содержит десяток строк со словами, начальные символы которых совпадают с теми символами, что Вы уже успели ввести. Так работает Google Suggest. Почему бы не сделать так же на своем сайте? Ведь это удобно. К тому же с библиотекой jQuery это не так уж и сложно…
Как обычно, для начала я приведу пример, а потом мы будем разбирать, как он работает.
Поскольку это всего лишь пример, поясню, что в левом текстовом поле доступен выбор российских городов, которые начинаются на букву «М», а в правом – список поселков городского типа (пгт) с численностью населения более 10 тыс. жителей (по данным Всероссийской переписи населения на 9 октября 2002 года).
Кроме того, используются разные настройки. В общем, попробуйте пример, а потом продолжим….
Вы можете скачать исходный код примера, и при наличии библиотеки jQuery воспроизвести это пример на своем сайте.
Сначала потребуется только подключить библиотеку jQuery и файл query.autocomplete.js в разделе HEAD нужной страницы.
<script type="text/javascript" src="js/jquery-1.2.1.js"></script> <script type="text/javascript" src="js/jquery.autocomplete.js"></script>
Если скачаете пример, то легко сможете разобраться и в стилевом оформлении. Учтите, что файл jquery.autocomplete.js использует имена классов (начинаются с ac_), но если Вы захотите по каким-то причинам изменить эти имена – это тоже можно будет довольно легко сделать.
Что касается HTML-кода, то естественно нужно описать поле для ввода текста:
<input id="example" type="text" />
А вот использовать jquery.autocomplete.js можно двумя разными способами.
Способ первый:
Если объем данных не очень большой, и данные не будут изменяться, то их можно поместить непосредственно на странице, как и сделано в примере в текстовом поле слева.
<script type="text/javascript">
$(document).ready(function(){
$("#example").autocompleteArray([
"Магадан",
"Магас",
"Магнитогорск",
"Майкоп",
........
"Муром",
"Мценск",
"Мыски",
"Мытищи",
"Мышкин"
],
{
delay:10,
minChars:1,
matchSubset:1,
autoFill:true,
maxItemsToShow:10
}
);
});
</script>
Способ второй:
Если данные большого объема, и/или часто изменяются, то необходимо предусмотреть обработку этих данных на сервере (для примера выбран PHP). jquery.autocomplete.js предусматривает отправку GET-запроса с параметром q, значением которого являются введенные символы. Именно так в примере работает текстовое поле справа.
<script type="text/javascript">
$(document).ready(function(){
$("#example2").autocomplete("autocomplete.php", {
delay:10,
minChars:2,
matchSubset:1,
autoFill:true,
matchContains:1,
cacheLength:10,
selectFirst:true,
formatItem:liFormat,
maxItemsToShow:10,
onItemSelect:selectItem
});
});
</script>
В этих примерах, помимо данных (в первом случае) и URL обработчика (во втором случае) мы передаем некоторые опции. Список опций приведен ниже:
autoFill – когда Вы начинаете вводить текст, в поле ввода будет подставлено (и выделено) первое подходящее значение из списка. Если Вы продолжаете вводить текст, в поле ввода и далее будет подставляться подходящее значение, но уже с учетом введенного Вами текста. (По умолчанию: false).
inputClass – этот класс будет добавлен к элементу ввода. (По умолчанию: «ac_input»).
resultsClass – класс для UL, который будет содержать элементы результата (элементы LI). (По умолчанию: «ac_results»).
loadingClass – класс для элемента ввода, в то время, когда происходит обработка данных на сервере. (По умолчанию: «ac_loading»).
lineSeparator – символ, который разделяет строки в данных, возвращаемых сервером. (По умолчанию: «\n»).
cellSeparator – символ, который разделяет «ячейки» в строках данных, возвращаемых сервером. (По умолчанию: «|»).
minChars – минимальное число символов, которое пользователь должен напечатать перед тем, как будет активизирван запрос. (По умолчанию: 1).
delay – задержка в миллисекундах. Если в течение этого времени пользователь не нажимал клавиши, активизируется запрос. Если используется локальный запрос (к данным, находящимся непосредственно в файле), задержку можно сильно уменьшить. Например до 40ms. (По умолчанию: 400).
cacheLength – число ответов от сервера, сохраняемых в кэше. Если установлено в 1 – кэширование данных отключено. Никогда не устанавливайте меньше единицы. (По умолчанию: 1).
matchSubset – использовать ли кэш для уточнения запросов. Использование этой опции может сильно снизить нагрузку на сервер и увеличить производительность. Не забудьте при этом еще и установить для cacheLength значение побольше. Например 10. (По умолчанию: 1).
matchCase – использовать ли сравнение чувствительное к регистру символов (только если Вы используете кэширование). (По умолчанию: 0).
maxItemsToShow – ограничивает число результатов, которые будут показаны в выпадающем списке. Если набор данных содержит сотни элементов, может быть неудобно показывать весь список пользователю. Рекомендованное значение 10. (По умолчанию: -1).
extraParams – дополнительные параметры, которые могут быть переданы на сервер. Если Вы напишете {page:4}, то строка запроса к обработчику на сервере будет сформирована следующим образом: my_handler.php?q=foo&page=4 (По умолчанию: {}).
width – устанавливает ширину выпадающего списка. По умолчанию ширина выпадающего списка определена шириной элемента ввода. Однако, если ширина элемента ввода небольшая, а строки выпадающего списка содержат большое количество символов – эта опция вполне может пригодиться. (По умолчанию: 0).
selectFirst – если установить в true, то по нажатию клавиши Tab или Enter будет выбрано то значение, которое в данный момент установлено в элементе ввода. Если же имеется выбранный вручную («подсвеченный») результат из выпадающего списка, то будет выбран именно он. (По умолчанию: false).
selectOnly – если установить в true и в выпадающем списке только одно значение, оно будет выбрано по нажатию клавиши Tab или Enter, даже если этот пункт не был выбран пользователем с помощью клавиатуры или указателя мыши. Заметьте, что эта опция отменяет действие опции selectFirst. (По умолчанию: false).
formatItem – JavaScript функция, которая поможет обеспечить дополнительную разметку элементов выпадающего списка. Функция будет вызываться для каждого элемента LI. Возвращаемые от сервера данные могут быть отображены в элементах LI выпадающего списка (см. второй пример). Принимает три параметра: строка результата, позиция строки в списке результатов, общее число элементов в списке результатов. (По умолчанию: none).
onItemSelect – JavaScript функция, которая будет вызвана, когда элемент списка выбран. Принимает единственный параметр – выбранный элемент LI. Выбранный элемент будет иметь дополнительный атрибут «extra», значением которого будет являться массив всех ячеек строки, которая была получена в качестве ответа от сервера. (По умолчанию: none).
Последние две опции весьма важны, если Вы хотите сделать действительно удобный и полезный элемент интерфейса, поэтому приведу примеры.
function liFormat (row, i, num) {
var result = row[0] + "<em class="qnt">" +
row[1] + " тыс.чел.</em>";
return result;
}
В опции formatItem мы определили имя вызываемой функции – liFormat, а сама функция просто формирует строку, которая будет вставлена в соответствующий элемент LI. Строка содержит название поселка и элемент em, в который выводится количество проживающих там, в тысячах человек. Элемент em имеет класс qnt, с помощью которого, используя CSS, мы сдвигаем этот элемент вправо, немного уменьшаем размер шрифта и делаем сам шрифт зеленого цвета.
Следующий пример для опции onItemSelect:
function selectItem(li) {
if( li == null ) var sValue = "Ничего не выбрано!";
if( !!li.extra ) var sValue = li.extra[2];
else var sValue = li.selectValue;
alert("Выбрана запись с ID: " + sValue);
}
Здесь видно как можно работать со значениями атрибута «extra» выбранного элемента LI. В примере мы выводим в alert значение идентификатора для записи из нашей тестовой базы.
Нам осталось только разобрать те действия, которые будут выполняться на стороне сервера. Как Вы наверное помните, мы выбрали для этого PHP. Вспомним также, что на сервер передается GET-запрос с параметром q, содержащим уже введенные пользователем символы. Сам код Вы сможете посмотреть, скачав файл примера.
Весь код мы будем выполнять только в случае существования XMLHttpRequest, только если передан GET-запрос с параметром q. Для примера используется текстовый файл, в котором содержится база данных. Вот фрагмент этого файла:
1:Пашковский:Краснодарский край:43,0 2:Горячеводский:Ставропольский край:34,4 3:Калинино:Краснодарский край:34,1 4:Приволжский:Саратовская область:32,0 . . . . . . . . . . . . . . . . . . . 268:Залари:Иркутская область:10,0 269:Октябрьский:Пермский край:10,0 270:Ишеевка:Ульяновская область:10,0 271:Жешарт:Республика Коми:10,0 272:Прохоровка:Белгородская область:10,0
Мы читаем этот файл в массив, а затем в цикле перебираем все строки, в свою очередь разбивая каждую из них в массив, к элементу под номером один (название поселка) которого обращаемся для поиска соответствия с переданным GET-запросом. Если соответствие будет найдена выводим информацию, правда в несколько ином порядке, чем она хранилась в файле.
Такой подход выбран во-первых, потому что это пример, который должен быть очень просто воспроизведен на любом другом сайте, и во-вторых, чтобы при очень небольшом объеме данных дать почувствовать тот момент, когда запрос выполняется.
Вот собственно и все, обращу разве Ваше внимание на то, что для работы со строками использую мультибайтовые строковые функции.
Отзывов (99) на «jQuery Autocomplete: автозаполнение»
+1
Будем пробовать!
какраз искал такой плагин – а то что находил, странно как то работали.
Каково происхождения плагин кстати? Ваш или чейто?
Нет, не мой. На самом сайте jQuery плагинов масса, на любой вкус и случай. Правда не все одинаково хороши. Автоподсказок я штук пять перепробовал – выбрал эту для себя. Ну и счел нужным поделиться с остальными, предварительно составив более-менее внятное описание на родном языке. Поскольку зачем кто-то будет изобретать велосипед, если он уже есть?
а может быть посоветуете «хороший» плагин для загрузки файлов AJAX? пробовал несколько – что то не срастаеться не с одним
…и кстати, а не встречали плагины визуального редактора на jQuery? или хотя бы сам принцип как они устроенны? т.е. суть понимаю – текстареа подменяеться на див-полотно, хтмл код преобразуеться согласно форматированию… но вот с реализацией туговато… может что посоветуете? а если есть опыт такого рода – и напишете новую статью, будет вообще СУПЕР
за ранее благодарен, начинающий падаванJQuery =)
Да и вот еще, а вопрос безопасности не затроните в новых статьях?
что учитывать при написании скриптов доступных юзерам, как строить защиту и предостеречься от атак….
Для загрузки файлов тоже пока ничего очень хорошего не встретил. Визуальные редакторы для jQuery есть, попробую выкроить время и написать об этом.
Вопросы безопасности – это тема даже не одной какой-то статьи. В статье можно пожалуй только краткий обзор основных методов дать. А сама тема по моему просто безгранична. Да и информации по ней вроде как достаточно, и на русском языке в том числе. Так что, если только в составе какого либо примера…
про безопасность JS и php действительно есть много материалов… только вот JS мало знакомы многие, тем более при работе с jQuery нужны только азы.
Про безопасность имелось ввиду относительно jQuery поделок.
пока не особо понимаю как «безопастнее» а как нет писать на jQuery, потому принимаю все необходимые меры на стороне сервера, фильтруем,адслэшим и т.д.
Любые проверки на стороне клиента, которые реализуются с помощью JavaScript (jQuery – просто частный случай) – это скорее проверки для удобства пользователя, заполняющего форму и не более. Ни в коем случае нельзя полагаться на такие проверки. Все данные, которые идут от клиента к серверу, должны обязательно, самым серьезным образом проверяться на сервере. Так что Вы все верно делаете.
А вот как бы всё тоже самое но ещё на поиске гугла прикрутить? Ну тоесть у меня на сайте нету поиска, можно поставить гугловский поиск просто по моему сайту, и вот как бы прикрутить вот это автозаполнение?!
Ну для этого Вам надо иметь возможность обращаться к какому-то сервису, который предоставлял бы выборку по введенным данным. Т.е. использовать какой-либо API Google. Вероятно Вам пригодится API данных Поиска кода Google.
Статья и пример просто супер! Очень рад что наткнулся на этот сайт! До этого мучался именно с этой темой… была проблема с кирилицей. Спасибо
У меня вопрос, а как сделать чтоб в появившемся списке автозаполнения была полоса прокрутки?
Полосу прокрутки там не сделать. Это не выпадающий список – это обычный ненумерованный список, который с помощью CSS выглядит подобно выпадающему списку. Можно разве что дать большее количество элементов в этом списке, но это как правило, становится не очень удобно для пользователя…
Спасибо. Ясно, жалко что нельзя (
Существует какой либо способом передать
значение переменной через extraParams , насколько я понял там только константы можно передать?
Во всяком случае конструкция вида
extraParams: {s: $(«#street_id»).val()}
не работает
Андрей, Вы на 100% уверены, что у Вас именно элемент #street_id содержит значение? Т.е. где-то раньше был использован метод val(val), чтобы присвоить ему соответствующее значение? Или же все-таки значение идентификатора содержится в атрибутах этого элемента, например в id? Тогда extraParams: {s: $(”#street_id”).attr(«id»)}
Конструкция должна работать. Попробуйте для начала пойти по шагам и тупо присвоить какой-либо переменной нужное значение:
var strid = $(”#street_id”).val();
а затем уже
extraParams: {s: strid}
Ну и конечно полезно при работе пользоваться FireBag’ом например. Очень помогает…
Если позволите, приведу участки кода в более развернутом виде
$(document).ready(function(){
// — Автозаполнение улицы —
$(«#street»).autocomplete(«street.php», {
autoFill:true,
selectFirst:true,
delay:50,
minChars:3,
matchSubset:1,
autoFill:true,
matchContains:1,
cacheLength:10,
selectFirst:true,
maxItemsToShow:10,
onItemSelect:selectStreet
});
// — END Автозаполнение улицы —
function selectStreet(li) {
if( li == null ) var sValue = «Ничего не выбрано!»;
if( !!li.extra ) var sValue = li.extra[0];
else var sValue = li.selectValue;
$(«#street_id»).val(sValue);
}
// — Автозаполнение дома —
$(«#house»).autocomplete(«street.php», {
autoFill:true,
selectFirst:true,
delay:50,
minChars:3,
matchSubset:1,
autoFill:true,
matchContains:1,
cacheLength:10,
selectFirst:true,
maxItemsToShow:10,
scroll:true,
onItemSelect:selectHouse
});
// — END Автозаполнение дома —
function selectHouse(li) {
if( li == null ) var sValue = «Ничего не выбрано!»;
if( !!li.extra ) var sValue = li.extra[0];
else var sValue = li.selectValue;
$(«#house_id»).val(sValue);
}
});
Соотвественно имеем
Улица:
Строение:
В автозаполнеии дома, разумеется есть:
extraParams: {s: $(«#street_id»).val()},
Да, вижу, что есть. Ну, а просто тупым путем идти не пробовали? Вывести $(”#street_id”).val(sValue); куда-нибудь в alert, чтобы ее ‘живьем’ увидеть? Я почему так выспрашиваю – extraParams должна сработать…
в selectStreet(li) вставлял алертом, все нормально присваивается значение.
А вот как вставить проверку перед вызовом autocomplete()?
Посмотрев в код jquery.autocomplete.js, увидим что:
function makeUrl(q) {
var url = options.url + «?q=» + encodeURI(q);
for (var i in options.extraParams) {
url += «&» + i + «=» + encodeURI(options.extraParams[i]);
}
return url;
};
Смущает, что нет обратки передаваемого значения
Ничего умного в голову не лезет. Попробуйте покопать оригинальную документацию:
http://www.dyve.net/jquery/?autocomplete
http://www.pengoworks.com/workshop/jquery/autocomplete.htm
Попробовал сделать такой вариант:
$(document).ready(function(){
var streetid = 0;
// — Автозаполнение улицы —
…
onItemSelect:selectStreet
});
// — END Автозаполнение улицы —
function selectStreet(li) {
….
streetid = sValue;
}
// — Автозаполнение Дома —
$(«#house»).autocomplete(«home.php», {
….
extraParams: { s: streetid },
….
});
// — END Автозаполнение Дома —
И вот что странно, я вижу, что переменная streetid меняется при выборе улицы, но в extraParams попадает значение по умолчанию (0). Из чего можно сделать вывод, что autocomplete() парсится сразу после загрузки документа и 1 раз, после чего уже работает со значением переменной на момент парсинга.
В документации нашел метод, но смысл его оказался скрыт от меня:
setExtraParams(obj)
This sets the extra parameters of the autocompleter to obj (which should be a JavaScript object, see above).
Немного поразмыслив вставил
«// — Автозаполнение Дома —»
в selectStreet(li)
Возник последний (надеюсь) вопрос:
как вернуть фокус на элемент ввода после выбора значения. Т.к. фокус становится свободным и при нажатии на [Tab] переходит на первый элемент формы
$(«selector»).focus();
Я так понял что данный плагин не поддерживает никакой валидации, то есть пользователь в принципе может ввести все что угодно. А не подскажете, как можно прикрутить валидатор на поле ввода текста, чтобы при отсутствии результатов можно было бы выполнить какое-либо действие (alert например или смену цвета фона input’а и т.п.), и можно ли это сделать в принципе?
Заранее спасибо.
Да, конечно. Строго говоря лучше вообще не доверять проверке данных, произведенных на стороне клиента. Это однозначно должен делать серверный сценарий. Такая валидация уместна только с целью предотвратить ввод некорректных данных в том смысле, что бы подсказать пользователю как надо что-то писать…
Вы посмотрите эти статьи:
jQuery Form – делаем ajax-форму
jQuery Validation – проверка данных в ajax форме
Это как раз по Вашему вопросу…
Лучше перестраховаться 2 раза: проверить и на клиенте, и на сервере.
To: Snowcore
Если Вам нужна ссылка на Ваш блог, то хотя бы пишите что-то по делу. Не стоит разводить флуд, ок? Поэтому остальные Ваши «комментарии» я удалил. Этот оставил, как хотя бы чуть-чуть относящийся к делу…
при проверке на соответствие ключу для второго и последующих символов попадаем сюда:
//== jquery.autocomplete.js ==//
function matchSubset(s, sub) {
if (!options.matchCase) s = s.toLowerCase();
var i = s.indexOf(sub);
if (i == -1) return false;
return i == 0 || options.matchContains;
};
так вот в такой реализации при ключе «Те» вернутся:
- слова, начинающиеся на «Те»
- слова начинающиеся на «Т» и содержащие «те» в любом месте фразы
т.е. идет поиск по любому вхождению в строку. Не уверен… может так и планировалось
Поэтому просто написал, может возникнут у кого-нибудь вопросы, какие возникли у меня при первом знакомстве с этим плагином – я думал будет искаться совпадение только в начале фразы…
–
Огромное спасибо Геннадию! Статьи Вещь!
Здравствуйте!
Подскажите, пожалуйста, как осуществить задуманное, используя вариант 2, приведенный выше. Суть такова, что есть форма с несколькими полями ввода и в каждом должен быть свой выпадающий список. Чтобы не повторять код для каждого поля, можно ли, например, по событию onFocus, передавать id поля ввода в js- функцию и каким образом?
Заранее, спасибо.
Можно конечно просто в jQuery-селекторе вместо $(«#example2″) написать $(«#input1″, «#input2″, … «#inputN»). Таким образом Вы сделаете подсказку для всех input’ов, которые будут отобраны. Но Вам-то необходимо для каждого input’а свой список. Значит Вам придется передавать на сервер какой-нибудь дополнительный параметр (см. extraParams) чтобы сформировать этот список. Т.е. этот параметр для каждого поля ввода должен быть свой….
Добавьте в опции extraParams, а его значение можно попробовать менять динамически, в зависимости от выбранного поля…
Спасибо Геннадий за ответ. А не могли бы Вы уточнить, как изменить динамически этот параметр?
См. комментарий №18. Что-то вроде этого…
Почему же нельзя?… Можно. Можно диву сказать – показывать полосу прокрутки, а не прятать ее, например вот так:
в стиле .ac_results {
вместо
overflow: hidden;
прописать
height: 200px;
overflow:auto;
overflow-x: hidden;
Только в ИЕ что то плющит его… крутить список не получается.
Gennady 28.04.2008 в 9:26 13
Полосу прокрутки там не сделать. Это не выпадающий список – это обычный ненумерованный список, который с помощью CSS выглядит подобно выпадающему списку. Можно разве что дать большее количество элементов в этом списке, но это как правило, становится не очень удобно для пользователя…
Gennady
04.08.2008 в 9:31 33
См. комментарий №18. Что-то вроде этого…
===============================
Странно, но я пока не добился передачи на сервер
(в ExtraParams) динамически изменяемой переменной.
То есть переменную можно передать, но только ту, которая была проинициализирована в момент загрузки страницы. То есть, extraParams: {s: $(”#street_id”).val()} передастся лишь в том случае, если значение на момент загрузки страницы имелось у данного элемента.
В моём случае мне надо передавать либо id элемента, либо имя элемента, который сейчас находится в фокусе. Пробовал изменять функцией по фокусу переменную(заранее объявленную в момент инициализации) она передается в ExtraParams, но лишь с начальным значением.
Поправьте, если что не так.
Тут однозначно нужно мудрить как-то еще. Ну например (не гарантирую, что будет работать – просто в голову пришло): сам код
// — Автозаполнение2 —
$(«#example2″).autocomplete(«autocomplete.php», {
delay:10,
minChars:2,
matchSubset:1,
autoFill:true,
matchContains:1,
cacheLength:10,
selectFirst:true,
formatItem:liFormat,
maxItemsToShow:10,
onItemSelect:selectItem
});
// — Автозаполнение2 —
оформить в функцию, которая будет вызываться, когда какое-либо поле ввода получает фокус. Функция должна принимать аргумент – значение для опции ExtraParams.
Попробуйте такой вариант…
Проблема в том, что предложенный вариант также не меняет то, что уже проинициализировано в момент загрузки.
Боюсь, что нужно как-то перегружать обработчик при передаче фокуса элементу точно также, как в момент загрузки страницы
$(document).ready(function(){});
Вопрос как:)
Вот пример, посмотрите. Откройте исходный код. Я старался все очень-очень подробно откомментировать. Да, и начинайте читать снизу – по логике там все начинается. Я правда не делал весь пример, с серверной частью, но по крайней мере Вы увидите как меняется значение ExtraParams.
Спасибо, кое-что получилось. Разве-что в примере не работает передача extraparams.
Надо так: extraparams:{some_var:id} – так передается.
Одно но – в браузере Opera (9.12) не работает.
Видно, как при вбивании в поле первых двух символов,
идет запрос на сервер, после чего всё «глохнет». Нет ни выпадающего списка, ни дальнейших реакций на события при вводе.
Upd.: в Опере работает как-то так.
Мы имеем поле ввода X. Чтобы выпал выпадающий список, элемент X должен получить фокус, затем потерять, затем снова получить.
Я поправил пример. Писал по памяти, а она подвела. Доделал в него обработку на сервере. Параметры передаются – все в норме…
Да и похоже (посмотрел опции на сайте jQuery), там еще проще можно сделать, чем в примере – только надо ковыряться.
Что касается Oper’ы (и не только ее) – с фокусом повнимательнее. А может в ней еще и стилевое оформление выпадающего списка играет роль…
Думаю, что такой алгоритм будет работать и в Опере и Эксплорере при событии Focus, а не Click.
1. При загрузке страницы узнаем элемент, находящийся в данный момент в фокусе. Искусственно уходим и снова возвращаемся.
2. При получении новым элементом фокуса также иммитируем уход, а затем приход в него.
Как оказалось, искусственная передача фокуса не оправдала надежд. Может надо эмулировать нажатие клавишb tab…
У меня форма находится в диалоговом окне и список с подсказками выводится ниже диалогового окна. Как поднять список на самый верх?
Я так понимаю Вы хотите использовать jquery.dialog.js и jquery.autocomplete.js вместе? Слишком много всего замешано и вот так просто сказать, почему не получается довольно сложно. Скорее всего надо смотреть в сторону стилевого оформления, посмотреть как в автокомплите оформляется выпадающий список и если там position:absolute; то первое, что надо проверить – его родительский контейнер, чтобы убедиться, что он position:relative;
Почему-то мне кажется, что собака где-то там должна быть зарыта…
Никак не могу добиться чтобы список запрашивался многократно из php. изначально список запрашивается по двум введенным буквам, далее если продолжать вводить символы выборка происходит из загруженного первый раз.
Ну да. По двум символам вернется выборка куда будут включены все слова, начинающиеся с этих двух символов. При вводе третьего символа выборка сократится, и в ней останутся все те слова, которые начинаются на эти три буквы (ха!) и так далее…
В чем проблема? Может быть Вас путает то, что Вы можете в выпадающем списке ограничивать количество отображаемых пунктов – так это только отображение….
Проблема в том что мне нужно чтобы при вводе каждой новой буквы у меня перезапрашивались данные из php файла с новым параметром q, а сейчас запрос происходит только один раз, а дальше при вводе новых букв выборка внутри поля ввода идет лишь из того что пришло с php в первый раз.
вот пример кода:
$(document).ready(function(){
// — Автозаполнение2 —
$(«input#fastfind»).autocomplete(«users/getusers.php»,
{
delay:10,
minChars:2,
matchSubset:1,
autoFill:true,
matchContains:1,
cacheLength:10,
selectFirst:true,
maxItemsToShow:10,
});
// — Автозаполнение2 —
});
Файл getusers.php:
$q=$_GET['q'];
$query=@mysql_query(«SELECT NICK FROM user WHERE NICK LIKE ‘%$q%’ LIMIT 20″);
while ($row=@mysql_fetch_array($query))
{
echo $row['NICK'].»\r\n»;
};
В коде – cacheLength:10 – попробуйте изменить на 1. У Вас кэшируются ответы сервера, а при 1 кэширование будет отключено.
нет, к сожалению не помогает, вообще что-то странное творится, никак не пойму, только что получил нужный результат, обновляю страницу – пробую снова – не работает
Вообще начинает нормально работать только когда убираешь LIMIT 20 из SQL-запроса, оно и понятно, но тогда передается слишком большой массив данных. Придется наверное лезть в исходник плагина…
Все бы хорошо, только с кириллицей оно дружит очень выборочно. Как бы его заставить запрос через POST посылать, а не GET-ом? :/
А что, через POST он начнет с кириллицей дружить? В общем-то пора бы уже и на utf-8 переходить, хотя бы в новых проектах. И даже если это по каким-то причинам невозможно, с кириллицей можно легко дружить, если использовать при поиске, сравнении и т.д. мультибайтовые строковые функции например…
Да все уже давно UTF-8. Но если браузер перед отсылкой начинает корежить GET исходя из своих системных предпочтений, а не выставленной кодовой страницы, то по крайней мере POST остается аутентичным.
Впрочем, речь не об этом. Не знаете ответа? — ладно, спасибо и на том.
Sol, извините конечно, но по-моему это бред…. Я про: «…браузер перед отсылкой начинает корежить GET…».
Ответ я знаю – плагин не поддерживает передачу методом POST, так как в самом коде плагина используется именно GET. Откойте исходник, перепишите для себя под POST…
Подскажите пожайлуста, я хочу в дополнительных параметрах передать id элемента.
Делаю:
$(«input.define»).autocomplete(«autocomplete.php», {
delay:1,
minChars:2,
matchSubset:1,
autoFill:false,
matchContains:1,
cacheLength:1,
selectFirst:true,
formatItem:liFormat,
maxItemsToShow:10,
onItemSelect:selectItem,
extraParams: { id: $(this).attr(‘id’) }
});
Но не получаться, пишет: undefinite
Пробовал еще так:
$(«input.define»).keyup(function () {
var id = $(this).attr(‘id’);
$(this).autocomplete(«autocomplete.php», {
delay:1,
minChars:2,
matchSubset:1,
autoFill:false,
matchContains:1,
cacheLength:1,
selectFirst:true,
formatItem:liFormat,
maxItemsToShow:10,
onItemSelect:selectItem,
extraParams: {type: id }
});
});
Id передается, но срабатывает такая конструкция через секунд 20 после разных манипуляций с input’ом =)
Sol, GET передает парамметры в UTF-8, если вы используете CP-1251 в php файле будут эроглифы, лечиться просто:
$value = iconv(‘utf-8′,’windows-1251′,$_GET['q']);
Посмотрите еще вот этот пример:
http://www.linkexchanger.su/example_misc/ac.html
ситуация в общем похожа – думаю это Вам поможет…
Спасибо большое =)
Еще вопросик, тут уже спрашивали про focus после выбора. Надо вернуть фокус в этот же инпут.
вот не пойму куда вставить $(”selector”).focus();?
По логике в фун-ию selectItem но как там узнать id?
И еще =)
Сделал:
$(«input.define»).onclick(function () {
var id = $(this).attr(«id»);
var name = $(this).attr(«name»);
ac(id, name);
});
В этом случае не срабатывает если в инпут перешли Табом
$(«input.define»).focus(function () {
var id = $(this).attr(«id»);
var name = $(this).attr(«name»);
ac(id, name);
});
А в этом если кликнули в поле =)
Если стоят оба по порядку то срабатывает только первый =( Что делать?
Во втором варианте – неправда Ваша. При получении фокуса полем неважно через клик или через Tab поле его получает.
Про возврат фокуса: если Вы в доп. параметрах что-то передаете на сервер, пихнуть туда еще и id например, и потом его вернуть с сервера. А в ответе смотрите extra.
Gennady, спасибо вам огромной =)
Очень мне помогли =)
Со временем появился ещё вопрос =)
В результате я возвращаю 3 поля (id,value1,value2)
в селекте выводить поле value1. Я хочу что бы при клике по этому полю в инпут вставлялось поле value2, а не value1. Возможно ли такое?
Да можно-то многое…. Только Вы попробуйте формулировать вопросы четче. Либо пример кода давайте. Потому как мне сложно догадаться, что Вы имеете ввиду…
Тут скриншот
http://mediapix.ru/pic.php?id=b0f857f04d343f253f7c07b0d8584cc0
Как видите в всплывающем списке указано:
1. тип (ООО)
2. название
3. Краткое пояснение
Если сделать выбор то в input попадет весь этот текст (+ html тэги).
Autocomplete возвращает результат в виде:
id|ОООНазвание_компанииИнформация|Название_компании
Вот мне бы хотелось, что бы при выборе в input попадало только название компании.
Причем, делать это по средствам функции liFormat это не желательно, так как формат записи в всплывающем списке бывает разный и определяется на стороне сервера (в php файле).
Надеюсь понятно объяснил.
Теперь понятнее. Вы просто подробнее пример №2 посмотрите – в списке выводится не только название города, но и кол-во проживающих там жителей, а в input попадает только название. По-моему точно Ваш случай…
А, ну да, не с той стороны пошел =) Изменяюсь.
Спасибо за ответ =)
Вот все таки странно как то эта штука себя ведет, никак не разберусь до конца.
вот сделано вот так:
$(«input#region»).autocomplete(«engine/users/getregion.php»,
{
delay:40,
minChars:2,
matchSubset:0,
autoFill:false,
matchContains:1,
matchCase:0,
selectFirst:true,
formatItem:frmt1,
maxItemsToShow:10,
onItemSelect:selectItem
});
ввожу первые две буквы,
делается выборка из getregion.php
ввожу третью букву, а она выбирает
из ранее выбранного, причем только первых
10-и результатов, а getregion.php заново не запрашивает. А бывает раз – и запросит, изредка.
бред какой то
ejkot, это происходит потому что ты вводишь быстрее чем установленные 40 мс delay, т.е на первую букву запрос не срабатывает, срабатывает только тогда когда ты привысил задержку в 40 мс. Мне сейчас тоже нужно сделать чтобы запрос посылался для каждой введенной буквы, попробую поправить исходник
Хорошая статья. Толково расписано как все это работает. А кто автор скрипта? Кстати вот я недавно совсем проводит сравнение autocomplete для jquery http://web-linux.ru/?p=267 . Составил обзор. Может кому пригодится.
2Олег:
Ввожу первые две буквы – как полагается – запрос – вывод данных. Ввожу третью – тишина. можно ждать хоть 40 мс, хоть полчаса. запрос не происходит
ejkot, понятно что запрос не происходит. В данном плагине запрос к серверу предполагается совершать только 1 раз. Чтобы дергать сервер на каждую введенную букву я подправил исходник плагина.
В 323 строке
var data = options.cacheLength ? loadFromCache(q) : null;
заменил на
var data = null;
Неоптимально канечно дергать сервер на каждую букву наверное, но результат меня устраивает.
2Олег: Во, спасибо теперь то что надо, а насчет оптимальности – так теперь можно зато уточнять сами запросы в серверной части и ограничивать выдачу типа SELECT … FROM … WHERE … LIMIT 20
–
еще одна странная особенность, не могу понять где ошибся. странная вещь происходит с первой буквой вводимой.
Например в списке Карелия, Архангельская, и т.п.
Ввожу например Ар нет в выборку не попадает Архангельская область, а если ввожу рх – то попадает…
А полный текст запроса можно?
function ddd (row, i, num) {
var result=row[0];
return result;
};
function selectItem(li) {
if( li == null ) return(false);
if( !!li.extra ) var sValue = li.extra[2];
else var sValue = li.selectValue;
}
$(document).ready(function(){
// — Автозаполнение2 —
$(«input#region»).autocomplete(«engine/users/getregion.php»,
{
delay:200,
minChars:2,
matchSubset:1,
autoFill:false,
matchContains:1,
cacheLength:1,
matchCase:0,
selectFirst:false,
formatItem:ddd,
maxItemsToShow:10,
onItemSelect:selectItem
});
// — Автозаполнение2 —
});
Серверная часть:
$q=$_GET['q'];
$query=db_get_array(«SELECT name,socr,regid FROM regions WHERE name LIKE ‘%$q%’ ORDER BY name»);
while ($row=@mysql_fetch_array($query))
{
echo $row['name'].»|».$row['socr'].»|».$row['regid'].»\n»;
};
MySQL проводит case-insensive поиск. Вродебы все верно. Должен находить…
Может быть в default-character-set неверная кодировка у вас?
Да не должно бы, впринципе у меня при соединении с бд кодировки явно передаются:
$db_link=mysql_connect(DBHostName,DBUserName,DBPassword)
or die («Невозможно установить соединение с БД: «.mysql_error());
mysql_select_db(DBName,$db_link)
or die («Не удалось найти базу данных. «);
mysql_query(‘SET CHARACTER SET utf8′,$db_link);
mysql_query(‘SET NAMES utf8′,$db_link);
Да и вторую букву понимает уже. какой то заморок с первой. такое впечатление что в полученном с сервера списке сам плагин ищет начиная со второй буквы каждой строки…
может minChars:2 поменять на minChars:1 ?
А в fireBug если глянуть, то там на сервер запрос корректный уходит?
Вобщем разобрался, глупая ошибка с верхним-нижним регистром, чтобы заработало нужно изменить запрос на:
”SELECT name,socr,regid FROM regions WHERE LCASE(name) LIKE ‘%$q%’ ORDER BY name”
всем спасибо
Решение проблемы с extraParams которую описывал выше Андрей -
$(«#states»).autocomplete(url, {
extraParams: {
country: function() { return $(«#country»).val(); }
}
});
Здравствуйте. Подскажите пожалуйста что делать? Отправляю запрос на сервер, а потом ту переменную которую получил сервер передаю обратно в яваскрипт и когда автокомплит выводит ее то кирилические символы заменяются на �. Подскажите как обойти эту проблему, потому что мне нужно искать в базе русские названия, а оно соответственно ничего не ищет. Все файлы в кодировке utf-8 а файл autocomplete.js в анси, и перекодировать я его не могу, хотя думаю что проблема не в этом.
Если ВСЕ файлы имеют кодировку utf-8, остается только проверить, в какой кодировке отдает данные Ваша база. А autocomplete.js тут действительно не при чем, хотя перевести его в utf-8 тоже по-моему труда не составляет – сохранить как, и при сохранении указать нужную кодировку. Не знаю, чем Вы пользуетесь для работы – я использую ZendStudio – никаких проблем с этим нет.
Народ как можно очистить уже хранимые в массиве данные?
На примере
1 поле город Москва
2 поле Улица Москвы
при изменение города допустим на Питер во втором поле должны появиться улицы Питера, а на практике получается Москва+Питер!
Привет, за статью спасибо. У тебя во 2 поле не Москва+Питер, а все улицы, которые есть в базе. У меня такая же проблема- не могу передать параметр с 1 поля в запрос, который выполняется во 2 поле.
Как я понял инициализация поля происходит при загрузке страницы, т.е. на изменение значения в 1 поле нельзя передать параметр во 2, т.к. страница уже загружена.
Это кто решил эту проблему, напишите =)
Заранее благодарен.
Как написано решение выше не работает.
Как прокрутку сделать?
Использовал ваш пример, то что надо, спасибо. Скажите, а можно как-нибудь получить список что сервер вернул Autocomplete. Необходимо сделать валидацию на стороне клиента, поэтому хочу стравнить то что введено в поле с тем что вернул сервер.
Вопрос немного непонятен – Вы же получаете ответ сервера в row (см. пример), так пожалуйста, оперируйте с этими данными…
Добрый день.
Сделал динамическое добавление полей ввода с помощью appendChild. В каждом таком поле хотелось бы использовать autocomplete.
$(«#example2″).autocomplete(«../../properties/ajax/index.php», {options});
Добавить таких окон можно много. А вот как сделать чтоб вместо «#example2″ можно было подставлять значения? Хотя мне кажется это уже не асинхронно будет. Что посоветуете сделать?
Разве #example2 догма? Почему не сделать .example2? Т.е. в объект jQuery выбрать элементы по имени их класса. Или вообще например указать в селекторе тип элемента? Так что путей множество. А вот асинхронность здесь вообще не при чем.
Я бы посоветовал внимательнее познакомиться со статьями, которые рассказывают о селекторах jQuery – это одна из основ. Поняв, прочувствовав ее, сможете совершенно спокойно оперировать теми элементами, которые Вам нужны.
Gennady, благодарю за ответ:)
Gennady, я думал что неправильно понял раздел
http://www.linkexchanger.su/2008/62.html.
Однако я пробовал делать и через $(‘input.CssCalssForInput’).autocomplete и другие варианты. Но всегда работает только первый инпут. Остальные молчат на запросы:(
Я попытался отладить, но даже на функцию .keydown(function(e)) в самой библиотеке второй инпут уже не реагирует.
Мы же не можем autocomplete запихивать в функцию, которая будет вызываться при обращении к полю?
Привет, почему не вылазит при вводе автозаполнение БРАУЗЕРА? Подскажите как это сделано, мне тоже нужно отключить.
Спасибо =)
Спасибо за полезную статью.
Скажите пожалуйста, а можно сделть так, чтобы пользователь мог ввести (выбрать) значение только из выданного списка.
Спасибо за полезную статью, я попробовал применить это на практике, но возникла проблема с автозавершением русских значений.
Используемая кодировка на сайте: Windows-1251
Файл developers.php:
$value) {
if (mb_strpos(mb_strtolower(rawurldecode($key),»Windows-1251″), $q,0,»Windows-1251″) !== false) {
echo «$key|$value\n»;
}
}
}
?>
Файл info.html
$().ready(function() {
$(«#developers»).autocomplete(«developers.php», {
delay:10,
minChars:2,
matchSubset:1,
autoFill:true,
matchContains:1,
cacheLength:10,
selectFirst:true,
maxItemsToShow:10
});
});
Разработчик:
При «ручном» запросе типа «developers.php?q=сату» скрипт выводит значение «Сатурн» (и это правильно).
А вот jquery.autocomplete.js это значение не выводит, и я не могу понять почему, хотя с англоязычными названиями всё работает на ура.
Помогите разобраться в чем может быть дело.
Да сделайте обработчик на сервере в UTF-8 отдав соответствующий заголовок, дальше используйте мультибайтовые строковые (собственно у Вас так и есть), а вернете результат потом в нужной кодировке.
С 1251 геморрой – обычное дело.
Обсуждение статьи можно продолжить на форуме jQuery.