Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Автозавершение набора текста. (https://javascript.ru/forum/dom-window/11606-avtozavershenie-nabora-teksta.html)

lolka84 02.09.2010 18:50

Автозавершение набора текста.
 
Здравствуйте, подскажите с чего начать, нужно сделать следующее:
Есть список, к примеру, городов. Выводим его в <select>. Как сделать, что б в момент набора названия города в селекте скрипт искал совпадения по маске и автозавершал набор. Ну потипу начинаешь набирать "Новос.." скрипт подсказывает "Новосибирск".

exec 02.09.2010 19:05

<html><head><title>Test</title></head><body>
<input type="text" id="foo" />
<select id="city">
	<option>
		Москва
	</option>
	<option>
		Санкт-Петербург
	</option>
	<option>
		Новосибирск
	</option>
	<option>
		Красноярск
	</option>
	<option>
		Самара
	</option>
	<option>
		Нижний Новгород
	</option>
	<option>
		Урюпинск
	</option>
	<option>
		Хабаровск
	</option>
	<option>
		Владивосток
	</option>

</select>
<script type="text/javascript">
	document.getElementById( 'foo' ).onkeypress = function () {
		var sel = document.getElementById( 'city' ).getElementsByTagName( 'option' );
		for ( var i = 0; i < sel.length; i++ ) {
			if ( this.value.length && sel[i].value.indexOf( this.value ) === 0 ) document.getElementById( 'city' ).selectedIndex = i;
		}
	}
</script>
</body></html>

lolka84 02.09.2010 21:24

Спасибо!
А возможно изменить скрипт, что б результат выводился не в селекте, а в инпуте, где, собсно, и текст вводим ?

exec 03.09.2010 08:14

<html><head><title>Test</title></head><body>
<input type="text" id="foo" />
<select id="city">
	<option>
		Москва
	</option>
	<option>
		Санкт-Петербург
	</option>
	<option>
		Новосибирск
	</option>
	<option>
		Красноярск
	</option>
	<option>
		Самара
	</option>
	<option>
		Нижний Новгород
	</option>
	<option>
		Урюпинск
	</option>
	<option>
		Хабаровск
	</option>
	<option>
		Владивосток
	</option>

</select>
<script type="text/javascript">
	document.getElementById( 'foo' ).onkeypress = function () {
		var sel = document.getElementById( 'city' ).getElementsByTagName( 'option' );
		for ( var i = 0; i < sel.length; i++ ) {
			if ( this.value.length && sel[i].value.indexOf( this.value ) === 0 ) this.value = sel[i].value;
		}
	}
</script>
</body></html>


Только это не совсем удобно будет. Например, если мы хотим набрать "Нижний Новгород", то после ввода буквы "Н" в поле запишется "Новосибирск".

inGray 03.09.2010 09:58

Тогда надо выводить только когда по такой подстроке всего одно значение. Например, не сразу присваивать значение sel[i].value, а добавлять его в массив, в последующем проверяя его длину, и если длина массива с найденными совпадениями = 1 то выводить единственный элемент массива в инпут.

lolka84 04.09.2010 19:04

exec, спасибо большое)

inGray, а как это в виде кода будет выглядеть ?

exec 04.09.2010 19:12

<html><head><title>Test</title></head><body>
<input type="text" id="foo" />
<select id="city">
	<option>
		Москва
	</option>
	<option>
		Санкт-Петербург
	</option>
	<option>
		Новосибирск
	</option>
	<option>
		Красноярск
	</option>
	<option>
		Самара
	</option>
	<option>
		Нижний Новгород
	</option>
	<option>
		Урюпинск
	</option>
	<option>
		Хабаровск
	</option>
	<option>
		Владивосток
	</option>

</select>
<script type="text/javascript">
	document.getElementById( 'foo' ).onkeypress = function () {
		var sel = document.getElementById( 'city' ).getElementsByTagName( 'option' ),
		city = '', find = 0;
		for ( var i = 0; i < sel.length; i++ ) {
			if ( this.value.length && sel[i].value.indexOf( this.value ) === 0 ) city = sel[i].value, find++;
		}
		if ( find === 1 ) this.value = city;
	}
</script>
</body></html>

lolka84 04.09.2010 20:08

exec, супер, но только сейчас заметил, что твой скрипт не дает ничего стирать в инпуте (клавишей Backspace) :)
Еще небольшой баг: 4я введенная буква вылазит в конце названия города. Т.е. пишу к примеру "Санк.." Скрипт выдает "Санкт-Петербургк". С чем это связано непонятно, может внутрений скрипт "примеров" глючит ?

inGray 04.09.2010 20:15

:thanks: Так действительно эффективнее, до тех пор пока не нужно подсказку из вариантов выводить.

exec 04.09.2010 20:29

Чуть поправил.

<html><head><title>Test</title></head><body>
<input type="text" id="foo" />
<select id="city">
	<option>
		Москва
	</option>
	<option>
		Санкт-Петербург
	</option>
	<option>
		Новосибирск
	</option>
	<option>
		Красноярск
	</option>
	<option>
		Самара
	</option>
	<option>
		Нижний Новгород
	</option>
	<option>
		Урюпинск
	</option>
	<option>
		Хабаровск
	</option>
	<option>
		Владивосток
	</option>

</select>
<script type="text/javascript">
	document.getElementById( 'foo' ).onkeypress = function ( e ) {
		if ( (e = e || window.event).keyCode !== 8 ) {
		var sel = document.getElementById( 'city' ).getElementsByTagName( 'option' ),
		city = '', find = 0;
		for ( var i = 0; i < sel.length; i++ ) {
			if ( this.value.length && sel[i].value.indexOf( this.value ) === 0 ) city = sel[i].value, find++;
		}
		if ( find === 1 ) this.value = city, e.preventDefault ? e.preventDefault() : (e.returnValue = false);
		}
	}
</script>
</body></html>

lolka84 04.09.2010 20:41

Спасибо, ребята)
JS для меня темный лес, да.

lolka84 06.09.2010 17:18

Ребята, апну тему.
Добавил условие (if (event.keyCode === 38)), что б скрипт работал только тогда, когда нажата клавиша UP (сделано для того, что бы можно было вносить новые значения в БД, ибо без этого условия сделать невозможно - скрипт автоматом подставляет только то, что есть в селекте).
Возникла следущая проблема: регистр символов. Т.е. если вводить "новос.." скрипт не работает. В селекте есессно все названия с большой буквы. Как побороть ?
<script type="text/javascript"> 
	    document.getElementById( 'a' ).onkeypress = function ( e ) { 
	        if ( (e = e || window.event).keyCode !== 8 ) { 
			  if (event.keyCode === 38) {
	        	var sel = document.getElementById( 's' ).getElementsByTagName( 'option' ), 
	       	    city = '', find = 0; 
	       		    for ( var i = 0; i < sel.length; i++ ) { 
	           			 if ( this.value.length && sel[i].value.indexOf( this.value ) === 0 ) city = sel[i].value, find++; 
	                } 
	                     if ( find === 1 ) this.value = city, e.preventDefault ? e.preventDefault() : (e.returnValue = false); 
			  }
		   } 
	    } 
	</script>

exec 06.09.2010 18:00

sel[i].value.indexOf( this.value ) заменить на sel[i].value.toLowerCase().indexOf( this.value.toLowerCase() )

lolka84 06.09.2010 18:37

Спасибо, дружище)


Часовой пояс GMT +3, время: 08:06.