Search code examples
phparrayshtml-selectpopulate

Modify function which dynamically populates select elements to use arrays from db


I'm trying to modify a function that I've been using to dynamically populate <select> element to use arrays from a database. The original function used hard-coded arrays to populate the elements, and pre-selected the option which matched the db value.

The revised function creates the element, but it's only adding the first value from the db. How can I modify it so that it will loop through all the values that should be added to the <select> element?

PHP Function and Query

<?php
function printSelectOptions($dataArray, $currentSelection) {
    foreach ($dataArray as $key => $value) {
        echo '<option ' . (($key == $currentSelection)) . ' value="' . $key . '">' . $value . '</option>';
    }
}
try {  
    $stmt = $conn->prepare("SELECT * FROM student");  
    $stmt->execute();
    }catch(PDOException $e) {
    echo $e->getMessage();
} 
$row = $stmt->fetch();
?>

Populate Select Element

<select name="fname">
    <?php
        echo printSelectOptions(array($row['fname'])); 
    ?>
</select>

The Original Function & Code for Populating an Element

function printSelectOptions($dataArray, $currentSelection) {
    foreach ($dataArray as $key => $value) {
        echo '<option ' . (($key == $currentSelection) ? 'selected="selected"' : '') . ' value="' . $key . '">' . $value . '</option>';
    }
}

<select name="fname">
    <?php
        $options = array("John"=>"John", "Mary"=>"Mary", "Elizabeth"=>"Elizabeth");
        $selected = $row['fname'];
        echo printSelectOptions($options, $selected); 
    ?>
</select>

Solution

  • Since you have only fetched a single row via fetch(), only a single value is getting passed into your function printSelectOptions(). Instead, get all rows via fetchAll() and modify your function to receive the full array, plus a string which is the column name (array key) you want to print from.

    // All rows into $rows...
    $rows = $stmt->fetchAll();
    
    // Make the function accept the full 2D array, and 
    // a string key which is the field name to list out:
    function printSelectOptions($dataArray, $currentSelection, $fieldname) {
        // String to hold output
        $output = '';
        foreach ($dataArray as $key => $value) {
            // Rather than echo here, accumulate each option into the $output string
            // Use the $fieldname as a key to $value which is now an array...
            $output .= '<option ' . (($key == $currentSelection)) . ' value="' . $key . '">' . htmlspecialchars($value[$fieldname], ENT_QUOTES) . '</option>';
        }
        return $output;
    }
    

    Then call the function as:

    echo printSelectOptions($rows, $currentSelection, 'fname');
    

    The way it is right now, the option's value attribute is populated by the array key, which would be numbered from zero. That's similar to your original array version, but it might be more useful to specify another column name like id as the key column.

    // This one also takes a $valuename to use in place of $key...
    function printSelectOptions($dataArray, $currentSelection, $valuename, $fieldname) {
        // String to hold output
        $output = '';
        foreach ($dataArray as $key => $value) {
            // Rather than echo here, accumulate each option into the $output string
            // Use the $fieldname as a key to $value which is now an array...
            $output .= '<option ' . (($value[$valuename] == $currentSelection)) . ' value="' . $value[$valuename] . '">' . htmlspecialchars($value[$fieldname], ENT_QUOTES) . '</option>';
        }
        return $output;
    }
    

    And would be called as:

        echo printSelectOptions($rows, $currentSelection, 'id', 'fname');