Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Обход элементов формы по Enter (https://javascript.ru/forum/jquery/50656-obkhod-ehlementov-formy-po-enter.html)

myshara 06.10.2014 12:42

Обход элементов формы по Enter
 
Доброго времени суток всем форумчанам!

Стоит такая задача-навесить ряд событий на кнопку Enter.

Есть элемент #dialog.
На нем есть ряд элементов input и button (кнопка одна "Oтправить")

1) Вызов диалога - нажалтие Enter.
2) Выбор из Datalist - нажатие Enter.
3) Переход к следующему полю input(button) - нажатие Enter.
4) Отправка формы на сервер - нажатие Enter.

Отследить нажатие кнопки Enter можно:
<script type="text/javascript">
$(document).bind('keydown', function(event) 
{if (event.keyCode == 13) my_fn(this)};});
</script>


А как быть дальше?
Как определить открыт Datalist или нет и по нажатию Enter выбрать из Datalist?
Как перейти к следующему input? Может стоит создать массив с именами input и переходить по ним?

Заранее благодарен!

P.S.:
Просьба - не убеждайте меня что все события нужно развести на разные клавиши (ins - вызов диалога, tab - переход по input, enter - выбор из списка и отправка формы на сервер).
Задача конкретная и "суровая" - все по кнопке Enter.

Еще раз спасибо.

danik.js 06.10.2014 13:21

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

myshara 06.10.2014 17:16

Попытка реализации
 
Спасибо danik.js.

Почти получилось.

Решил сделать так:

<script type="text/javascript">
$(document).bind('keydown', function(event) {if (event.keyCode == 13) $('#dialog').dialog('open')};});
			
$('input:[name="input_1"]').bind('keydown', function(event) {if (event.keyCode == 13) $('input:name="input_2"]').focus()};});

$('input:[name="input_2"]').bind('keydown', function(event) {if (event.keyCode == 13) $('input:[name="input_3"]').focus() };});
			
$('input:[name="input_3"]').bind('keydown', function(event) {if (event.keyCode == 13) $('input:[name="input_4"]').focus() };});

$('input:[name="input_4"]').bind('keydown', function(event) {if (event.keyCode == 13) $('button:[name="btn_send"]').focus() }; });

</script>


В результате:
1) Диалог открывается.
2) По элементам input переходим.

Ошибки:
1) В Firefox не обрабатывается Datalist (в Chrome все нормально)
2) Код $('button:[name="btn_send"]').focus() - не только ставит фокус но и как бы нажимает кнопку, а это следующее нажатие на Enter. (В обоих браузерах).

Как решить данные "траблы"?

danik.js 06.10.2014 18:25

Насчет datalist - не знаю че эт такое. Насчет отправки - нужно тормозить событие, так как браузер по нажатию на Enter отсылает форму - это его дефолтное действие. Странно что это срабатывает только на последнем поле. Пробуй return false либо event.preventDefault().

Вместо кучи кода лучше что-то вроде:

var $inputs = $form.find('input:not([type="hidden"]),select,textarea');

$inputs.on('keydown', function(event) {
    if (isEnter(event)) {
        var $next  = $inputs.eq($inputs.index(this) + 1);
        next.focus();
        event.preventDefault();
    }
});

var $submit = $form.find('[type="submit"]');
$submit.on('keydown', function(event) {
    if (isEnter(event))
        this.form.submit();
});

myshara 06.10.2014 21:39

Кратко о datalist
 
Привет всем.

Кратко о Datalist : http://htmlbook.ru/html/datalist

Это список значений для быстрого доступа (автодополнения).

Интересно:
1) в Хроме - как sql select like "chr%"
2) в Мозиле - как sql select like "%chr%"

где: chr - символ(строка) которое вводиться (содержимое input)
% - подстановочный символ

Мне нравится как работает в Мозиле (жаль что отображает только 5 (далее скрол), как настроить 10 в списке?)

myshara 08.10.2014 11:27

Пробую так:

$inputs.on('keydown', function(event) {
if (isEnter(event)) {
$datalist.Event()
var $next  = $inputs.eq($inputs.index(this) + 1);
event.preventDefault();}};)


Результата нет.

danik.js 08.10.2014 11:31

Цитата:

Сообщение от myshara
$datalist.Event()

Это что?
функцию isEnter ты должен создать сам. Ну или делать проверку на месте.
где вызов $next.focus() ? И про какой результат речь?

myshara 08.10.2014 19:45

danik.js - спасибо что не бросили тему.

Извините за код.
Да упустил в предложенном выше коде $next.focus().
$datalist.Event() - честно я думал перехватить событие в $datalist=$('datalist')

Пробовал такой вариант:

$inputs.on('keydown', function(event) {
if (isEnter(event)) {
var $next  = $inputs.eq($inputs.index(this) + 1);
setTimeout($next.focus(),500);
event.preventDefault();}
};)


Нужного мне результата нет.

Да, я прекрасно понимаю что фокус находится в input несмотря на то, что виден datalist и мы можем с клавиатуры стрелками выбрать значение, и следовательно происходит переход $next.focus(). Но почему не срабатывает задержка и выбор значения? Как это перехватить?

Еще раз спасибо.

danik.js 08.10.2014 21:23

Цитата:

Сообщение от myshara
Но почему не срабатывает задержка

Потому что ты незамедлительно вызываешь функцию:
Цитата:

Сообщение от myshara
$next.focus()

Откуда тут задержке взяться. setTimeout вхолостую срабатывает, потому как ждет аргументом функцию, а ты передаешь результат вызова функции focus()
Понял свой косяк? Кроме того, если ты передашь аргументом непосредственно функцию .focus - получится хрень, потому что она будет оторвана от контекста вызова (оторвана $next). This в javascript, если в курсе - штука необычная и нужно быть внимательным с этим. Решение - анонимная функция, внутри которой уже делай вызов $next.focus() - без отрыва от $next.

myshara 09.10.2014 09:42

Уважаемый danik.js.

Насколько я понял вы предлагаете:

setTimeout(function(){$next.focus();},200);


Но и так я не получил необходимого мне результата.


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