JQuery UI автозаполнение не закрывает меню параметров, если нет фокуса, когда возвращается AJAX - PullRequest
2 голосов
/ 09 сентября 2011

Я использую виджет автозаполнения jquery ui с ajax и заметил следующую проблему.

Фон: для того, чтобы пользователь мог сосредоточиться на автозаполнении и получить параметры, не вводя ничего, я использую событие focus:

autoComp.focus(function() { $(this).autocomplete("search", "");}

Однако это приводит к следующему эффекту: когда пользователь щелкает, отправляется запрос ajax. В ожидании ответа пользователь затем щелкает в другом месте, и автозаполнение размывается. Но как только ответ возвращается, появляется меню опций, хотя автозаполнение не имеет фокуса. Чтобы его убрать, пользователь должен щелкнуть один раз внутри и снова за пределами автозаполнения, что немного раздражает.

есть идеи, как мне это предотвратить?

РЕДАКТИРОВАТЬ: я решил это очень уродливо путем создания другой медиаторной функции, которая знает идентификатор элемента, и эта функция вызывает функцию ajax с идентификатором, которая в случае успеха проверяет фокус элемента и возвращает ноль, если не сфокусировано. Это довольно уродливо, и я все еще ищу альтернативы.

РЕДАКТИРОВАТЬ # 2: Попытка сделать, как предложил Wlliam, все еще не работает .. XR не определен при размытии. Какая-то проблема с ключевым словом this, может, оно имеет другое значение, если я напишу функцию getTags вне автозаполнения?

this.autocomplete = $('.tab#'+this.id+' #tags').autocomplete({
    minLength: 0,
    autoFocus: true,
    source: getTags,
    select: function(e, obj) {
        tab_id = $(this).parents('.tab').attr('id');
        tabs[tab_id].addTag(obj.item.label, obj.item.id, false);
        $(this).blur(); // This is done so that the options menu won't pop up again.
        return false;  // This is done so that the value will not stay in the input box after selection.
    },
    open: function() {},
    close: function() {}
});
$('.tab#'+this.id+' #tags').focus(function() {
    $(this).autocomplete("search", "");
});
$('.tab#'+this.id+' #tags').blur(function() {
    console.log('blurring');
    var xhr = $(this).data('xhr'); // This comes out undefined... :(
    if (xhr) {
        xhr.abort();
    };
    $(this).removeClass('ui-autocomplete-loading');
});

и это функция getTags, скопированная в ключевое слово source:

        function getTags(request, response)
        {
            console.log('Getting tags.');
            $(this).data('xhr', $.ajax({
                url: '/rpc',
                dataType: 'json',
                data: {
                    action: 'GetLabels',
                    arg0: JSON.stringify(request.term)
                },
                success: function(data) {
                    console.log('Tags arrived:');
                    tags = [];
                    for (i in data) {
                        a = {}
                        a.id = data[i]['key'];
                        a.label = data[i]['name'];
                        tags.push(a);
                    }
                    response(tags);
                }
            }));
            console.log($(this).data('xhr'));
        }

Ответы [ 2 ]

4 голосов
/ 09 сентября 2011

Я думаю, вам нужно использовать опцию обратного вызова для source, чтобы прервать запрос AJAX. Цитирование из обзора виджета автозаполнения:

Обратный вызов получает два аргумента:

  • Объект запроса с единственным свойством, называемым "term", который ссылается на значение в настоящее время в текстовом вводе. Например, когда пользователь ввел "new yo" в поле города, термин автозаполнения будет равно "новый йо".
  • ответный обратный вызов, который ожидает, что один аргумент будет содержать данные, чтобы предложить пользователю. Эти данные должны быть отфильтрованы на основе предоставленный термин, и может быть в любом из форматов, описанных выше для простых локальных данных (String-Array или Object-Array с метка / значение / оба свойства). Это важно при предоставлении пользовательских обратный вызов источника для обработки ошибок во время запроса. Вы должны всегда вызвать ответный обратный вызов, даже если вы столкнулись с ошибкой. это гарантирует, что виджет всегда имеет правильное состояние.

В вашем случае это будет выглядеть примерно так:

$("#autoComp").autocomplete({
    source: function(request, response) {
        var searchString = request.term;

        // ajax call to remote server, perhaps filtered with searchString
        $(this).data('xhr', $.ajax({
            ...
            success: function(data) {
                ...
                // pass back the data filtered by searchString
                response(filteredList);
            }
        }));
    },
    minLength: 0,
    focus: function() {
        $(this).autocomplete("search");
    }
})
// cancel the request when user click away from the input box
.blur(function() {
    var xhr = $(this).data('xhr');
    if (xhr) xhr.abort();
});
1 голос
/ 08 июня 2012

Я справился с этой проблемой, используя Open event .Если при открытии раскрывающегося списка у входа нет фокуса, я просто его закрываю.

$("#autoComp").autocomplete({
  open: function() {
    if ($(this).is(':not(:focus)')) {
      $(this).autocomplete('close');
    }
  },
  source: function(request, response) {
    ...
  }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...