You are here:Home arrow Home arrow PHP arrow Database aware Select elements for Zend_Form (or Extending Zend_Form_Element_Multi)
  • Narrow screen resolution
  • Wide screen resolution
  • Decrease font size
  • Default font size
  • Increase font size
  • default color
  • green color
  • blue color

Database aware Select elements for Zend_Form (or Extending Zend_Form_Element_Multi)

Monday, 09 February 2009

In this article, you will know how you can extend select form element that comes with Zend Framework, to be easily filled with data from your database table. We want to be able to easily fill select elements from database table with less repetitive code. It's already easy to fill select elements with database data out of the box:

$db = Zend_Db_Table_Abstract::getDefaultAdapter();
$options = $db->fetchPairs(
   $db->select()->from('table_name', array('id', 'display_field'))
     ->order('some_field ASC'), 'id');
$form->getElement('someelement')->AddMultiOptions($options);

In the snippet above you get default database adapter, then simply fetch all items from 'table_name' ordering by 'some_field', and you see we fetch them as pairs binding to 'id' field. This basically means that the result of fetchPairs returns associative array of items. For select control options, we just want two fields: one for the display and one for the values ('id' is the value field, 'display_field' is for display)

But what if you have many database aware select controls? How is it possible to extend Zend Framework select elements with an easy method to populate data from database table?

Read on for details.

Our goal this time is being able to:

$form->getElement('someelement')->dbAddMultiOptions('table_name',array('id','display_field'));

Let's create the proper directory structure first. We should be extending Zend_Form_Element_Multi which is an ancestor class for all form elements that have multiple options.

Our directory structure should look as below:

 - library
     - Zend
     - Smartycode
       - Form
         - Element
           Multi.php
           Dbselect.php
Below are contents of Multi.php <?php
/**
 * Extends Multi element from Zend Framework with some useful DB related methods
 * @author Danila V. (www.smartycode.com)
 */

abstract class Smartycode_Form_Element_Multi extends Zend_Form_Element_Multi
{
  /**
   * Adds multiple options from a database table
   *
   * @param Zend_Db_Table_Abstract|string $table Table to get values from
   * @param array $cols Columns to select. Order is important. First column is what we bind to
   * @return string Optional where selector
   */

  public function dbAddMultiOptions($table, $cols, $where = null) {
    // Get default database adapter
    $db = Zend_Db_Table_Abstract::getDefaultAdapter();
    if($table instanceof Zend_Db_Table) $table = $table->info('NAME');
   
    $select = $db->select()->from($table, $cols);
        if($where) $select->where($db->quoteInto($where[0], $where[1]));

    $options = $db->fetchPairs($select, $cols[0]);
    return parent::addMultiOptions($options);
  }
}

As you can see, we introduce just one new function to multi elements. It allows to add multiple options at once by fetching all rows from $table (which can be either a string specifying database name or instance of Zend_Db_Table), two columns where first column is the value column and second is for display, and additional $where selector, which is array to be quoted by database adapter, i.e. array ('selector_field > ?', 20);

Next, let's create out DB aware select element (Dbselect.php). This is really mostly a copy paste from ZF's class with only one difference: it extends our multi abstract element <?php
/**
* @author Danila V. (www.smartycode.com)
*/

class Smartycode_Form_Element_Dbselect extends Smartycode_Form_Element_Multi
{
    /**
     * Use formSelect view helper by default
     * @var string
     */

    public $helper = 'formSelect';
}

You can easily extend radio buttons with dbAddMultiOptions by extending it from Smartycode_Form_Element_Multi as above.

Now onto usage examples. You can create instance of db aware select element by specifying it in form's constructor, or manually creating instance of Smartycode_Form_Element_Dbselect:

    $form = new Zend_Form ( array (
      'method' => 'post',
      'elements' => array (
        'email' => array ('text', array (
            'required' => true,
            ))
        ),
        'states' => array ('dbselect',
          array ('required' => true))
      )
    ));
Example of filling with data from DB: $form->getElement('states')->dbAddMultiOptions('State', array('id', 'name')); $form->getElement('states')->dbAddMultiOptions('State', array('id', 'name'),
   array('country LIKE ?', 'Russia'));
$states = new States(); // Zend_Db_Table instance
$form->getElement('states')->dbAddMultiOptions($states, array('id', 'name'));
Comments? Questions? Send them to master at smartycode (or Danilka on #zftalk)




Reddit!Del.icio.us!Facebook!Slashdot!Netscape!Technorati!StumbleUpon!
Last Updated ( Sunday, 03 October 2010 )

Add comment


Security code
Refresh

Next >