Select Dropdown PHP foreach loop with 'optgroup' options

17,781

Solution 1

Try

<select name="backgroundList" id="backgroundList">
<?php
$album_type = '';
foreach ($albums as $album) {
  if ($album_type != $album['type']) {
    if ($album_type != '') {
      echo '</optgroup>';
    }
    echo '<optgroup label="'.ucfirst($album['type']).' Backgrounds">';
  }
  echo '<option value="'.$album['id'].'">'.htmlspecialchars($album['title']).'</option>';
  $album_type = $album['type'];    
}
if ($album_type != '') {
  echo '</optgroup>';
}
?>
</select>

Solution 2

After searching for loads of various posts online...then a great deal of trial and error, I finally found an optgroup solution that worked great.

This code is fairly similar to tagrin0, but I thought I'd provide this with a bit more comments to help the other noobs that might be wanting a clear picture of how to make this work without much fudging and interpretation with the code.

Hope it helps someone.

Here's the table structure...

opt_id | grp_id | optName | grpName | optAbbrv...

echo '<select id="xxx" class="xxx"> select">';
echo '<option >Select an instance...</option>';

$dbc = mysqli_connect('localhost','xxx','xxx','xxx') or die('Error connecting to MySQL server.');

// run your query, something like
// "SELECT <optgroup>_ID, <option>_ID, <optgroup>_Name, <ption>_Name FROM [mysql table this data is stored in] ORDER BY groupID, optionID"

$select = "SELECT * FROM ci_opt ORDER BY grp_id, opt_id";

    $data  = @mysqli_query($dbc, $select) or die(mysql_error());

    // <optgroup> of the previous <option>
    $previous = "";

    // variable to set the first group
    $first_group = true;

    while($row = mysqli_fetch_array($data)) {

        // if this <option> changed <optgroup> from the previous one,
        // then add a new <optgroup>
        if ($row['grpName'] != $previous) {
            if (!$first_group) {
                echo '</optgroup>';
            } else {
                $first_group = false;
            }
            echo '<optgroup label="' . $row['grpName'] . '">';
            $previous = $row['grpName'];
        }

        // echo the current <option>
        // Note: I've also prepared the [onclick] for linking the select to an event

        echo '<option id="'. $row['optAbbrv'] .'" onclick="javascript:void()">' . ucwords($row['optName']) . '</option>';

    }
    // close the last <optgroup> tag
    echo '</optgroup>';
    // close the last <select> tag
    echo '</select>';
    // close the connection
    mysqli_close($dbc);

// end php

Share:
17,781
Chris
Author by

Chris

Updated on June 26, 2022

Comments

  • Chris
    Chris about 2 years

    I have a dropdown menu with a PHP 'foreach' that I loop through to populate the select options. This works well. However, what I'd like to do is have various sub labels using the "optgroup" option. In my returned array, I have a "type" of "blue", "green" and "red". How can I split the select options up into groups based on the $album['type']?

    This is the code I have:

    $query = mysql_query("SELECT * FROM background_albums);
    $albums = array();
    while($row = mysql_fetch_assoc($query)) {
        array_push($albums, $row);
    }
    
    <select name="backgroundList" id="backgroundList">
      <? foreach($albums as $album) { ?>
        <option value="<?=($row['id']);?>"><?=$row['title'];?></option>
      <? } ?>
    </select>
    

    This is the kind of thing I'd like to achieve within the foreach loop:

    if ($album['type'] == 'green')...
    
    <optgroup label="Green Backgrounds">
          <option>1</option>
          <option>2</option>
          <option>3</option>
          <option>4</option>
    </optgroup>
    
    if ($album['type'] == 'blue')...
    
    <optgroup label="Blue Backgrounds">
          <option>5</option>
          <option>6</option>
          <option>7</option>
          <option>8</option>
    </optgroup>
    
  • mickmackusa
    mickmackusa almost 3 years
    This answer is missing its educational explanation.