javascripthtmljquerymulti-select

Change Multiselect With Group Options Based On Input Of Another Select Option


I have Two Select Options in that Based on first select options i need to load second select options values. Second select option having multiselect option The HTML code is below.

<div>
  <select name="Control" id="ctrl_typ" onchange="Control_change()">
    <option selected="selected" disabled="disabled">COMMAND</option> 
    <option  disabled="disabled"></option>
    <option  value="1">First</option>
    <option  value="2">Second</option>                  
  </select> 
  <select name="Names[]" multiple id="nameid" size="30">
  </select>
</div>

JS part is below.

var maxSelect=1000;
$( document ).ready(function()
   {
    $('#nameid').multiselect({
    columns: 1,
    texts: {
        placeholder: 'Name',
        search     : 'Search Names'      
       },
    search: true,
    maxWidth:467,
    maxHeight:400, 
    selectAll: true,
    selectGroup: true,
    onOptionClick: function( element, option ) 
       {
         if( $(element).val().length > maxSelect ) {
                    if( $(option).is(':checked') ) {
                        var thisVals = $(element).val();

                        thisVals.splice(
                            thisVals.indexOf( $(option).val() ), 1
                        );

                        $(element).val( thisVals );

                        $(option).prop( 'checked', false ).closest('li')
                            .toggleClass('selected');
                    }
                }
           else if( $(element).val().length == maxSelect ) 
                {
                    $(element).next('.ms-options-wrap')
                        .find('li:not(.selected)').addClass('disabled')
                        .find('input[type="checkbox"]')
                            .attr( 'disabled', 'disabled' );
                }
                // max select not reached, make sure any disabled
                // checkboxes are available
                else {
                    $(element).next('.ms-options-wrap')
                        .find('li.disabled').removeClass('disabled')
                        .find('input[type="checkbox"]')
                            .removeAttr( 'disabled' );
                }
            }
 });

function Control_change()
   {
    var ctrlval=$("#ctrl_typ option:selected").val();
    var Gload="";
    if(ctrlval==1)
       {
        Gload="<select name="Names[]" multiple id="nameid" size="30">
                 <optgroup label='Label 1'>
                   <option value='1'>One</option>
                   <option value'2'>Two</option>
                   <option value='3'>Three</option>
                 </optgroup>
                 <optgroup label='Label 2'>
                   <option value='4'>Four</option>
                   <option value'5'>Five</option>
                   <option value='6'>Six</option>
                 </optgroup>
              </select>"; 
        $('#nameid').replaceWith(Gload);
       }
    else if(ctrlval==2)
       {
        Gload="<select name="Names[]" multiple id="nameid" size="30">
                 <optgroup label='Label 3'>
                   <option value='1'>One</option>
                   <option value'2'>Two</option>
                   <option value='3'>Three</option>
                 </optgroup>
                 <optgroup label='Label 4'>
                   <option value='4'>Four</option>
                   <option value'5'>Five</option>
                   <option value='6'>Six</option>
                 </optgroup>
              </select>";
        $('#nameid').replaceWith(Gload);
       }

   }

I am tried the above code but is not working well while select multiselect dropdown it giving error guide me to resolve the issue. I want to load the multiselect dropdown with group values.


Solution

  • There are several issues. the biggest is the use of double quotes around your select html. I have replaced that with template literal backticks (`)

    The other is that you are replacing the select instead of replacing the content

    Here is a running version that may or may not look like you need it to do but it does change the select based on the other. I have not changed anything except the syntax errors and the missing includes

    var maxSelect = 1000;
    $(document).ready(function() {
      $('#nameid').multiselect({
        columns: 1,
        texts: {
          placeholder: 'Name',
          search: 'Search Names'
        },
        search: true,
        maxWidth: 467,
        maxHeight: 400,
        selectAll: true,
        selectGroup: true,
        onOptionClick: function(element, option) {
          if ($(element).val().length > maxSelect) {
            if ($(option).is(':checked')) {
              var thisVals = $(element).val();
    
              thisVals.splice(
                thisVals.indexOf($(option).val()), 1
              );
    
              $(element).val(thisVals);
    
              $(option).prop('checked', false).closest('li')
                .toggleClass('selected');
            }
          } else if ($(element).val().length == maxSelect) {
            $(element).next('.ms-options-wrap')
              .find('li:not(.selected)').addClass('disabled')
              .find('input[type="checkbox"]')
              .attr('disabled', 'disabled');
          }
          // max select not reached, make sure any disabled
          // checkboxes are available
          else {
            $(element).next('.ms-options-wrap')
              .find('li.disabled').removeClass('disabled')
              .find('input[type="checkbox"]')
              .removeAttr('disabled');
          }
        }
      });
    })
    
    function Control_change() {
      var ctrlval = $("#ctrl_typ option:selected").val();
      var Gload = "";
      if (ctrlval == 1) {
        Gload = `<optgroup label='Label 1'>
                           <option value='1'>One</option>
                           <option value'2'>Two</option>
                           <option value='3'>Three</option>
                         </optgroup>
                         <optgroup label='Label 2'>
                           <option value='4'>Four</option>
                           <option value'5'>Five</option>
                           <option value='6'>Six</option>
                         </optgroup>`;
        $('#nameid').html(Gload);
      } else if (ctrlval == 2) {
        Gload = `<optgroup label='Label 3'>
                           <option value='1'>One</option>
                           <option value'2'>Two</option>
                           <option value='3'>Three</option>
                         </optgroup>
                         <optgroup label='Label 4'>
                           <option value='4'>Four</option>
                           <option value'5'>Five</option>
                           <option value='6'>Six</option>
                         </optgroup>`;
        $('#nameid').html(Gload);
      }
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <script src="
    https://cdn.jsdelivr.net/npm/jquery-multiselect@1.0.0/jquery-MultiSelect.min.js
    "></script>
    <link href="
    https://cdn.jsdelivr.net/npm/jquery-multiselect@1.0.0/jquery-MultiSelect.min.css
    " rel="stylesheet">
    <div>
      <select name="Control" id="ctrl_typ" onchange="Control_change()">
        <option selected="selected" disabled="disabled">COMMAND</option>
        <option disabled="disabled"></option>
        <option value="1">First</option>
        <option value="2">Second</option>
      </select>
      <select name="Names[]" multiple id="nameid" size="30">
      </select>
    </div>

    Here is a version using the documentation found here https://springstubbe.us/projects/jquery-multiselect/

    var maxSelect = 3; // Keep this for your max selection logic
    
    $(function() {
      // Initialize the multiselect with optgroup support
      $('#nameid').multiselect({
        columns: 1,
        texts: {
          placeholder: 'Select Names',
          search: 'Search Names'
        },
        search: true,
        maxWidth: 467,
        maxHeight: 400,
        selectAll: true,
        selectGroup: true, // Crucial for optgroup functionality
        onOptionClick: function(element, option) {
          var selectedValues = $(element).val() || [];
    
          if (selectedValues.length > maxSelect) {
            if ($(option).is(':checked')) {
              var clickedValue = $(option).val();
              var indexToRemove = selectedValues.indexOf(clickedValue);
              if (indexToRemove > -1) {
                selectedValues.splice(indexToRemove, 1);
              }
              $(element).val(selectedValues);
              $(option).prop('checked', false).closest('li').removeClass('selected');
              alert('You can only select a maximum of ' + maxSelect + ' options.');
            }
          } else if (selectedValues.length === maxSelect) {
            $(element).next('.ms-options-wrap')
              .find('li:not(.selected)').addClass('disabled')
              .find('input[type="checkbox"]')
              .attr('disabled', 'disabled');
          } else {
            $(element).next('.ms-options-wrap')
              .find('li.disabled').removeClass('disabled')
              .find('input[type="checkbox"]')
              .removeAttr('disabled');
          }
        }
      });
    
      // Handle change on the 'Control' dropdown
      $('#ctrl_typ').on('change', function() {
        var ctrlval = $(this).val();
        let optionsToLoad = [];
    
        if (ctrlval === '0') {
          optionsToLoad = [allOptGroupsData[0]]; // Only Group 1
        } else if (ctrlval === '1') {
          optionsToLoad = [allOptGroupsData[1]]; // Only Group 2
        } else if (ctrlval === 'all') {
          optionsToLoad = allOptGroupsData; // All groups
        } else if (ctrlval === 'clear') {
          optionsToLoad = []; // Clear the list
        }
    
        if (!ctrlval || ctrlval === 'COMMAND' || ctrlval === 'clear') {
          $('#nameid').multiselect('loadOptions', []); // Clear and disable
          $('#nameid').multiselect('disable', true);
        } else {
          $('#nameid').multiselect('loadOptions', optionsToLoad);
          $('#nameid').multiselect('disable', false); // Enable once options are loaded
        }
      });
    
      // Initial state: clear and disable the multiselect if "COMMAND" is selected
      $('#ctrl_typ').trigger('change');
    });
    body {
      font-family: sans-serif;
      padding: 20px;
    }
    
    div {
      margin-bottom: 20px;
    }
    
    .ms-options-wrap {
      margin-top: 5px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@nobleclem/jquery-multiselect@2.4.24/jquery.multiselect.min.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@nobleclem/jquery-multiselect@2.4.24/jquery.multiselect.min.css">
    
    <div>
      <label for="ctrl_typ">Select Control Group:</label>
      <select name="Control" id="ctrl_typ">
        <option selected="selected" disabled="disabled">COMMAND</option>
        <option value="0">Show Group 1 Data</option>
        <option value="1">Show Group 2 Data</option>
        <option value="all">Show All Data</option>
        <option value="clear">Clear List</option>
      </select><br/>
      <label for="nameid">Select Names:</label>
      <select name="Names[]" id="nameid" multiple size="30"></select>
    </div>
    
    
    
    <script>
      // Data structure that includes optgroups, directly from the documentation example
      const allOptGroupsData = [{
        label: 'Group 1',
        options: [{
          name: 'Option 1',
          value: 1,
          checked: false
        }, {
          name: 'Option 2',
          value: 2,
          checked: true
        }, {
          name: 'Option 3',
          value: 3,
          checked: false
        }]
      }, {
        label: 'Group 2',
        options: [{
          name: 'Option 4',
          value: 4,
          checked: false
        }, {
          name: 'Option 5',
          value: 5,
          checked: true
        }, {
          name: 'Option 6',
          value: 6,
          checked: false
        }]
      }];
    </script>