I have two Zend_Forms (form1 and form2). I would like to combine them so I have a third form (form3) consisting of all the elements from both forms.
What is the correct way to do this with the Zend Framework?
Here's how I ended up doing it...I didn't want to namespace each form, I just wanted all the elements in the form so I decided to just add all the elements individually instead of using subForms.
<?php
class Form_DuplicateUser extends Zend_Form
{
public function init()
{
$this->setMethod('post');
$form1 = new Form_ContactPrimaryInformationForm();
$this->addElements($form1->getElements());
$form2 = new Form_ContactAdditionalInformationForm();
$this->addElements($form2->getElements());
}
}
You can use subforms. The only difference between Zend_Form and Zend_Form_SubForm are the decorators:
$form1 = new Zend_Form();
// ... add elements to $form1
$form2 = new Zend_Form();
// ... add elements to $form2
/* Tricky part:
* Have a look at Zend_Form_SubForm and see what decorators it uses.
*/
$form1->setDecorators(array(/* the decorators you've seen */));
$form2->setDecorators(array(/* ... */));
$combinedForm = new Zend_Form();
$combinedForm->addSubForm('form_1', $form1);
$combinedForm->addSubForm('form_2', $form2);
Then in the controller you assign the form to the view:
$this->view->form = $combinedForm;
And you can acces the two subforms in the view by name:
// In the view
echo $this->form->form_1;
echo $this->form->form_2;
Related
I have a form with all field that map an object.
Of this, i would generate a subform within of the Form class.
I'm trying to do this by the displaygroup, but when call the "subform" in the controller, the tag form, is not generate.
how can I solve ?
Thanks
this is the code.
<?php
$username = new Zend_Form_Element_Text('user');
...//param for field
$password = new Zend_Form_Element_Password('pwd');
...//param for field
$name = new Zend_Form_Element_Text('name');
...//param for field
$submit = new Zend_Form_Element_Submit('submit');
...//param for field
$this->addElement(array($user,$password,$name,$submit));
$this->addDisplayGroup(array($user,$password,$submit),'login');
$this->addDisplayGroup(array($user,$password,$name, $submit),'create');
?>
A subform is something different than a display group. A subform is a Zend_Form_SubForm instance nested in Zend_Form instance. You can use this to embed one form into another. As an example, you might have a user profile form and a registration form. In the registration form you can enter profile values as well as some other details. So, you can use this profile form as subform embedded inside the registration form. A subform is mainly used for DRY (don't repeat yourself) principles or to create a multi-page form.
A display group is just a visual representation of some form elements grouped together. In html syntax this is called a fieldset. The main purpose is to create groups of elements which belong to each other. For example in a shopping cart you might have an invoice address group and a shipping address group. Such display group is mainly used for semantics and visual representation.
On of the largest differences is that for display groups, the form has awareness of those form elements, as with subforms the form has no awareness of the elements of the subforms. This said, I notice you want to create one form which contains two display groups: one when you login, one when you create (or register) a user. With the given from above you cannot use display groups for this. One option is to use two form instances:
class LoginForm extends Zend_Form
{
public function init ()
{
$this->addElement('text', 'user');
$this->addElement('password', 'pwd');
$this->addElement('submit', 'submit');
}
}
class RegisterForm extends Zend_Form
{
public function init ()
{
$this->addElement('text', 'user');
$this->addElement('password', 'pwd');
$this->addElement('text', 'name');
$this->addElement('submit', 'submit');
}
}
If you want to reuse the fields user and pwd you might want to use subforms for this:
class BaseForm extends Zend_Form_SubForm
{
public function init ()
{
$this->addElement('text', 'user');
$this->addElement('password', 'pwd');
}
}
class LoginForm extends Zend_Form
{
public function init ()
{
$subform = new BaseForm;
$this->addSubform($subform, 'base');
$this->addElement('submit', 'submit');
}
}
class RegisterForm extends Zend_Form
{
public function init ()
{
$subform = new BaseForm;
$this->addSubform($subform, 'base');
$this->addElement('text', 'name');
$this->addElement('submit', 'submit');
}
}
In both cases, you can simply instantiated one of those forms in your controller:
public function loginAction ()
{
$form = new LoginForm();
// More code here
$this->view->form = $form;
}
public function registerAction ()
{
$form = new RegisterForm();
// More code here
$this->view->form = $form;
}
Zend_Form_SubForm doesn't render <form> tags by default.
In order to get it to do so, you need to add the 'Form' decorator to your subform instance before you render it.
Try:
$mySubForm->addDecorator('HtmlTag', array('tag' => 'dl', 'class' => 'zend_form'))
->addDecorator('Form');
and then, in your view script, you can do:
<?php echo $this->mySubForm; ?>
I've just (as in today) started working on some ZF stuff.
I have a Form that needs to have some text in a div appear at the top of the form, but I have no idea how to include it.
The structure of the form is:
class MyForm extends \app\forms\FormType {
public function init() {
// gets all the form elements of the parent
parent::init();
// A few additional form elements for MyForm created here
}
}
Any help would be apprecaited!
In your controller where you instantiate the form object just set it with the view object like this:
public function actionNameAction()
{
// ...
if (/* some condition to check form page */) {
$this->view->divText = 'your text';
}
}
Then put the div in the action-name.phtml script:
views/scripts/controller/action-name.phtml
Contents:
<?php if (!empty($this->divText)): ?>
<div><?php echo $this->divText; ?></div>
<?php endif; ?>
Additionally, you could pass the view object by reference to your form class. Just overload the construct function like so:
public function __construct($options = null, &$view)
{
parent::__construct($options);
$this->view = $view;
}
Then in your controller when you instantiate your form object do this:
$form = new MyForm(null, $this->view);
Let's go back to your form class once again and modify the init() method:
public function init()
{
// ...
$this->view->divText = 'Text set from within ' . __CLASS__;
}
Using this way, you won't have to put any conditional if statements checking anything in the controller. You're already checking if $this->divText is not empty in the view, so by passing the view object to your form class you can ensure that that text will only be set when the form is being used.
If I do this
public function indexAction()
{
$view = new Zend_View();
$registrationForm = new Form_NewAwatag();
$view->assign((array) $registrationForm);
echo $view->render("index.phtml");
}
it will create a new Zend_View object. How can I use the default Zend_View object?
Is it correct how I pass object to the view script?
You can get the view by using $this->view;
Assign values with $this->view->variable = $value
Your code could be stripped down to this
public function indexAction()
{
$registrationForm = new Form_NewAwatag();
$this->view->assign('myForm', $registrationForm);
}
Because the Zend MVC construct will automatically render the index.phtml file while it is the indexAction beeing called. In the view your form can be accessed by $this->myForm.
In my controller I got a function which looks like this:
public function newExperienceAction() {
$this->_helper->layout->disableLayout();
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('newExperience', 'html')->initContext();
$id = $this->_getParam('id', null);
$this->form = new Application_Form_Cv();
$this->experience = new Zend_Form_SubForm();
$this->form->addSubForm($this->experience, 'experience');
$rowExperience = new Application_Form_Experience();
$rowExperience->setDisplayGroups('experience');
$this->experience->addSubForm($rowExperience, "experience$id", $id+3);
echo $rowExperience->__toString();
}
When the user press (+) on the form, a new subForm will be displayed.
I'm currently in the process if shaping it into a table. I will have more than one subForm on this form so I need to use DisplayGroups.
In this situation, I believe I have to create a Display group when the form is first created.
Then I need to append the new subForms to the existing display groups.
So the question:
How do I add new subForms to an existing display group?
You can achieve this by simply adding
$rowExperience->setIsArray(true);
This causes the sub-form to act like a display group, i.e. its values are wrapped in an array indexed by the sub-form's name (experience$id in your case).
I'm afraid this is not possible now. I'm using Zend Framework version 1.11.7 and the code of the addDisplayGroup method looks like that:
foreach ($elements as $element) {
if($element instanceof Zend_Form_Element) {
(...)
}
if (isset($this->_elements[$element])) {
(...)
}
}
So this is not supported yet. You can add only Zend_Form_Element instances
So I've created myself a custom form element which has a custom view helper. Now I want to be able to set certain parameters/variables on this form element and be able to access them in my element's view helper. How can I do that?
Here's an example of what I am talking about:
adding the element to the form:
$element = new My_Form_Element_Picker('elementname');
$element->setFoobar('hello');
// or
$form->addElement('Picker', 'elementname', array('foobar' => 'hello'));
form element:
class My_Form_Element_Picker extends Zend_Form_Element_Xhtml
{
public $helper = 'pickerElement';
}
view helper:
class My_View_Helper_PickerElement extends Zend_View_Helper_FormElement
{
public function pickerElement($name, $value = null, $attribs = null)
{
//now I want to check if the 'foobar' option was set, otherwise use a default value
$foobar = 'default';
}
}
There is a fourth optional argument to the view helper that might do the trick for you.
if you define your view helper like this:
public function pickerElement( $name, $value=null, $attribs=null, $options=null ) { }
And then inside your actual form element you define it like this:
class My_Form_Element_Picker extends Zend_Form_Element_Xhtml {
public $helper = 'pickerElement';
public $options = array();
public function setFoobar( $foobar ) {
$this->options['foobar'] = $foobar;
}
}
You will find that the options are passed into the view helper and can be used.
This code is from memory so please forgive any mistakes, this method definitely works for me though.