Home > Software engineering >  Bootstrap multiselect - filtering a second multiselect from the first
Bootstrap multiselect - filtering a second multiselect from the first

Time:12-25

I currently have 2 multiselect dropdowns on a page, one called 'hazards' and the other 'hp_codes'. They both populate their lists from a SQL DB and the idea is that 'hp_codes' will populate based on what is selected in 'hazards'.

So in theory someone could select hazard1, hazard2, and hazard3 and then the second list will churn out the options linked to those 3 hazards (some options may be the same - duplicates to be removed).

I'm a bit of a newby to this, hence throwing a net out, so I'd any suggestions are absolutely appreciated.

So far, I've tried the solution on this question(Bootstrap multiselect dynamic options based on first dropdown) to no avail (I typed all the options in to stop the page from pulling the hp_codes from the DB. Having the ability to keep these being pulled from the DB would be really helpful for updates in the future from a maintenance page point of view.

What would be the best way to achieve this?

Edit Here is a snippet of what currently sits in my form. To pull the data in to the multiselect from the DB

// Method to bind Dropdown
function fill_hazards_select_box($con)
{ 
 $output = '';
 $query=mysqli_query($con,"SELECT hazards FROM Chemilist_states");
    $cnt=1;
    while($row=mysqli_fetch_array($query))
    {
    $output .= "<option value='$row[0]'> $row[0] </option>";
    }

 return $output;
}

function fill_hp_codes_select_box($con)
{ 
 $output = '';
 $query=mysqli_query($con,"SELECT hp_codes FROM Chemilist_hazards");
    $cnt=1;
    while($row=mysqli_fetch_array($query))
    {
    $output .= "<option value='$row[0]'> $row[0] </option>";
    }

 return $output;
}

$month = date('m');
$day = date('d');
$year = date('Y');

$today = $year . '-' . $month . '-' . $day;
?>

Then to initialise the plugins

    <script>
        $(document).ready(function() {
            $('#hazards').multiselect({
                maxHeight: 300,
                buttonWidth: '505px',
                dropRight: true,
                nonSelectedText: 'Select Hazard Statement(s)',
                includeResetOption: true,
                includeResetDivider: true,              
                enableFiltering: true,
                includeFilterClearBtn: true,
                enableCaseInsensitiveFiltering: true,
            });
        });
    </script>

        <!-- Initialize the plugin: -->
    <script>
        $(document).ready(function() {
            $('#hp_codes').multiselect({
                maxHeight: 300,
                buttonWidth: '505px',
                dropRight: true,
                nonSelectedText: 'Select Hazard Properties',
                includeResetOption: true,
                includeResetDivider: true,              
                enableFiltering: true,
                includeFilterClearBtn: true,
                enableCaseInsensitiveFiltering: true,
            });
        });
    </script>   

and finally to put the mutliselect within the form

    <div >
    <label>Hazard Statements: <span >*</span></label><br>

                                                                            <!-- Build your select: -->
    <select id="hazards" name="hazards[]"    multiple="multiple" required>
    <?php echo fill_hazards_select_box($con);?> 
        </select>   
                                                                            </div>

                                                                        <div >

    <label>Hazard Properties: <span >*</span></label><br>

                                                                            <!-- Build your select: -->
    <select id="hp_codes" name="hp_codes[]"    multiple="multiple" required>
    <?php echo fill_hazards_select_box($con);?> 
    </select>   
                                                                            </div>

CodePudding user response:

First you need a change handler on the initial select. Then you need to aggregate the selected options via a loop. Then you ship that input off to some ajax or other function to get the codes, which are then added into the other multi select. There are many ways to accomplish all these, here is one of them. I didn't see a jQuery tag on your post, so this is all vanillaJS, but easily transferred to jQuery if desired.

window.addEventListener('DOMContentLoaded', () => {
  let hprops = document.querySelector('#hp_codes')
  document.querySelector('#hazards').addEventListener('change', e => {
    let options = e.target.options;
    let hazards = [];
    for (var i = 0, l = options.length; i < l; i  ) {
      if (options[i].selected) {
        hazards.push(options[i].value);
      }
    }

    hprops.innerHTML = '';
    hprops.setAttribute('disabled', true); // disable until we get the data in there
    // ajax to get actual data ...
    let results = []
    if (hazards.includes('1')) results.push('AAA')
    if (hazards.includes('2')) results.push('BBB')
    if (hazards.includes('3')) results.push('CCC')

    results.forEach(r => hprops.innerHTML  = `<option value='${r}'>${r}</option?`)
    hprops.removeAttribute('disabled');

  })
})
<div >
  <select id="hazards" name="hazards[]"  multiple="multiple" required>
    <option value='1'>Oil slick</option>
    <option value='2'>Moose crossing</option>
    <option value='3'>Pothole</option>
  </select>
</div>

<div >

  <label>Hazard Properties: <span >*</span></label><br>

  <!-- Build your select: -->
  <select id="hp_codes" name="hp_codes[]"  multiple="multiple" required>

  </select>

  • Related