2009-06-25 75 views
0

我有一个jquery自动完成文本框(多个:true)用于设置项目上的类别,非常像stackoverflow标签。jquery自动完成:当它们完成时获取“新”值

自动完成源是一个对象列表,其中formatItem被override以执行正确的显示。

我想要做的是从中拉出两个列表:所选类别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'); 

也能正常工作的预先存在的类别(“其他”条款),但未能对新项目(“如果”条款)。这是因为不仅在这种情况下itemData传递为null,而且格式化参数也为null。我原以为它仍然会作为用户输入的文本传入,但显然不是。

那么我该怎么办?该回调被称为不匹配的项目,但它似乎没有给我任何信息,告诉我实际上是不匹配的项目。

回答

0

最坏的情况下,你应该能够从输入自己拉值:

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

不幸的是,event.target.value只是完整的内容文本框。如果我打算使用它,我可以完全绕过所有这些代码并尝试分割$('#txtbox')。val();但我希望能够使用自动完成中已有的代码在显示值和ID之间进行映射。 – Clyde 2009-06-29 15:06:20

1

你怎么能得到“结果”事件,当“多”设置为true火灾和用户类型的不属于现有列表的条目?在我的测试页面中,我无法做到。

无论如何,我通过自动完成插件源代码进行调试,发现它不处理您有'多重= true','mustmatch = false'以及用户类型不属于您的自动完成列表。

这里的调试信息:

有其检查由用户按下的按键的代码,如果是逗号或您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方法的样子。它试图获得当前选定的值。 这里select对象是插件创建的'autocomplete'下拉列表。 如果用户输入了不属于该列表的单词,它将返回false,并且'结果'事件不会触发。

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; 
} 

所以,你可以修改你的自动完成插件的版本或获取文本框的值,做解析自己。

+0

我最终只是解析自己(它实际上只是分离字符的分割,然后在列表中搜索字符串)。但是,谢谢,这非常有趣 – Clyde 2009-07-15 13:25:02

0

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