8

我試圖執行Bootstrap Tokenfield with Jquery Ui autocomplete 並且迄今爲止我能夠做到這一點,除了我不能防止輸入字段中的重複,所以,不幸的是,我的用戶可以選擇相同的值兩次。如何防止與自舉Tokenfield重複當使用Jquery Ui自動完成

在我的搜索中,我發現Bootstrap Tokenfield的方法是preventing duplicate。然而,我不知道如何應用我的代碼,因爲它在我看來,它與Twitter typeahead,而不是Jquery Ui。

我該如何防止與Bootstrap令牌字段重複使用Jquery Ui自動完成?

這是一個基於jQuery用戶界面自動完成我的引導TokenField代碼

$('.tokenfield').tokenfield({ 
    autocomplete: { 
    source: [ 
    { 
     "id": "1", 
     "value": "Ferdine Faithfull" 
    }, 
    { 
     "id": "2", 
     "value": "John Carta" 
    }, 
    { 
     "id": "3", 
     "value": "Mezane Smith" 
    } 
    ], 

    delay: 100 
    }, 
    showAutocompleteOnFocus: true 
}); 

而下面是我在Github上找到防止重複,雖然我認爲這是事先鍵入的內容

$('#my-tokenfield').on('tokenfield:createtoken', function (event) { 
    var existingTokens = $(this).tokenfield('getTokens'); 
    $.each(existingTokens, function(index, token) { 
     if (token.value === event.attrs.value) 
      event.preventDefault(); 
    }); 
}); 

回答

15

我想你已經完成了所有工作,你只需要替換類

所以在第一個代碼之後,而不是第二個代碼寫入

$('.tokenfield').on('tokenfield:createtoken', function (event) { 
    var existingTokens = $(this).tokenfield('getTokens'); 
    $.each(existingTokens, function(index, token) { 
     if (token.value === event.attrs.value) 
      event.preventDefault(); 
    }); 
}); 

這裏的區別是你的類,它已被應用,它可以工作在Twitter的事先鍵入的內容和jQuery UI的

1

這可以防止那些已經被添加爲令牌上市項目:

$('.tokenfield').on('tokenfield:createdtoken tokenfield:removedtoken', function (event) { 
    var field = $(this); 
    var currentTokens = field.tokenfield('getTokens'); 
    var originalSource = field.data('bs.tokenfield').options.autocomplete.source; 
    var newSource = originalSource.slice(); //clone original autocomplete source 
    for (var i = newSource.length - 1; i >= 0; i--) { 
     for (var j = currentTokens.length - 1; j >= 0; j--) { 
     if (JSON.stringify(currentTokens[j].label) == JSON.stringify(newSource[i]) 
      || JSON.stringify(currentTokens[j]) == JSON.stringify(newSource[i])) { 
      //remove the token from the newSource 
      var index = newSource.indexOf(newSource[i]); 
      if (index > -1) 
      newSource.splice(index, 1); 
     }; 
     }; 
    }; 
    //update source 
    field.data('bs.tokenfield').$input.autocomplete({source: newSource}) 
}) 

在創建或刪除標記以更新列表後調用此函數。它使用JSON.stringify()來比較對象,並對字符串對象和{value:「foo」,label:「bar」}源對象進行比較。

0
$('.tokenfield').on('tokenfield:createtoken', function (event) { 
    var existingTokens = $(this).tokenfield('getTokens'); 
    $.each(existingTokens, function(index, token) { 
     if (token.value === event.attrs.value) 
      event.preventDefault(); 
    }); 
}); 
+0

使用id或class來代替#my-tokenfield,無論它如上所述。 – 2016-01-20 11:13:55

+0

請解釋你的答案。目前它被視爲低質量的帖子。謝謝! – Dropout 2016-01-20 14:35:53

0

@Javier你的解決方案工作良好,但有時它得到越野車,並添加兩倍的令牌!你有這個想法嗎?

PS在看到我找到解決方案的文檔後。這兩個事件處理都需要。因爲事件是在創建/編輯/刪除標記之前和之後觸發的。

所以,你需要用它來防止加載(之前創建的事件)

$('#tokenfield').on('tokenfield:createtoken', function (event) { 
    var existingTokens = $(this).tokenfield('getTokens'); 
    //check the capitalized version 
    event.attrs.value = capitalizeFirstLetter(event.attrs.value); 
    $.each(existingTokens, function(index, token) { 
     if (token.value === event.attrs.value) { 
      event.preventDefault(); 
      return false; 
     } 
    }); 
}); 

這等過,如你所說,爲源列表(在創建事件)

$('#tokenfield').on('tokenfield:createdtoken tokenfield:removedtoken', function (event) { 
    var field = $(this); 
    var currentTokens = field.tokenfield('getTokens').map(function(i){return i.value}); 
    var originalSource = field.data('bs.tokenfield').options.autocomplete.source; 
    var newSource = []; 
    for (var i = 0; i<originalSource.length; i++) { 
     if(currentTokens.indexOf(originalSource[i])==-1){ 
     newSource.push(originalSource[i]); 
     } 
    }; 
    //update source 
    field.data('bs.tokenfield').$input.autocomplete({source: newSource}); 
    //empty the input field 
    $(".tokenfield.form-control").find("input.token-input").val(""); 
}); 

注意:我更改了「檢查循環」(雙擊是過度使用),並添加了一個檢查以避免「大寫」匹配,以防萬一需要。

function capitalizeFirstLetter(string) { 
    return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); 
}