input с автоДополнением
Здравствуйте, Java script изучаю относительно недавно и столкнулся с такой проблемой:
на сервере есть база данных (MySQL), в ней содержится список фамилий (их может быть достаточно много, больше 1000). Требуется в форме во время ввода в текстовое поле (input) под ним отобразить список фамилий из этой БД, по мере ввода в поле, которые совпадают по начальным буквам. Т.е. примерно как это реализовано в google в строке поиска. Это необходимо для того чтобы гарантировать правильность написания фамилий в реальном времени. Вопрос в основном в том, как грамотней поступить. Насколько я понимаю прямого доступа к MySQL JS получить не пожет чтобы делать соответствующие запросы БД по мере ввода букв. Значит во время загрузки страницы PHP должен создать массив с фамилиями для JS, с которым я дальше буду работать. Однако данный подход неэффективен в плане быстродействия если массив достаточно большой. Кто сталкивался с подобными вещами подскажите пожалуйста как лучше поступить... |
zem,
Цитата:
- погуглите по запросам Ajax / XmlHtpRequest (можно до кучи посмотреть мою старую-старую статью - там как раз все разжеванно для начинающих. На этом сайте тоже должны быть статьи) - далее, как изучите аякс: -- создайте скрыйтый div с абсолютным позиционированием -- по событию onkeyup (или onkeypress) input'a посылайте аякс запрос на сервер, чтобы получить данные из базы; параметром передавайте значение input'a -- полученный результат положите в Ваш div и покажите его. Также надо будет пересчитать координаты дива (изменить свойства стиля left и top) согласно координатам input'a (как получить координаты - тоже посмотрите, куча тем), чтобы он отображался под input'ом, создавая подобие выпадающего списка -- на событие onblur input'a можно повесить скрытие [и очистку] div'a |
Вот, набросал в свободные 20 минут, может вам поможет.
Основной ход мысли такой: * Ловить на input событие onKeyUp * Посылать запрос на сервер с введённым текстом * Получить ответ и составить из него ссылки в "нужное место". Код (тут возможны неточности и не кросс-браузерные функции, писалось быстро, использовать только в качестве примера): <html> <head> <script> var lnbox = { // Ссылка на DOM элемент поля ввода lninput: null, // Ссылка на DOM элемент всплывающего div'а lnelement: null, // Массив полученных фамилий lastnames: new Array(), // Объект XmlHttpRequest, для передачи данных (ajax) httpreq: window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"), // Функция инициализации (выполняется по загрузке body) init: function() { // Устанавливаем ссылку на форму ввода this.lnelement = document.getElementById('lastnamebox'); // Устанавливаем ссылку на вслывающий div this.lninput = document.getElementById('lastnameinput'); // Устанавливаем обработчик событий нажатой (точнее отпущенной) // клавиши на форму ввода this.lninput.onkeyup = function(e) { lnbox.process(e); } // Устанавливаем обработчик ответа сервера this.httpreq.onreadystatechange = function() { if (lnbox.httpreq.readyState == 4) lnbox.updateBox(lnbox.httpreq.responseText); } }, // Функция запроса на сервер, параметр text - текст из поля ввода requestUpdate: function(text) { // Посылаем методом GET this.httpreq.open("GET", 'http://localhost/getlastnames.php?text='+ text +'&rand='+ Math.random()); this.httpreq.send(null); }, // Функция обновления div'а с фамилиями, вызывается при ответе // с сервера, т.е обработчик ответа updateBox: function(answer) { // Полученный ответ парсим в js массив (подробнее читай JSON) this.lastnames = eval(answer); // Если пустой ответ - выходим из функции if(this.lastnames.length <= 0) return false; // Показываем div this.lnelement.style.display = 'block'; // Отчищаем элемент от содержания this.lnelement.innerHTML = ""; // Проходим циклом по массиву фамилий for(var i = 0; i < this.lastnames.length; i++) { // Создаем элемент - тег <a> var lnk = document.createElement('a'); // Ставим заглушку в качестве ссылки lnk.href = "javascript://"; // Устанавливаем содержанием текущую фамилию lnk.innerHTML = this.lastnames[i]; // Ставим событие при щелчке на ссылку изменяется // текст в форме ввода lnk.onclick = function() { lnbox.lninput.value = this.innerHTML; // Прячем div lnbox.lnelement.innerHTML = ''; lnbox.lnelement.style.display = 'none'; } // Присоединяем элемент к div'у с ссылками this.lnelement.appendChild(lnk); } }, // Функция обработки события нажания (точнее отпускания) клавиши // на поле ввода process: function(event) { var key = window.event ? window.event.keyCode : (event.keyCode ? event.keyCode : (event.which ? event.which : null)) // Если введено меньше 2х символов не обрабатываем if(this.lninput.value.length > 2) this.requestUpdate(this.lninput.value); } } </script> <style> #lastnamebox { position: absolute; display: none; width: 180px; margin-top: 2px; border: 1px solid #; background: #F1F1F1; } #lastnamebox a:link, #lastnamebox a:visited { display: block; padding: 5px 0 5px 15px; color: #000000; font-size: 12px; } #lastnamebox a:hover { text-decoration: none; background: #FAFAFA; color: #666666; } </style> </head> <body onLoad="lnbox.init()"> <input id="lastnameinput" type="text" size="30" /> <div id="lastnamebox"></div> </body> </html> В этом коде конечно нужно провести оптимизацию: поставить http запрос на timeout (чтоб при печати слова не вызывалось при каждом символе), не делать запрос, если не изменилось содержание input'а (напр. при нажатии клавиш <Shitf>, <Alt>, ...), добавить переход по вариантам клавишей <Вниз> (ожидаемый функционал), убирать div на onBlur, и т.д и т.п... PHP скрипт getlastnames.php (в данном примере такой адрес) должен возвращать массив фамилий в формате JSON, т.е например такой формат файла (самый простой): <?php header("Content-type: text/javascript; charset=UTF-8"); echo '["Андрей", "Борис", "Ванга", "Гриша", "Юрий", "Яша"]'; Этот php скрипт будет получать $_GET['text'], и по нему выбирать нужные варианты фамилий и выдавать их в формате JSON. Можно конечно отправлять сразу html результат, но это не рационально при использовании ajax. |
Огромное спасибо ds [.code] и Андрей Параничев, не ожидал такой оперативности. Теперь знаю в каком направлении двигаться.
|
Часовой пояс GMT +3, время: 15:03. |