jquery autocomplete:完成后获取“新”值

时间:2009-06-25 20:18:20

标签: javascript jquery autocomplete

我有一个jquery自动完成文本框(multiple:true)用于设置项目的类别,非常类似于stackoverflow标记。

自动完成源是一个对象列表,formatItem覆盖以执行正确的显示。

我要做的是从中拉出两个列表:一个选定类别ID列表(整数数组),以及他们输入的任何“新”类别的列表,这些类别不在原始列表中名单。这就是我试过的:

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 个答案:

答案 0 :(得分:1)

当'multiple'设置为true并且用户键入不属于现有列表的条目时,如何才能触发'result'事件?在我的测试页面中,我无法做到。

无论如何,我通过autocomplete插件源代码调试,发现它没有处理你有'multiple = true','mustmatch = false'和用户输入不属于你的条目的情况自动完成列表。

这是调试信息:

有一个代码可以检查用户按下的键,如果它是COMMA或你的multipleSeparator,它会触发 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;
}

要解决此问题,您应该检查options.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;
}

因此,您可以修改自动完成插件的版本或获取文本框的值并自行进行解析。

答案 1 :(得分:0)

最坏的情况是你应该能够自己从输入中提取值:

if (itemData == null)
{
    // no match -- new category
    newCategoryNames[newCategoryNames.length] = event.target.value;
}

答案 2 :(得分:0)

1)在我的情况下,如何在选择后获得ItemSelected的Id或出现在文本框中。 ID不应该显示在选定的列表中,它应该从后面附加到每个列表值。 2)jquery自动完成包含多列列表结构(例如:我想要:ItemCode,Name,Desc,其中搜索基于Item Code。)