2009-06-25 78 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,其中搜索基於商品代碼。)