Search code examples
javascriptjqueryjquery-select2

Select2 remove default option when another selected


I'd like to have a default option act like a placeholder.

I'm doing an ajax search for Products. I want my input box to show "All" until I've selected a product.

This will be the default view:

enter image description here

But as soon as I select a product, I want All to disappear and just the product to show: enter image description here

I've put together a codepen to hopefully get things rolling!

Thank you all!

https://codepen.io/saltcod/pen/bGdzoGN

HTML:

<div class="container">

  <select class="form-control am-product-selector__product-list-select" name="choices-multiple-default" id="choices-multiple-default" placeholder="All Products" multiple>
    <option value="All" selected>All</option>

  </select>

</div>

And the JS:


const options = [{ id: 1, text: 'All' }];

const select2Instance = jQuery( '#choices-multiple-default' ).select2( {
        placeholder: 'Search products',
        ajax: {
            url: url,
            dataType: 'json',
            delay: 250,

            data: params => {
                return {
                    //term: params.term // search query
                };
            },

            // Process fetched results
            processResults: data => {
                if ( data ) {
                    data.map( item => {
                        options.push( { id: item.id, text: item.title } );
                    } );
                }

                return {
                    results: options
                };
            },
            cache: true
        },
        minimumInputLength: 3 // the minimum of symbols to input before perform a search
    } );

Solution

  • First, let's outline the scenarios that need to be handled:

    1) Adding an option (other than "All") from the async list.

    • When an option (other than "All") is selected, remove the "All" option from the selection.
    • This will be handled before selection.

    2) Deleting all options (no values in the select).

    • When all options are unselected, the "All" option should automatically be re-added.
    • This will be handled after selection.

    3) Selecting the "All" option from the dropdown.

    • When "All" is selected, clear all other selections.
    • This will be handled before selection.

    Now, let's explore how we can use the Select2 Events API to handle these scenarios:

    • select2:selecting event - Triggered before a result is selected.
    • select2:unselectevent - Triggered whenever a selection is removed.

    The code is:

    select2Instance.on('select2:selecting', function (e) {
      // Get the value of the item being selected
      const valueToSelect = e.params.args.data;
      
      // Get the current selected values in the dropdown
      const currentValues = $(this).val();
      
      // If the option being selected is 'All', or if 'All' is already selected, clear current selections.
      // The selected result will be added after clear.
      if (valueToSelect.id === 'all' || currentValues.includes('all')) {
        $(this).val([]);
      }
    });
    
    select2Instance.on('select2:unselect', function () {
      const values = $(this).val();
      
      // If no values are left after unselecting, automatically set the value to 'all'.
      // This ensures that when all options are unselected, the dropdown defaults to 'all'.
      if (values.length === 0) {
        $(this).val('all');
      }
      
      // Trigger the 'change.select2' event specifically for Select2 to notify it of the changes.
      $(this).trigger('change.select2');
    });
    

    Demo: https://codepen.io/andreivictor/pen/MYgvRoV

    More info about Select2 Events: