craigh
craigh

Reputation: 2291

limit displayed selections tom-select

I am using the javascript lib Tom-Select. I would like to limit the display of how many items have been selected. I do not want to limit the number of actual choices - only how many are displayed. Standard functionality shows all selections in a growing box. I would like to set a limit of 3. Then if a user selects more than 3 the box will no longer grow but simply say 4 items selected (or 5, 6, etc). Bonus points if I could limit selections by the element width instead of a count (forcing the element to always remain on one line of the form).

Upvotes: 1

Views: 1857

Answers (2)

R. Steigmeier
R. Steigmeier

Reputation: 402

ok, i got it. This is how you can achieve it:

<script>
    new TomSelect('#your_id', {
        plugins: ['checkbox_options'],
        onInitialize: function (){
            updateSelectedDisplay(this);
        },
        onItemAdd: function() {
            updateSelectedDisplay(this);
        },
        onItemRemove: function() {
            updateSelectedDisplay(this);
        }
    });
    function updateSelectedDisplay(instance) {
        selectedItems = instance.control.querySelectorAll('.item');
        var childElement = instance.control.querySelector('#ts-placeholder');
        var numSelected = selectedItems.length;

        if (numSelected > 1) {
            // hide all existing
            selectedItems.forEach(function(item){
                item.hidden = true
            })
            if (!childElement){
                // add dummy
                var divElement = document.createElement('div');
                // Set attributes
                divElement.setAttribute('id', 'ts-placeholder');
                // Set content
                divElement.textContent = numSelected + ' items selected';
                // Append the div element to the second last position of the desired parent element
                instance.control.insertBefore(divElement, instance.control.lastChild);
            } else {
                var childElement = instance.control.querySelector('#ts-placeholder');
                childElement.textContent = numSelected + ' items selected';
            }
        } else {
            selectedItems.forEach(function(item){
                item.hidden = false
            })
            var childElement = instance.control.querySelector('#ts-placeholder');
            if (childElement){
                instance.control.removeChild(childElement)
            }
        }
    }
</script>

To modify the threshold just modify if (numSelected > 1) according to your needs. Unfortunately it doesn't solve the behaviour of TomSelect that it resizes the input field. That might be tackled by adding custom css.

Upvotes: 0

b126
b126

Reputation: 1254

You could trick using the render method and the items.length array, but how will you then let your users delete their own choices as you don't display the selected items?

render: {
            option: function (data, escape) {
                return '<div class="d-flex"><span>' + escape(data.text) + '</span></div>';
            },
            item: function (data, escape) {
                //return '<span class="tag is-info mb-1 mr-1">' + escape(data.text) + '</span>';
                if (this.items.length >= 3){
                    return '<span class="tag is-info mb-1 mr-1" style="display:none">' + escape(data.text) + '</span>';
                }else{
                    return '<span class="tag is-info mb-1 mr-1">' + escape(data.text) + '</span>';
                }
            }
        }

Upvotes: 0

Related Questions