understanding grid layout in zend - zend-framework

I'm a bit confused with designing forms in zend.
I understood that I have the fields in my form class and the look should be done in the views.
In the index view which is nearly plain html I don't have problems, but in the add and edit views which show my form I have problems to change the look.
I have a viewscript like follows:
<?php
$title = 'AVB ändern';
$this->headTitle($title);
?>
<h1><?= $this->escapeHtml($title) ?></h1>
<?php
$id= $form->get('id');
$id->setAttribute('class', 'form-control');
$id->setAttribute('placeholder', 'id');
$avbname= $form->get('avbname');
$avbname->setAttribute('class', 'form-control');
$avbname->setAttribute('placeholder', 'avbname');
$vbedingungen= $form->get('vbedingungen');
$vbedingungen->setAttribute('class', 'form-control');
$vbedingungen->setAttribute('placeholder', 'vbedingungen');
$versichererid= $form->get('versichererid');
$versichererid->setAttribute('class', 'form-control');
$versichererid->setAttribute('placeholder', 'versichererid');
$aktiv= $form->get('aktiv');
$aktiv->setAttribute('class', 'form-control');
$aktiv->setAttribute('placeholder', 'aktiv');
$submit = $form->get('submit');
$submit->setAttribute('class', 'btn btn-primary');
$form->prepare();
echo $this->form()->openTag($form);
?>
<div class="form-group">
<?= $this->formElement($id) ?>
<?= $this->formElementErrors()->render($id, ['class' => 'help-block']) ?>
</div>
<div class="form-group">
<?= $this->formLabel($avbname) ?>
<?= $this->formElement($avbname) ?>
<?= $this->formElementErrors()->render($avbname, ['class' => 'help-block']) ?>
</div>
<div class="form-group">
<?= $this->formLabel($vbedingungen) ?>
<?= $this->formElement($vbedingungen) ?>
<?= $this->formElementErrors()->render($vbedingungen, ['class' => 'help-block']) ?>
</div>
<div class="form-group">
<?= $this->formLabel($versichererid) ?>
<?= $this->formElement($versichererid) ?>
<?= $this->formElementErrors()->render($versichererid, ['class' => 'help-block']) ?>
</div>
<div class="form-group">
<?= $this->formLabel($aktiv) ?>
<?= $this->formElement($aktiv) ?>
<?= $this->formElementErrors()->render($aktiv, s['class' => 'help-block']) ?>
</div>
<?php
echo $this->formSubmit($submit);
echo $this->formHidden($form->get('id'));
$form->setAttribute('action', $this->url('typavb', ['action' => 'edit']));
echo $this->form()->closeTag();
Of course it shows one field beneath the other.
How can I show two fields in a row (with the labels) ?
I really would appreciate an example or a tip to a good tutorial, which shows how to do it properly with this zend3 concept.
Is it even the right place to do it in the view or do I need a new layout.phtml for this case?

