Twitter Typeahead различает события

Я разрабатываю систему, которая позволяет пользователям аннотировать элементы строками или терминами из словаря. Я использую написание Twitter для автозаполнения и хочу различать введенную строку и термин.

Я не могу понять, как различать следующие ситуации:

  1. пользователь нажимает Enter после того, как придумал собственное значение
  2. пользователь нажимает стрелку вниз (или вверх) (тем самым выбирает вариант автозаполнения) и нажимает клавишу ввода

Слушатели событий я написал:

$("#itemInp").on('typeahead:select', function(event, term) {
    console.log("save: term", term);
});

$("#itemInp").on('keyup', function(event) {
    if(event.which == 13) {
        var string = $("#itemInp").val();
        console.log("save: string", string);
    }
});

Со следующим HTML:

<input id="itemInp"><input>

Первый слушатель улавливает все выбранные термины с опережением ввода, что позволяет правильно сохранить термин. Проблема в том, что второй прослушиватель также запускается в случае, если пользователь нажимает и вводит, выбирая термин, предшествующий типу, который теперь также сохраняется в виде простой строки. Есть ли способ не запускать второй слушатель, если выбрано предложение с опережением типа?

Скрипка с загруженным кодом: https://jsfiddle.net/zban3vs6/1/

Изменить: я рассмотрел несколько хаков, но у всех есть свои проблемы:

  1. Добавьте специальный символ в строку, отображаемую во входных данных в момент ее выбора, путем добавления настраиваемого отображения Typeahead: https://jsfiddle.net/2t9rzhwf/ Это вызывает введение дополнительного символа, что вызывает проблемы, если пользователь нажимает стрелку вниз, не нажимая Enter.

  2. Попытайтесь упорядочить слушателей, сначала попросите термин «триггер слушателя», установите для логического значения true и отфильтруйте это логическое значение во втором слушателе. Не нравится такой способ фильтрации, так как он вносит задержку.

  3. Решение, предоставляемое @ peter-clause, проверяет, находится ли выбранное значение в списке доступных элементов. Но таким образом я не могу отслеживать, намеревался ли пользователь использовать опцию автозаполнения для выбора термина или явно добавляет простую строку.


person rasvaan    schedule 09.02.2016    source источник


Ответы (2)


У меня была похожая проблема. Вот как я это решил.

    var wasSelected = false;
    $("#itemInp").on('typeahead:select', function(event, term) {
        wasSelected = true;
        console.log("save: term", term);
    });

    $("#itemInp").on('change', function(event) {
        if(!wasSelected) {
            var string = $("#itemInp").val();
            console.log("save: string", string);
        }
        wasSelected = false;    
    });
person Karolis Šinas    schedule 01.04.2016
comment
Спасибо, главное, что помогло мне обойти это, - это осознание того, что порядок запуска слушателей не меняется. Мое решение более специфично для реализации, я очищаю поле ввода в первом слушателе, когда используется typeahead. Если второй слушатель затем встречает поле, он предполагает, что для этого случая нет ввода. - person rasvaan; 15.04.2016

Довольно хакерское решение, но вы можете проверить, находится ли выбранное значение в списке доступных элементов.

if (states.indexOf(string) == -1) {
    //...
}

См. https://jsfiddle.net/zban3vs6/2/.

person Peter Clause    schedule 09.02.2016
comment
Спасибо за ответ, но таким образом я не могу отслеживать, намеревался ли пользователь использовать опцию автозаполнения для выбора термина или явно добавляет простую строку. Я упростил пример, приложение использует опережающий тип, связанный с uris, для устранения неоднозначности выбранных терминов. Если кто-то, например, набирает Алабаму, не нажимая вверх или вниз, чтобы выбрать предложение ввода вперед, я бы в этом случае сохранил его как термин, в то время как он должен быть сохранен как обычная строка. - person rasvaan; 09.02.2016