Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

PHP

Bill Dowd
Bill Dowd
7,681 Points

How to re-select a multi-select drop-down form field from a database.

I have a drop-down field for the days of the week. The value under each listed day of the week (1 = Monday, 2 = Tuesday, etc.). This/these values, 1 through 7, of the selected days, are stored in a DB table field. I am struggling with how to reselect the days when I need to edit the record. If they're not selecting, then when I update other fields in the record and save it, I'll lose the day selection unless I remember to reselect them and remember what those days were for that record.

Here is a portion of the code that doesn't work:

        $form = "<select name='payment_days[] multiple'>\n";
        $form .= "\t<option value='-'>---</option>\n";
        $form .= "\t<option value='1' " . ($this->payment_days == '1' ? 'SELECTED' : '') . ">Monday</option>\n";
        $form .= "\t<option value='2' " . ($this->payment_days == '2' ? 'SELECTED' : '') . ">Tuesday</option>\n";
        $form .= "\t<option value='3' " . ($this->payment_days == '3' ? 'SELECTED' : '') . ">Wednesday</option>\n";
        $form .= "\t<option value='4' " . ($this->payment_days == '4' ? 'SELECTED' : '') . ">Thursday</option>\n";
        $form .= "\t<option value='5' " . ($this->payment_days == '5' ? 'SELECTED' : '') . ">Friday</option>\n";
        $form .= "\t<option value='6' " . ($this->payment_days == '6' ? 'SELECTED' : '') . ">Saturday</option>\n";
        $form .= "\t<option value='7' " . ($this->payment_days == '7' ? 'SELECTED' : '') . ">Sunday</option>\n";
        $form .= "</select>\n";

        return $form;

3 Answers

Bill Dowd
Bill Dowd
7,681 Points

I brain is hurting, but I figured out how to do it. This is the function in my class file that builds the form drop-down field.

public function GetPaymentDayChoices() {
    $dayarray = explode(',', $this->payment_days);
    $form = "<select name='payment_days[]' multiple size='5'>\n";
    $form .= "\t<option value='-'>---</option>\n";
    $dayselect = array();
    // Create an array representing each day of the week with the value "Selected" for each match
    for($i = 1 ; $i <= 7 ; $i++) {
        foreach($dayarray as $value) {
            if(count($dayselect) == $i) { // Check to see if that day of the week has been added
                continue;
            } elseif($value == $i) { // If there is a match from the DB then add
                $dayselect[$i] = 'SELECTED';
            }
        }
        if(count($dayselect) < $i) { // If there was no match from the DB after all the iterations, add a blank
                $dayselect[$i] = '';
            }
    }
    $form .= "\t<option value='1' " . $dayselect[1] . ">Monday</option>\n";
    $form .= "\t<option value='2' " . $dayselect[2] . ">Tuesday</option>\n";
    $form .= "\t<option value='3' " . $dayselect[3] . ">Wednesday</option>\n";
    $form .= "\t<option value='4' " . $dayselect[4] . ">Thursday</option>\n";
    $form .= "\t<option value='5' " . $dayselect[5] . ">Friday</option>\n";
    $form .= "\t<option value='6' " . $dayselect[6] . ">Saturday</option>\n";
    $form .= "\t<option value='7' " . $dayselect[7] . ">Sunday</option>\n";
    $form .= "</select>\n";

    return $form;
}
Tom Sager
Tom Sager
18,987 Points

I am not sure that I understand your question - you only want to update certain fields in a DB record without changing the other fields? If so, this is handled by the database. For MySQL, it might look like this

$sql = "UPDATE table_name SET name_of_field_to_change='new value' WHERE id=3"

Any fields in record 3 that are not in the SET list are not changed.

Is this close to what you are trying to do?

Bill Dowd
Bill Dowd
7,681 Points

Thanks Tom. Not exactly. I'm pulling up the complete record for a person so the user can edit any field they want to. So when the record is placed into a form, the fields need to be filled out with what was in the DB. The hard part is making sure drop-downs are preserved and the hardest one I've had to do is the days of the week multi-select, because it's a multi-select. Those selections need to show and be maintained when the user updates the record as most of the time they may only be changing one or two fields. I hope that helps you. I solved the problem, finally, below.

Tom Sager
Tom Sager
18,987 Points

It makes my head hurt too! I think you can simplify your logic if you use an associative array.

public function GetPaymentDayChoices() {
    $daysofweek = array(
        1 => "Monday",
        2 => "Tuesday",
        3 => "Wednesday",
        4 => "Thursday",
        5 => "Friday",
        6 => "Saturday",
        7 => "Sunday"
        );

    $form = "<select name='payment_days[]' multiple size='5'>\n";
    $form .= "\t<option value='-'>---</option>\n";

    $mydays = explode(',', $this->payment_days);

    foreach ($daysofweek as $key => $day) {
        $selected = array_key_exists($key, $mydays) ? "SELECTED" : "";
        $form .= "\t<option value='" . $key . "' " . $selected . ">" . $day . "</option>\n";
    }
    return $form;
}

I don't have a PHP interpreter handy, so this code may not parse correctly. But it should give you an alternate approach. On each loop iteration, $selected is set either to the day, e.g. "Tuesday" or to a blank string.

Happy coding!

Bill Dowd
Bill Dowd
7,681 Points

I think you're on to something. I'll give this a try and see if I can make it work.

Thanks, Tom.

Bill Dowd
Bill Dowd
7,681 Points

It doesn't work exactly right. It only highlighted the first two days and it should have highlighted days 1,3,5 as stored in the DB. However, still think you're on to something easier, so I'll play some with it to see if I can make it work.