I\'ve read the manual many times, I\'ve scoured the posts offered by Google on the subject, I have even bought a couple of books that deal with ZF. Now, why am I still confused?
You probably have solved this by now, but I've been doing some work and needed a similar solution.
form->getSubform('subform'); foreach ($subform as $key => $value) { //some markup and custom code here print $value; //some markup and custom code here } ?>
within the foreach loop, you can add table markup. If you've named your keys for your table rows appropriately, they should match up with the form keys. You could even use a loop that grabs the appropriate subform by key, or even an element by a key. you could skip the foreach loop if you know the keys, and simply say print $subform['somekey']; assuming you set the main form by saying $form->setIsArray(true); (not sure if that last part is strictly necessary, but for complicated forms, it should be set like that anyway.
I removed the default decorators so I could have complete control of printing within each element. Zend_Form ought to have a built-in method for grabbing individual elements a little more easily.. but I think this works pretty well.
Hope that's helpful to someone!
Render each element individually in your view - for example
<!-- view script here -->
<form method="POST">
Name: <?php echo $this->myForm->getElement('name')->render(); ?>
some other text between the fields
Birthdate: <?php echo $this->myForm->getElement('birthdate')->render(); ?>
<input type="submit" />
</form>
This maintains the ability to use the Zend_Form view helpers (i.e. to display error messages and maintain the values of the form fields when validation fails) but gives you full customization ability.
If you want to go further, then turn off the default decorators of the individual form elements and then either attach your own to further customize exactly what tags are used (i.e. for error messages and labels) or don't use decorators at all (other than to render the form element itself) and then write all the surrounding HTML manually. Complete customization ability without losing the benefits of Zend_Form, both at the form level and at the view level.
Matthew Weier O'Phinney has started a series of blog posts about Zend_Form decorators:
If you just want to add arbitrary markup before or after your form elements without using the ViewScript decorator, you could use my AnyMarkup decorator: http://www.zfsnippets.com/snippets/view/id/62
For example, here is how you would prepend an input field with an image inside a wrapper tag (needs include paths for autoloading to be set correctly):
$form->addElement('text', 'my_field', array( 'label' => 'Enter Info:', 'decorators' => array( 'ViewHelper', array('AnyMarkup', array( 'markup' => '<span class="imgwrapper">'. '<img src="info.png" alt="info icon"/></span>'), 'placement' => 'prepend' ), 'HtmlTag', 'Label' ) );
whycantitbemorethan25c mentioned them above, but ViewScripts give you extremely fine-grained control for rendering forms. Zend_Form is meant to be fast and so it assumes many defaults like standard decorators and orders the element the way they were added to the form object. With the ViewScript you can skip much of that that and place all of your elements however you would like within normal HTML.
Don't skip over the concept of Decorators entirely though. They style the individual elements even if they are used in a ViewScript later. For example, you can use them for error messages as others have suggested.
If you have very complicated form that has multiple data points with similar actions (think of a list of users with active/inactive buttons and a delete button for each) you should consider Zend_Form_SubForm. The subforms can utilize the ViewScripts just like normal forms and if you cascade a form with a ViewScript with subforms with their own ViewScripts you end up with nicely contained logic and presentation that is much more powerful than just a straight form.
I wrote some sub-classes to Zend_Form and the decorators to make it layout the form in a <table>. It even had some special tricks to do things like make multiple submit buttons show on the same row.
Took a full day of hacking around to get it working. It was written against Zend 1.5.1 so don't know if it will work with the current version, but if you are interested I could probably upload the source somewhere.
This seems to be a very common complaint with Zend Forms.
(I know I'll get poo-poo'd by the CSS purists over using tables to layout forms, and while I agree that CSS is better for most things, I have yet to see good form layout using CSS that doesn't look like a butt-ugly kludge. With tables the forms 'just work' pretty much on every browser I need them to.)
EDIT: Okay, speaking of butt-ugly kludges, I've put my code for producing tabular zend forms in github. Go here to see it. (Because gaoshan88 asked for it.)