8

Tôi cố gắng để thực hiện Bootstrap Tokenfield with Jquery Ui autocomplete và cho đến nay tôi đã có thể làm được điều đó, ngoại trừ một thực tế rằng tôi không thể ngăn chặn bản sao trong lĩnh vực đầu vào, do đó, không may người dùng của tôi có thể chọn cùng một giá trị hai lần.Làm thế nào để ngăn chặn trùng lặp với Bootstrap Tokenfield Khi sử dụng jQuery UI Autocomplete

Trong tìm kiếm của tôi, tôi đã thấy rằng Bootstrap Tokenfield có cách là preventing duplicate. Tuy nhiên tôi không biết làm thế nào để áp dụng cho mã của tôi bởi vì nó trông với tôi rằng nó đi với Twitter typeahead và không Jquery Ui.

Làm cách nào để ngăn chặn trùng lặp với Bootstrap TokenField Sử dụng tính năng tự động hoàn tất Jquery Ui?

Đây là mã Bootstrap TokenField của tôi dựa trên jquery ui autocomplete

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

    delay: 100 
    }, 
    showAutocompleteOnFocus: true 
}); 

Và dưới đây là những gì tôi đã tìm thấy trên Github để ngăn chặn trùng lặp dù tôi nghĩ rằng nó là dành cho Typeahead

$('#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(); 
    }); 
}); 

Trả lời

15

Tôi nghĩ bạn đã làm tất cả, tất cả những gì bạn cần làm là thay thế lớp học

Vì vậy, sau mã đầu tiên, thay vì mã thứ hai viết

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

Sự khác biệt ở đây là lớp học của bạn mà đã được áp dụng và nó hoạt động cho cả Twitter Typeahead và jQuery UI

1

Điều này ngăn cản các mặt hàng niêm yết đã được thêm vào như là thẻ:

$('.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}) 
}) 

Hàm này được gọi sau khi mã thông báo được tạo hoặc xóa để cập nhật danh sách. Nó sử dụng JSON.stringify() để so sánh các đối tượng và so sánh các đối tượng chuỗi và đối tượng nguồn {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

Sử dụng id hoặc class thay cho # my-tokenfield bất kể nó như được đề cập ở trên. –

+0

Vui lòng giải thích câu trả lời của bạn. Nó hiện đang được xem như một bài đăng chất lượng thấp. Cảm ơn! – Dropout

0

@Javier việc giải pháp của bạn tốt nhưng đôi khi nó được lỗi và thêm hai lần token! Bạn có ý tưởng về hành vi này không?

PS Sau khi xem tài liệu, tôi tìm thấy giải pháp. Cả hai sự kiện xử lý là cần thiết. Vì các sự kiện được kích hoạt trước và sau khi tạo/chỉnh sửa/xóa mã thông báo.

Vì vậy, bạn cần điều này để ngăn chặn các add (trước khi tạo sự kiện)

$('#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; 
     } 
    }); 
}); 

Và điều này khác quá, như bạn đề nghị, đối với các nguồn-list (sau khi tạo sự kiện)

$('#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(""); 
}); 

LƯU Ý: Tôi đã thay đổi "kiểm tra vòng lặp", (gấp đôi cho đã overkilling), và thêm một kiểm tra để tránh "viết hoa" phù hợp, chỉ trong trường hợp bạn cần nó.

function capitalizeFirstLetter(string) { 
    return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); 
} 
Các vấn đề liên quan