Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 18.03.2008, 23:22
zem zem вне форума
Новичок на форуме
Отправить личное сообщение для zem Посмотреть профиль Найти все сообщения от zem
 
Регистрация: 18.03.2008
Сообщений: 2

input с автоДополнением
Здравствуйте, Java script изучаю относительно недавно и столкнулся с такой проблемой:

на сервере есть база данных (MySQL), в ней содержится список фамилий (их может быть достаточно много, больше 1000). Требуется в форме во время ввода в текстовое поле (input) под ним отобразить список фамилий из этой БД, по мере ввода в поле, которые совпадают по начальным буквам. Т.е. примерно как это реализовано в google в строке поиска. Это необходимо для того чтобы гарантировать правильность написания фамилий в реальном времени.

Вопрос в основном в том, как грамотней поступить. Насколько я понимаю прямого доступа к MySQL JS получить не пожет чтобы делать соответствующие запросы БД по мере ввода букв. Значит во время загрузки страницы PHP должен создать массив с фамилиями для JS, с которым я дальше буду работать. Однако данный подход неэффективен в плане быстродействия если массив достаточно большой.

Кто сталкивался с подобными вещами подскажите пожалуйста как лучше поступить...
Ответить с цитированием
  #2 (permalink)  
Старый 19.03.2008, 01:24
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

zem,

Сообщение от zem
Значит во время загрузки страницы PHP должен создать массив с фамилиями для JS, с которым я дальше буду работать. Однако данный подход неэффективен в плане быстродействия если массив достаточно большой.
правильный ход мысли =) а значит дальше будет все просто:

- погуглите по запросам Ajax / XmlHtpRequest (можно до кучи посмотреть мою старую-старую статью - там как раз все разжеванно для начинающих. На этом сайте тоже должны быть статьи)

- далее, как изучите аякс:

-- создайте скрыйтый div с абсолютным позиционированием

-- по событию onkeyup (или onkeypress) input'a посылайте аякс запрос на сервер, чтобы получить данные из базы; параметром передавайте значение input'a

-- полученный результат положите в Ваш div и покажите его. Также надо будет пересчитать координаты дива (изменить свойства стиля left и top) согласно координатам input'a (как получить координаты - тоже посмотрите, куча тем), чтобы он отображался под input'ом, создавая подобие выпадающего списка

-- на событие onblur input'a можно повесить скрытие [и очистку] div'a

Последний раз редактировалось Dmitry A. Soshnikov, 19.03.2008 в 01:52.
Ответить с цитированием
  #3 (permalink)  
Старый 19.03.2008, 02:09
Отправить личное сообщение для Андрей Параничев Посмотреть профиль Найти все сообщения от Андрей Параничев
 
Регистрация: 21.02.2008
Сообщений: 1,250

Вот, набросал в свободные 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.

Последний раз редактировалось Андрей Параничев, 19.03.2008 в 02:31.
Ответить с цитированием
  #4 (permalink)  
Старый 19.03.2008, 09:34
zem zem вне форума
Новичок на форуме
Отправить личное сообщение для zem Посмотреть профиль Найти все сообщения от zem
 
Регистрация: 18.03.2008
Сообщений: 2

Огромное спасибо ds [.code] и Андрей Параничев, не ожидал такой оперативности. Теперь знаю в каком направлении двигаться.
Ответить с цитированием
Ответ


Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Поместить значение в INPUT Владислав Events/DOM/Window 2 18.03.2009 23:57
в теге input изменение атрибута type gabber Internet Explorer 6 11.11.2008 13:01
Копирование из одного input в другой input bar-boss Общие вопросы Javascript 7 08.04.2008 19:10
Разным элементам input - разное форматирование. Как? eclipse (X)HTML/CSS 1 25.10.2007 13:55
Позиция курсора в input type="text" (ie) Кирпич Общие вопросы Javascript 2 21.10.2007 06:44