JQuery AutoComplete: получить «новые» значения, когда они сделаны - PullRequest
0 голосов
/ 26 июня 2009

У меня есть текстовое поле автозаполнения jquery (множественное: true), используемое для задания категорий элемента, в точности как теги stackoverflow.

Источник автозаполнения - это список объектов с переопределением formatItem для правильного отображения.

То, что я пытаюсь сделать, это вытащить из него два списка: один список идентификаторов выбранных категорий (массив целых чисел) и список любых введенных ими «новых» категорий, которых не было в оригинале. список. Вот что я попробовал:

var categories = [];
var newCategoryNames = [];

var collectData = function(event, itemData, formatted) {
    if (itemData == null)
    {
        // no match -- new category
        newCategoryNames[newCategoryNames.length] = formatted;
    }
    else
    {
        categories[categories.length] = itemData.iCategoryID;
    }
};
$('#txtCategories').result(collectData).search().unbind('result');

Это прекрасно работает для уже существующих категорий (предложение "else"), но не работает с новыми элементами (предложение "if"). Это связано с тем, что в этом случае itemData не только передается со значением NULL, но и отформатированный параметр также имеет значение NULL. Я думал, что он все равно будет передан как введенный пользователем текст, но, видимо, нет.

Так что я могу сделать? Этот обратный вызов вызывается на несовпадающем элементе, но, похоже, он не дает мне никакой информации, которая скажет мне, что это был за несоответствующий элемент.

Ответы [ 3 ]

1 голос
/ 15 июля 2009

Как вы можете получить событие «result», чтобы сработало, когда для «множественного» задано значение true и пользователь вводит запись, которой нет в существующем списке? На моей тестовой странице я не смог этого сделать.

Во всяком случае, я отладил исходный код плагина автозаполнения и обнаружил, что он не обрабатывает сценарий, в котором у вас есть «несколько = истина», «mustmatch = ложь» и пользователь вводит в запись, которая не принадлежит вашему список автозаполнения.

Вот отладочная информация:

Существует код, который проверяет нажатие пользователем клавиши, если это COMMA или ваш множественный разделитель, он запускает Метод selectCurrent ().

        // matches also semicolon
        case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
        case KEY.TAB:
        case KEY.RETURN:
            if( selectCurrent() ) {
                // stop default to prevent a form submit, Opera needs special handling
                event.preventDefault();
                blockSubmit = true;
                return false;
            }
            break;

Так выглядит метод selectCurrent. Он пытается получить текущее выбранное значение. Здесь объект выбора - это выпадающий список автозаполнения, созданный плагином. Если пользователь ввел слово, которое не принадлежит списку, он возвращает false и событие «result» не срабатывает.

function selectCurrent() {
    var selected = select.selected();

    if( !selected ) //selected is NULL if user types in comma after typing a word which doesn't belong in the list. And that is why I was surprised that your result event was even triggered.
        return false;

    var v = selected.result;
    previousValue = v;

    if ( options.multiple ) {
        var words = trimWords($input.val());
        if ( words.length > 1 ) {
            v = words.slice(0, words.length - 1).join( options.multipleSeparator ) + options.multipleSeparator + v;
        }
        v += options.multipleSeparator;
    }

    $input.val(v);
    hideResultsNow();
    $input.trigger("result", [selected.data, selected.value]);
    return true;
}

Чтобы исправить это, вы должны проверить параметры.multiple. Вот окончательный код, который будет делать правильно:

function getLastWord()
{
    var words = trimWords($input.val());
    return words[words.length - 1];
};

function selectCurrent() {
    var selected = select.selected();

    //options.multiple BUGFIX START

    //We don't have to check for options.mustMatch because the 'select' component
    //already handles it.
    if(! selected && options.multiple)
    {
        var lastWord = getLastWord();
        //Below code is similar to how the Cache component generates the data.
        selected = {
                        data : lastWord,                            
                        value : options.formatMatch(lastWord, -1, options.data.length),
                        result : options.formatResult && options.formatResult(lastWord) || lastWord

        };
    }
    //options.multiple BUGFIX END

    if( !selected )
        return false;

    var v = selected.result;
    previousValue = v;

    if ( options.multiple ) {
        var words = trimWords($input.val());
        if ( words.length > 1 ) {
            v = words.slice(0, words.length - 1).join( options.multipleSeparator ) + options.multipleSeparator + v;
        }
        v += options.multipleSeparator;
    }

    $input.val(v);
    hideResultsNow();
    $input.trigger("result", [selected.data, selected.value]);
    return true;
}

Таким образом, вы можете изменить свою версию плагина автозаполнения или получить значение текстового поля и выполнить анализ самостоятельно.

0 голосов
/ 30 июля 2009

1) В моем случае, как вы получите Id ItemSelected или присутствует в текстовом поле после выбора. Идентификатор не должен отображаться в выбранном списке, он должен быть прикреплен сзади к каждому значению списка. 2) Содержит ли автозаполнение jquery структуру списка из нескольких столбцов (например: я хочу: ItemCode, Name, Desc, в котором поиск основан на коде товара.)

0 голосов
/ 26 июня 2009

В худшем случае вы сможете извлечь значение из ввода самостоятельно:

if (itemData == null)
{
    // no match -- new category
    newCategoryNames[newCategoryNames.length] = event.target.value;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...