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.

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

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

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

    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: