ZF-2942: decorator that draws the form as table with labels in header row

Description

It would be nice to have a standard decorator that draws the form as a table with the labels in a header row of the table. This is for forms that has several of the same input fields.

For example, say you have the following input fields (each rendering as a text box): user1-name user1-pass user2-name user2-pass user3-name user3-pass etc.

If you have such a form, it may make sense to have the labels displayed in a header row instead of a label for each and every input field. Right now, it seems that it would be easier for me to rewrite my form without Zend_Form to accomplish this than to figure out how to deal with it using Zend_Form, but maybe it's just me who's tiring a little from reading so many docs and APIs for the framework who's not seeing a simple solution yet.. :-)

So instead of:


User 1 - name:
User 1 - pass:
User 2 - name:
User 2 - pass:
User 3 - name:
User 3 - pass:

you'd have:


User    Name    Pass
1       
2       
3       

This is only a very simple example of course. If you have, say, 10 input fields (name, password, address...) duplicated for 5 instances (eg. users), it could be a lot more useful to put it in a table like this than to have each field on its own line.

Comments

I ended up writing this myself after all. I've attached the decorator class I wrote.

Example usage:


require_once 'Zend/Form.php';
require_once 'Zend/Form/SubForm.php';
require_once 'Zend/View.php';
$view = new Zend_View;

$form = new Zend_Form(array(
    'action' => '#',
    'method' => 'post',
    'elements' => array(
        'department' => array('text', array('label' => 'Department')),
        'manager' => array('text', array('label' => 'Manager')),
        'submit' => 'submit'
    ),
    'ElementsBelongTo' => 'employees'
));
$form->setView($view);

foreach (range(1, 10) as $key)
{
    $id = new Zend_Form_SubForm(array(
        'elements' => array(
            'number' => array('text', array('label' => 'Employee #', 'value' => $key)),
        ),
    ));
    
    $id->addSubForm(new Zend_Form_SubForm(array(
        'elements' => array(
            'street' => array('text', array('label' => 'Street address')),
            'city' => array('text', array('label' => 'City')),
            'areacode' => array('text', array('label' => 'Area code/zip')),
        )
    )), 'address');
    
    $id->addSubForm(new Zend_Form_SubForm(array(
        'elements' => array(
            'home' => array('text', array('label' => 'Home #', 'validators' => array('int'))),
            'mobile' => array('text', array('label' => 'Mobile #', 'validators' => array('int'))),
            'office' => array('text', array('label' => 'Office #', 'validators' => array('int'))),
        )
    )), 'telephone');
    
    $form->addSubForm($id, $key);
}

$form->setDecorators(array(
    'FormElements',
    array('Table', array('doNotSetDecorators' => false)), # this is the one
    'Form'
    ));

if (!empty($_POST) && $form->isValid($_POST))
{
    # ...
}

echo $form;

Please categorize/fix as needed.

Scheduling for next minor release.

Great feature, just used it.

Please add it to the release... seems to be forgotten. ?!?

Is it possible that you mixed up PREPEND and APPEND?

<?php case self::PREPEND: return $output . $this->_buildTable($form); case self::APPEND: default: return $this->_buildTable($form) . $output; ?>

I think it should be the other way around?

Corrected the following issues in the given file:

  • Correct positioning of table regarding to Order-Number
  • Added class to table heads to identify which field they are belonging to
  • Used Errors-Decorator to format error messages within the table.

it seems my submit button is appearing before the table which is odd.

really useful feature though, can this be added to the next release?

Did you use my (5kb) Version? This should fix it, else please tell me what is wrong or post the code to fix it please.

Of course I didn't put much time in there so please check everything again before putting it into the next release or rewrite it completely for production use.

Furthermore, try to use the "setOrder" - Function to explicitly set the order of the elements. It might help.

Julian it seems that elements only show up if they have an order attribute.

Could you perhaps fix it and upload your solution?

This is not my task to be exactly, I also only needed the table functionality and so added a bit of code to make it better, as you can see above.

Perhaps you could do the same?