To print parts of Elements separately, there's several functions pre-defined in ZF. You can find all of them in \Zend\Form\ConfigProvider->getViewHelperConfig(), see here on Github.
In your case, your already using formLabel, formElement and formElementErrors.
These are handy for separte use if you have something like Currency, where you'd like a user to both fill in an amount and choose a currency but only use a single label, e.g.:
$this->formLabel($form->get('amount'));
$this->formElement($form->get('amount'));
$this->formElementErrors($form->get('amount'));
$this->formElement($form->get('currency'));
$this->formElementErrors($form->get('currency'));
An entire "form row" is made up out of:
A label (optional)
Element
ElementErrors (if present after server-side validation)
So, as in this example you need the entire "amount" bit, you could shorten the above to:
$this->formRow($form->get('amount')); // prints all elements for the row
$this->formElement($form->get('currency'));
$this->formElementErrors($form->get('currency'));
If you look closely through the linked ConfigProvider of 'zendframework/zend-form', you might've noticed there's also a form ViewHelper. This can be used to print an entire form in a single go, like so:
file: add-foo.phtml
<?= $this->form($form) ?>
And that's it. It prints the whole form. Of course it uses the ZF defined ViewHelpers, as such also with that layout and classes applied.
If you wish, can take that config and override it in your own projects.
For example, your question code shows you add <div class="form-group"></div> around each row. Presumably for Bootstrap 4. To do this magically so you need not do:
<div class="form-group">
<?= $this->formRow($form->get('foo')) ?>
</div>
We can adjust the formRow ViewHelper. Simply follow these steps:
Create a FormRow.php in your own project, e.g. module/Foo/src/View/Helper/FormRow.phtml
Make sure to extend it from ZF's FormRow and copy in the original (ZF) render function, like so:
use Zend\Form\View\Helper\FormRow as ZendFormRow;
class FormRow extends ZendFormRow
{
public function render(ElementInterface $element, $labelPosition = null)
{
// its content
}
}
We want to add a wrapper (form-group class div), so define it in the class, like so:
class FormRow extends ZendFormRow
{
protected $inputRow = '<div class="form-group">%s</div>';
// the other stuff
}
At the bottom of the render function, you'll find the following code (before the else):
if ($this->renderErrors) {
$markup .= $elementErrors;
}
Place after the above:
$markup = sprintf(
$this->inputRow,
$markup,
);
Register your new ViewHelper, using the same aliases as ZF so as to overwrite the values:
'view_helpers' => [
'aliases' => [
'formrow' => FormRow::class,
'form_row' => FormRow::class,
'formRow' => FormRow::class,
'FormRow' => FormRow::class,
],
'factories' => [
FormRow::class => InvokableFactory::class,
],
],
Done.
Now when you do $this->form($form) the FormElement ViewHelper from ZendFramework will receive your custom formRow ViewHelper when it its Factory does ->get('formRow'), as the config is overwritten to your own. As such, all rows will now automagically have the surrounding div.
Bit more than you asked for, but have fun ;) I'm gonna stop avoiding work now O:)

Related

how to show a form in a grid view

