2013-07-30 3 views
2

У меня есть несколько полей ввода для автозаполнения с помощью автозаполнения jQuery UI. Каждый вход имеет соответствующий скрытый ввод (например, имя пользователя или идентификатор пользователя). В обработчике изменений я устанавливаю значение скрытого поля. Это работает точно так, как ожидалось.jQuery UI Autocomplete - сделать click/enter перейти к следующему полю

Проблема возникает, когда я хочу, чтобы клавиша Return + щелчок мыши автоматически выбирал следующее поле. Если я не инициирую вручную событие изменения, событие изменения ui.item имеет значение NULL. Если я запускаю его вручную, он запускает второе событие изменения с нулем ui.item.

Я могу добавить охранника в изменении защиты от нулевого ui.item, но это помешало бы мне расчистке поля я ранее заполненные

Короче. - нажав вкладку, введите или щелчок мыши должен установите значение текстового ввода для имени пользователя, установите скрытый ввод в идентификатор пользователя и сфокусируйте следующий ввод текста.

Вот JSFiddle с инлайн комментариями, чтобы показать/объяснить проблему в контексте: http://jsfiddle.net/shipstar/Jvfx3/4/

Спасибо!

+0

Другой подход заключается в использовании исходного массива источника автозаполнения, чтобы найти соответствующее значение. Это хорошо (хотя и неуклюжий) для небольших наборов данных, но кажется нецелесообразным для больших данных. – Kyle

+0

Другим хакерским решением было бы добавить пустую запись и установить minLength в 0. Это визуально неудобно и будет плохо работать при переключении на серверный источник данных. – Kyle

ответ

1

Переместите логику фокуса внутри close event и обновите значение в пределах select event.

http://jsfiddle.net/Jvfx3/6/

select: function (event, ui){ 
    var $userIdField = $(this).siblings(".user-id"); 
    var userId = ui.item ? ui.item.userId : ''; 
    $userIdField.val(userId); 

    $(this).siblings('label').find('span').text(userId); 
}, 
close: function(event, ui){ 
    if (!event.keyCode || event.keyCode === 13){ 
     $(this).parents('form').find('.user-name').filter(function(){ 
      return $(this).val() === ''; 
     }).first().focus(); 
    } 
} 
+0

Это исправляет непреднамеренную боковую ошибку, но я думаю, что основная проблема все еще стоит - два события стреляют. Я мог бы установить Timeout на _trigger, чтобы обеспечить правильный порядок, но это все еще похоже на хак. – Kyle

+0

re: скрипка # 6 - это исправление двойного срабатывания, но теряет возможность удалять ранее выбранные записи, потому что событие select только срабатывает, когда вы явно выбираете что-то в исходных данных. #whackamole – Kyle

0

Не уверен, что если ты еще с этой проблемой или нет, но у меня были точно такие же трудности, как и вы. Я все еще практически новичок, когда дело доходит до JS & jQuery, поэтому могут быть и другие, более чистые способы сделать это, но я не знаю, что это такое, и мне удалось заставить это работать в моем коде, поэтому надеюсь, это работает для вас или кого-либо еще с этой проблемой.

Я расширил решение @Jacob_Kralls и попытался решить проблему неспособности удалить ранее выбранную запись. Поскольку ui.item возвращает значение null после установки фокуса, я добавил второе скрытое поле для хранения копии выбранного значения, а вместо проверки на большие или удаленные наборы данных вы можете сравнить с полем скопированного значения.

Вот скрипка: http://jsfiddle.net/Jvfx3/11/

фрагмент кода HTML с новым checkVal поле:

<div> 
    <input type="hidden" class="user-id" id="h1" /> 
    <input type="hidden" class="user-name-checkVal" id="cv1" /> 
    <input type="text" class="user-name" id="t1" /> 
    <label>User ID is: <span>undefined</span></label> 
</div> 

Javascript сниппеты:

В случае выбора, установите в поле checkVal, равное значению, выбранному.

select: function (event, ui) { 
    $(this).siblings(".user-id").val(ui.item.userId); 
    $(this).siblings(".user-name-checkVal").val(ui.item.value); 
    $(this).siblings('label').find('span').text(ui.item.userId); 
},  

in the change event сравнить имя пользователя value для проверкиVal, разрешить пустое имя пользователя при удалении значения.

change: function (event, ui) { 
    var username = $(this).val(); 
    var checkVal = $(this).siblings(".user-name-checkVal").val(); 
    if (username == '') { 
    //username has changed, and now its null. value has been deleted. 
    // clear everything set when value was selected. 

    $(this).val(''); 
    $(this).siblings(".user-name-checkVal").val(''); 
    $(this).siblings(".user-id").val('undefined'); 
    $(this).siblings('label').find('span').text('undefined'); 

    } else if (username != checkVal) { 
    //username was not selected from list. reset everything set by select. 
    $(this).siblings(".user-name-checkVal").val(''); 
    $(this).siblings(".user-id").val(''); 
    $(this).siblings('label').find('span').text('undefined'); 

    //user-name is invalid, alert user of the error. 
    alert('Invalid username. choose from list.'); 

    //since the value was entered, and not selected, keep focus here. 
    $(this).val(''); 
    $(this).focus(); 
    } 
}, 

на близком событии, снова сравнит имя пользователя и checkVal, только установить фокус на следующий элемент в списке, если они совпадают.(Это работало в хроме, но в Firefox, курсор еще не закончился в следующем пункте, не знаю, почему)

close: function (event, ui) { 
    if (!event.keyCode || event.keyCode === 13) { 
     var username = $(this).val(); 
     var checkVal = $(this).siblings(".user-name-checkVal").val(); 
     if (username == checkVal) { 
      $(this).parents('form').find('.user-name') 
       .filter(function() { return $(this).val() === ''; }) 
       .first().focus(); 
     } 

    } 
} 
Смежные вопросы