How can I use QuickForm to add disabled select options?

Chuck picture Chuck · Jan 26, 2010 · Viewed 9.6k times · Source

I have code using QuickForm that creates a select widget with the following:

$form->addElement( 'select', 'state_id', 'State:', statesArray() );

statesArray() queries the database to get the states available and returns an associative array with the ids linked to the state names. I'm using a similar technique throughout the solution.

What I'd like to do is prepend this array with two options that are disabled, so that by default the select menu says something like "Please select a state" followed by a dash, both of which are disabled. If I weren't using QuickForm, the select would have the following as the first two options:

  <option value="" disabled="disabled">Select a State</option>
  <option value="" disabled="disabled">-</option>

Both options are disabled, and if the user leaves the option on the first value, the select widget submits an empty value which is made invalid by the form checking code.

Is there a way to do this with QuickForm?

Thanks, Chuck

Answer

Chuck picture Chuck · Jan 27, 2010

OK, after digging much deeper into the QuickForm documentation, I figured this out. The solution is to not populate the select widget with an array, but to build the select element manually add this to the form.

Originally, I had this:

function dbArray( $tableName, $fieldName ) {
    $query = <<< EOT
SELECT   `id`, `$fieldName`
FROM     `$tableName`
ORDER BY `$fieldName`
EOT;

    $link = connectToDatabase();
    $result = mysql_query( $query, $link );
    while ( $rec = mysql_fetch_assoc( $result ) );
    {
        $array[$rec['id']] = $rec[$fieldName];
    }

    return $array;
}

function statesArray() {
    return dbArray( 'states', 'name' );
}

$form = new HTML_QuickForm( 'account', 'POST' );
$form->addElement( 'select', 'state_id', 'State:', statesArray() );

I did a version where array( 'none' => 'Please select a State' ) was prepended to the dbArray call before returning the array to the calling code, but this didn't make the option disabled. Adding a rule to confirm that the choice is numeric was the workaround ($form->addRule( 'state_id', 'You must select a state.', 'numeric' )). But I still didn't like that it was selectable. Here's the solution I found.

function statesSelect() {
    $select = HTML_QuickForm::createElement( 'select' );
    $select->addOption( 'Select a State', '', array( 'disabled' => 'disabled' ) );
    $select->addOption( '-', '', array( 'disabled' => 'disabled' ) );

    $statesArray = dbArray( 'states', 'name' );
    foreach ( $statesArray as $id => $name ) {
        $select->addOption( $name, $id );
    }

    return $select;
}

$form = new HTML_QuickForm( 'account', 'POST' );
$form->addElement( statesSelect() );
$form->addRule( 'state_id', 'You must select a state.', 'required' );

I hope this helps someone else. :)