I'm trying a bit around with grid views. I show different contents so the user can have something like a dashboard.
Please have a look at the screenshot:
The notizen area should be a search form.
Here part of my controller action:
$view = new ViewModel();
$wiedervorlageView = new ViewModel(['wvs' => $this->wvTable->fetchAll()]);
$wiedervorlageView->setTemplate('layout/template/wiedervorlage');
$notizenView = new ViewModel(['notizen' => $this->notizenTable->fetchAll()]);
$notizenView->setTemplate('layout/template/notizen');
$geburtstageview = new ViewModel();
$geburtstageview->setTemplate('layout/template/geburtstageview');
$sidebarBlockView = new ViewModel(['aps' => $this->ansprechpartnerTable->getGeburtstage()]);
$sidebarBlockView->setTemplate('layout/template/block');
$geburtstageview->addChild($sidebarBlockView, 'block');
$view->addChild($wiedervorlageView, 'wiedervorlage')
->addChild($notizenView, 'notizen')
->addChild($geburtstageview, 'geburtstage');
return $view;
And here the search viewscript:
<?php
$title = 'Suche';
$this->headTitle($title);
?>
<h1><?= $this->escapeHtml($title) ?></h1>
<?php
$suche= $form->get('suche');
$suche->setAttribute('class', 'form-control');
$suche->setAttribute('placeholder', 'suche');
$suchtyp= $form->get('suchtyp');
$suchtyp->setAttribute('class', 'form-control');
$suchtyp->setAttribute('placeholder', 'suchtyp');
$submit = $form->get('submit');
$submit->setAttribute('class', 'btn btn-primary');
$form->prepare();
echo $this->form()->openTag($form);
?>
<div class="form-group">
<?= $this->formLabel($suche) ?>
<?= $this->formElement($suche) ?>
<?= $this->formElementErrors()->render($suche, ['class' => 'help-block']) ?>
</div>
<div class="form-group">
<?= $this->formLabel($suchtyp) ?>
<?= $this->formElement($suchtyp) ?>
<?= $this->formElementErrors()->render($suchtyp, ['class' => 'help-block']) ?>
</div>
<?php
echo $this->formSubmit($submit);
echo $this->form()->closeTag();
My question is how to change the notizen area so that it works with the form?
I tried different possibilities but I came to the conclusion that I didn't understood the logic in this case.
Any help or explanation appreciated.
Solution:
ok I changed to partials, before I wanted to try with the described concept to see the difference to the partials. I worked before with partials,my challenge here was really only the form, now it is clear hopefully. But either way, the concept with the partials is much more convenient and readable.
So, I changed the viewscripts like suggested, here for completion the one with the form:
<div class="row">
<h2> Suche </h2>
<?php
$suche= $form->get('suche');
$suche->setAttribute('class', 'form-control');
$suche->setAttribute('placeholder', 'suche');
$suchtyp= $form->get('suchtyp');
$suchtyp->setAttribute('class', 'form-control');
$suchtyp->setAttribute('placeholder', 'suchtyp');
$submit = $form->get('submit');
$submit->setAttribute('class', 'btn btn-primary');
$form->prepare();
echo $this->form()->openTag($form);
?>
<div class="form-group">
<?= $this->formRow($suche) ?>
<?= $this->formElementErrors()->render($suche, ['class' => 'help-block']) ?>
<?= $this->formRow($suchtyp) ?>
<?= $this->formElementErrors()->render($suchtyp, ['class' => 'help-block']) ?>
<?php
echo $this->formSubmit($submit);
echo $this->form()->closeTag(); ?>
</div>
</div>
As I posted this I thought I would need to redirect to the controller Action with the search script. Now I copied it to the same controller action. So it works and it is ok for me.
Here part of the changed controller action for anybody who has the same understanding issue:
$form = new SearchForm(NULL);
$form->get('submit')->setValue('suche');
return new ViewModel([
'wvs' => $this->wvTable->fetchAll(),
'form' => $form,
'aps' => $this->ansprechpartnerTable->getGeburtstage()
]);
You should really learn to create partials. What you're doing now is mixing concerns.
What you're doing in your controller will give you a giant mess if/when you have to refactor.
With partials you would do something like this.
File: notizen-partial.phtml
<?php
/** #var array $notizen */
?>
<table>
<tr>
<th>datum</th>
<th>text</th>
</tr>
<tr>
<td><?= $notizen['datum'] ?></td>
<td><?= $notizen['text'] ?></td>
</tr>
</table>
So, the above expects a variable $notizen, of type array (hinted in the PHP at the top). You could add some validation that the array is actually present, contains the values, etc. but that's up to you.
Now, register this partial in the configuration of the module, with the following config:
'view_manager' => [
'template_map' => [
'partial/notizen-partial' => __DIR__ . '/../view/partials/notizen-partial.phtml',
],
],
Make sure you correct the path for your situation!!!
Repeat the above for each little "container" of your data handling (wvs, aps, etc.).
Next, have an Action return the data you need to the View:
// ... create/get data
return [
'wvs' => $this->wvTable->fetchAll(),
'notizen' => $this->notizenTable->fetchAll(),
'aps' => $this->ansprechpartnerTable->getGeburtstage(),
];
This goes to "action-view.phtml", or whatever. This file handles the "place data where it needs to be".
The layout of the view, based on your screenshot, would be something like this (I'm going under the assumption your using Bootstrap 4.*):
<div class="row">
<div class="col-12">
<!-- That top row - full width -->
<!-- ## notizen here ## -->
</div>
</div>
<div class="row">
<div class="col-8">
<!-- second row - two thirds of width -->
<!-- Wiedervorlagen here -->
</div>
<div class="col-4">
<!-- second row, second column - one thirds of width -->
<!-- Geburtstage here -->
</div>
</div>
Now, you need to use the additional partials to display the data in the right locations. For example, your 'notizen' data, is now $notizen variable in this view. However, we're not using it in this view, so lets pass it on to the partial we created earlier, like so:
<?= $this->partial('partial/notizen-partial, ['notizen' => $notizen]) ?>
A lot happening here:
Calling the partial ViewHelper (look in the folder of this file to see other ViewHelpers already available!)
Passing it the name of the partial, which we set in the configuration earlier
Passing key/value pairs. The keys will be variable names, the values will be their values (you can add as many as you like/need)
Place this call in your action view, like so:
<div class="row">
<div class="col-12">
<!-- That top row - full width -->
<?= $this->partial('partial/notizen-partial, ['notizen' => $notizen]) ?>
</div>
</div>
And you're done.
You now have:
Single partials to display collections of data
Using ViewHelpers, so you can recycle the same view in different locations throughout your application
Separated concerns of your code (kept displaying in phtml template files, kept data collection / handling in Controller, kept logic in Repositories/Models/Entities)
I've studiously ignored your pasted Form. The principle for that is the same, you could pass the $form in to a partial and have that partial contain the displaying of the form. Creating something re-usable.
If you'd like to know more about customizing Form ViewHelpers (e.g. FormRow, FormElement, FormNumber, etc.), please see answers I've given others, such as this one.

yii2 validate form element from model without using activeform

I want to use the simple form tag & element like
<form name="formname" action="" method="post">
<input type="text" name="title" value="" />
</form>
I want to validate all fields on client side & server side using yii model.
Model validations can easily apply with activeform but i don't want to use activeform.
Any easy way to validate the form fields on client & server both sides?
Use beginForm() method. And try something like below.
use yii\helpers\Html;
<?php $form = Html::beginForm()([
'method' => 'post',
'name' => 'formname',
]); ?>
<?= Html::textarea->textarea(['rows' => 6, 'name'=>'title'])->label(false) ?>
<div class="form-group">
<?= Html::submitButton('POST', ['class' => 'btn btn-primary']) ?>
</div>
<?php Html::endForm() ?>
and then in your model
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
// $model->addRule(['fieldname'], 'string', ['max' => 50]);
}

Zend Framework Custom Forms with viewScript

I am having some problems working out how to use custom forms in Zend Framework.
I have followed various guides but none seem to work. Nothing at all gets rendered.
Here is the bits of code that I am trying to use (All code below is in the default module). I have simplified the code to a single input for the test.
applications/forms/One/Nametest.php
class Application_Form_One_Nametest extends Zend_Form {
public function init() {
$this->setMethod('post');
$name = new Zend_Form_Element_Text('name');
$name->setLabel('Box Name')
->setRequired(true)
->addFilter('StripTags')
->addFilter('StringTrim')
->addValidator('NotEmpty');
$submit = new Zend_Form_Element_Submit('submit');
$submit->setLabel('Submit Message');
$submit->setAttrib('id', 'submitbutton');
$submit->setAttrib('class', 'bluebutton');
$this->addElements(array($name, $submit));
}
}
application/views/scripts/one/formlayout.phtml
<form action="<?= $this->escape($this->form->getAction()) ?>" method="<?= $this->escape($this->form->getMethod()) ?>">
<p>
Please provide us the following information so we can know more about
you.
</p>
<? echo $this->element->name ?>
<? echo $this->element->submit ?>
</form>
application/controllers/IndexController.php
public function formtestAction() {
$form = new Application_Form_One_Nametest();
$form->setDecorators(array(array('ViewScript', array('viewScript' => 'one/formlayout.phtml'))));
$this->view->form = $form;
}
application/views/scripts/index/formtest.phtml
<h1>Formtest</h1>
<?
echo $this->form;
?>
The above code does not throw any errors or render any part of formlayout.phtml including the form tags or text between the p tags.
Can anybody tell me what I might be doing wrong?
I think the problem is your form element's decorator. You should set the decorator to ViewHelper and Error only. It works for me at least.
Here is the code I used and it should work
applications/forms/Form.php
class Application_Form_Form extends Zend_Form {
public function loadDefaultDecorators() {
$this->setDecorators(
array(
array(
'ViewScript',
array(
'viewScript' => 'index/formlayout.phtml',
)
)
)
);
}
public function init() {
$this->setAction('/action');
$this->setMethod('post');
$this->addElement('text', 'name', array(
'decorators' => array('ViewHelper', 'Errors')
));
}
}
application/views/scripts/index/formlayout.phtml
<form action="<?php echo $this->element->getAction(); ?>" method="<?php echo $this->element->getMethod(); ?>">
<div>
<label for="name">Box Name</label>
<?php echo $this->element->name; ?>
</div>
<input type="submit" value="Submit Message" id="submitbutton" class="bluebutton">
</form>
application/views/scripts/index/index.phtml
<!-- application/views/scripts/index/index.phtml -->
<?php echo $this -> form; ?>
application/controllers/IndexController.php
public function indexAction() {
$form = new Application_Form_Form();
$this -> view -> form = $form;
}
Here is a very simple example to get you going adapted from this article.
The form:-
class Application_Form_Test extends Zend_Form
{
public function init()
{
$this->setMethod('POST');
$this->setAction('/');
$text = new Zend_Form_Element_Text('testText');
$submit = new Zend_Form_Element_Submit('submit');
$this->setDecorators(
array(
array('ViewScript', array('viewScript' => '_form_test.phtml'))
)
);
$this->addElements(array($text, $submit));
$this->setElementDecorators(array('ViewHelper'));
}
}
The order in which setDecorators(), addElements() and setElementDecorators() are called is very important here.
The view script _form_test.phtml can be called anything you like, but it needs to be in /views/scripts so that it can be found by the renderer.
/views/scripts/_form_test.phtml would look something like this:-
<form id="contact" action="<?php echo $this->element->getAction(); ?>"
method="<?php echo $this->element->getMethod(); ?>">
<p>
Text<br />
<?php echo $this->element->testText; ?>
</p>
<p>
<?php echo $this->element->submit ?>
</p>
</form>
You instantiate the form, pass it to the view and render it as usual. The output from this example looks like this:-
<form id='contact' action='/' method='post'>
<p>
Text<br />
<input type="text" name="testText" id="testText" value=""></p>
<p>
<input type="submit" name="submit" id="submit" value="submit"></p>
</form>
That should be enough to get you started creating your own forms.
Usually, if you don't see anything on the screen it means that some sort of error happened.
Maybe you have errors turned off or something, maybe not. I'm just trying to give you ideas.
The only things I could spot where the following.
In the below code, you have to still specify the form when trying to print out the elements.
<form>
action="<?php $this->escape($this->element->getAction()) ?>"
method="<?php $this->escape($this->element->getMethod()) ?>" >
<p>
Please provide us the following information so we can know more about
you.
</p>
<?php echo $this->element->getElement( 'name' ); ?>
<?php echo $this->element->getElement( 'submit' ) ?>
</form>
As vascowhite's code shows, once you are inside the viewscript, the variable with the form is called element. The viewscript decorator uses a partial to do the rendering and thus it creates its own scope within the viewscript with different variable names.
So, although in your original view it was called $form, in the viewscript you'll have to call it element.
Also, maybe it was copy/paste haste, but you used <? ?> tags instead of <?= ?> or <?php ?> tags. Maybe that caused some error that is beyond parsing and that's why you got no output.

Using ViewScript Decorator on Nested Subforms (Zend Form)

I want to use a view script to render my zend form as it seems to be the best way to
control the layout/design of the form while still using the Zend_Elements classes.
From the view script, I render the element with $this->element->getElement('elementName') .
I'm having problems with the names of the elements. This is actually a sub-form inside a sub-form inside a form.
When I used the FormElements decorators , the fully qualified name of the elements was form[subForm][subForm][element] , which was good.
Wehn I moved to the viewScript decorators, it changed to subForm[subForm][element].
I understood that I need to use the PrepareElements decorator to fix this, but this caused the name to change form[subForm][form][subForm][subForm][elements] (it doubled the first two names in the start).
Any ideas how I should handle this?
Thanks.
UPDATE: I tried to debug PrepareElements and I really don't understand what is doing.
It seems like it works ok in the first iteration, but then it adds again the form[subform] prefix when running on one of the middle subforms.
When I'm not using the PrepareElements decorator, I'm just missing the "form" prefix in the names (i.e., instead of form[subForm][element], I get only subForm[element]).
May be I can just fix this somehow?
I tried to change the belongsTo but that only replaced the "subForm" prefix .
It actually seems like what is missing is a belongsTo method on the subForm.
Again, this is all because of the ViewScript decorator. It works fine with the FormElements decorators.
UPDATE 2: Just to clarify, I wouldn't mind this name change, but it causes my fields to not populate when I call form->populate .
Edit: I think that I've narrowed the problem to this: when I get my values back in setDefaults, they are ordered like this:
array(
\"formElements1-name\" => value1... \"subFormName\" => array(
\"parentFormName\" => array(
\"subFormName\" => subForm-values-array
)
)
...
The main problem here is the "parentFormName" => "subFormNAme".. what does it repeat itself? I'm already in the main form. I'm guessing this is caused because I've set the setElementsBelongTo(formName[subFormName]) , but if I wouldn't do that, then I would get my subform values completely separate from the form,
i.e.
values array = array(
\"formName\" => array(
formValues
), \"subFormNAme\" => array(
subFormValues
)
, while I exepct it to be
array(
formName => array(
subFormNAme => values-array
)
)...
Is it even possible to make this work?
Are you just trying to output your form using <?php echo $this->form; ?> from your view script?
That works well for simple forms, but for my more complex forms I tend to render each element individually but don't need to use ViewScript decorator on each individual element to do this. Just try something like this from your view script:
<div class="form">
<fieldset>
<legend>Some Form Name</legend>
<form action="<?php echo $this->escape($this->form->getAction()) ?>"
method="<?php echo $this->escape($this->form->getMethod()) ?>"
enctype="multipart/form-data">
<?php echo $this->form->id; // render the id element here ?>
<div class="half">
<?php echo $this->form->name; // render the user name field here ?>
</div>
<div class="half">
<?php echo $this->form->description; // render the description element here ?>
</div>
<div class="clear"></div>
<div class="half">
<?php echo $this->form->address1; // render the address ?>
</div>
<div class="half">
<?php echo $this->form->address2; // render address2 ?>
</div>
<div class="clear"></div>
<div class="third">
<?php echo $this->form->zip; // render zip code ?>
</div>
<div class="third">
<?php echo $this->form->city; // render city ?>
</div>
<div class="third">
<?php echo $this->form->state; // render state ?>
</div>
<div class="clear"></div>
<div class="half">
<?php echo $this->form->country; // render country ?>
</div>
<div class="clear"></div>
<?php echo $this->form->submit; ?>
</form>
</fieldset>
</div>
That is how I do most of my forms because I want to have some elements take up half the width and others the full width.
Surprisingly, the reference guide doesn't tell you that you can do this. I seem to remember a page about it in the past but cannot find it now. When I got started with Zend Framework, I thought the only way I could get my form to output exactly how I wanted was to create complex decorators, but that is not the case.
Matthew Weier O'Phinney has a great blog post on rendering Zend_Form decorators individually which explains what I did above. I hope they add this to the first page of Zend Form because that was discouraging to me at first. The fact is, 90% of my forms render elements individually instead of just echo'ing the form itself.
Note: To stop ZF from enclosing my form elements in the dt and dd tags, I apply this decorator to all of my standard form elements. I have a base form class that I extend all of my forms from so I don't have to repeat this everywhere. This is the decorator for the element so I can use tags to enclose my elements.
public $elementDecorators = array(
'ViewHelper',
'Errors',
array('Description', array('tag' => 'p', 'class' => 'description')),
array('HtmlTag', array('tag' => 'div', 'class' => 'form-div')),
array('Label', array('class' => 'form-label', 'requiredSuffix' => '*'))
);
For my submit buttons I use
public $buttonDecorators = array(
'ViewHelper',
array('HtmlTag', array('tag' => 'div', 'class' => 'form-button'))
);
The current solution is to use the PrepareElements decorator on the subforms with one change - remove the recursive call in the PrepareElements code. Also, no "setElementsBelongTo" is required.
This seem to generate the correct names and ids.
The solution would be to use the belongsTo() form element property.
Example :
new Zend_Form_Element_Text('<elementName>', array('belongsTo' => '<subformName>'))
In this way, the render() method will use a form element name like
name="<subformName>[<elementName>]"
I had the same problem and i solved it with a decorator
1 : Create a generic subform with elements
2 : Using a specific decorator with PrepareElements
3 : Change form to an array with setIsArray(true)
Example :
Form
$i = 4;
for($i = 0; $i < $nbReclam ; $i++)
{
$rowForm = new Zend_Form_SubForm($i);
$name= new Zend_Form_Element_Textarea('name');
$rowForm->addElement($name);
$this->addSubForm($rowForm, $i);
}
$this->setDecorators(array(
'PrepareElements',
array('ViewScript', array('viewScript' => 'myDecorator.phtml')),
));
$this->setIsArray(true);
Decorator
<table>
<thead>
<tr>
<th>N°</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<?php foreach ($this->element->getSubForms() as $subForm) : ?>
<tr>
<td> <?php echo $i++?> </td>
<?php foreach ($subForm->getElements() as $row) : ?>
<td><?php echo $row ?></td>
<?php endforeach ?>
</tr>
<?php endforeach ?>
</tbody>
</table>
Enjoy
Sorry for my english, i am french

select menu default values not rendering in symfony

I am using Symfony 1.4, and am using embedded forms to place multiple similar forms into one form for a configuration page. I am having success showing the form, but the default values of the sfWidgetFormChoice widgets are not being rendered, i.e. the selected="selected" attribute is gone from the HTML.
Incidentally, the default values show up if I don't use embedded forms. The problem with avoiding embedded forms is that each form has identical inputs and therefore overwrites itself.
The action code is as such, some code omitted for brevity:
$serviceFormArray = array();
$this->fullForm = new ConfigForm();
foreach($this->serviceArray as $net => $service)
{
$this->partialForm = new ConfigForm();
foreach($service as $typeId => $val)
{
$typeObj = Doctrine::getTable('Type')->find($typeId);
$typeField = new sfWidgetFormChoice(array(
'default' => $val,
'choices' => array('1' => 'on', '0' => 'off'),
'label' => $typeObj->name)
);
$typeField->setDefault($val);
$serviceFormArray[$typeObj->name] = $typeField;
}
$netObj = Doctrine::getTable('Network')->find($net);
$this->partialForm->setWidgets($serviceFormArray);
$this->fullForm->embedForm($netObj->name,$this->partialForm);
}
and the template looks like this, some code omitted for brevity:
<div class="sectionBox">
<?php echo $fullForm->renderFormTag('/configure/submitconfig') ?>
<?php foreach ($fullForm->getVisibleFields() as $part => $field): ?>
<div class="settingsField">
<?php echo $field->renderLabel() ?>
<?php echo $field->render() ?>
<input type="hidden" name="plug" value="<?php echo $plugName; ?>"/>
</div>
<?php endforeach; ?>
<div id="submitConfig"><input type="submit" value="Save"/></div>
</form>
</div>
Try setting default value via $form->setDefault($name, $default).
$this->partialForm->setDefault($typeObj->name, $val);