I use my class to alter decoration of my form.
In other words, instead of calling
Application_Form_Login extends Zend_Form
I use:
Application_Form_Login extends My_Form
In my "My_Form" class I define the following:
protected $_disableLoadDefaultDecorators = true;
protected $_elementDecorators = array(
'ViewHelper',
array(
'Errors',
array(
'data-icon'=>"alert",
'class'=>"ui-body ui-body-e errors"
)
),
'Label',
array(
array(
'row' => "HtmlTag"
), array(
'tag'=>"div",
'data-role'=>"fieldcontain"
)
)
);
This works perfect on my regular forms.
But once I use jQuery forms:
$this->addElement(new ZendX_JQuery_Form_Element_AutoComplete(
"ac1",
array('label' => "Your Address:"))
));
It has no effect on them, and they still render with their default decorators.
Any ideas how to globally set decorators for jQuery Form Elements as well?
I have solved the problem. Any default decorators defined this way will also work on any ZendX_JQuery_Form_Element
IF
The element is created inside of addElement function. In other words, instead of creating an element this way:
$this->addElement(new ZendX_JQuery_Form_Element_AutoComplete(
"address",
array(
'label' => "Your Address:"
)
));
You should create it this way:
$this->addElement('AutoComplete', 'address', array(
'label' => "Your Address:"
));
Because when addElement creates the element itself, it will pass the default decorators to the creating function. Otherwise the elements will be created outside of the form context.
There's no AutoComplete element in Zend_Form. So, the class you use to build your forms, that includes all your global settings and decorations (in my case: "My_Form") should extend ZendX_JQuery_Form, and not Zend_Form
ZendX_JQuery_Form_Element_UiWidget requires UiWidgetElement decorator. So we replace the ViewHelper decorator with ZendX_JQuery's: UiWidgetElement.
Related
I want to create custom module which can upload multiple images like product.I have created one custom module but it uploads only one image.
form.php
$fieldset->addField('filename', 'image', array(
'label' => Mage::helper('footertop')->__('File'),
'name' => 'filename',
));
I think you need to create your custom renderer for the image field. For this create this class in your module:
class [YOURNamespace]_[YOURModule]_Block_Adminhtml_[YOUREntity]_Helper_Image extends Varien_Data_Form_Element_Image{
//make your renderer allow "multiple" attribute
public function getHtmlAttributes(){
return array_merge(parent::getHtmlAttributes(), array('multiple'));
}
}
Now at the top of your _prepareForm (where you add your fields) add this line before adding any field:
$fieldset->addType('image', '[YOURNamespace]_[YOURModule]_Block_Adminhtml_[YOUREntity]_Helper_Image');
Or if you want to be "politically correct" add it this way:
$fieldset->addType('image', Mage::getConfig()->getBlockClassName('[YOURmodule]/adminhtml_[YOURentity]_helper_image'));
This will tell Magento that in your current fieldset, all the fields with type image should be rendered by your own class.
Now you can add your field like similar to how you did it:
$fieldset->addField('image', 'image', array(
'name' => 'image[]', //declare this as array. Otherwise only one image will be uploaded
'multiple' => 'multiple', //declare input as 'multiple'
'label' => Mage::helper('YOURmodule')->__('Select Image'),
'title' => Mage::helper('YOURmodule')->__('Can select multiple images'),
'required' => true,
'disabled' => $isElementDisabled
));
That's it.
Don't forget to replace the placeholders ([YOURModule] and others) with your values.
I am learning how to use Zend Framework 2 (2.1.4) forms and running into this error.
Call to a member function insert() on a non-object in ... /Zend/Form/Fieldset.php on line 178
I don't want use the form to automatically connect to a database, in fact I only want to use the form to help validate and will pull from and populate it with an array of values. How do I turn off the database connectivity in the form objects?
I am used to dealing with the ZF1 forms so this new form system is confusing. Once I thought about it though, the way we can use the form elements in our view scripts for formatting is going to be nice. Those old decorators were a pain. Anyway, for me, it would be nice to use the forms without dealing with bound database objects. Is this possible? It just seems so overly complicated to need a model class using InputFilterAwareInterface classes in addition to a simple form. One step at a time though, I can't even get the form to display.
I appreciate any help.
Below are my controller, form, and view scripts:
Form class:
namespace FBWeb\Form;
use Zend\Form\Form;
use Zend\Form\Element;
class ClientForm extends Form
{
public function __construct()
{
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'client',
'type' => 'Zend\Form\Element\Text',
'options' => array(
'label' => 'Client Name',
),
'attributes' => array(
'type' => 'text',
),
));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Add'
),
));
}
}
Controller class:
namespace FBWeb\Controller;
use Zend\Debug\Debug;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Session\Container;
use Zend\Http\Request;
use FBWeb\Form\ClientForm;
class ClientController extends AbstractActionController
{
public function indexAction()
{
$clientform = new ClientForm();
return array('form' => $clientform);
}
}
index.phtml view script:
<div id="clientformtable">
<?php
$form = $this->form;
$form->setAttribute('action','/app/client/add');
$form->prepare();
echo $this->form()->openTag($form);
$client = $form->get('client');
echo $this->formRow($client);
echo $this->form()->closeTag();
?>
</div>
This, and similar error messages, happen due to the fact that the form isn't properly set up. As you can see within the code above the __construct() function doesn't call the parents constructor. Therefore the internal "bootstrapping" doesn't happen and the error occurs.
You have to make sure to always call the parents constructor when dealing with Zend\Form\Form and/or Zend\Form\Fieldset.
parent::__construct('client-form');
I need a straight forward working example how I can include a collection element in Zend Form, I have seen some examples from Zend Framework 2 site and from previous posts in StackOverflow where most of them pointed to this link. But right now I am not using Fieldsets and staying with Forms, so in case if someone can direct me in the right way, how I can include a simple collection element when the user gets a page where the user can choose multiple choices from the shown collection form. Much better would be populating the collection form from database.
I have searched in the internet for quite a sometime now and thought I would post here, so that Zend profis can give their suggestions.
Just For Information:
Normally one can include a static dropdownbox in Zend Form in this fashion
$this->add(
array(
'name' => "countr",
'type' => 'Zend\Form\Element\Select',
'options' => array(
'label' => "Countries",
'options' => array(
'country1' => 'Brazil',
'country2' => 'USA',
'country3' => 'Mexico',
'country4' => 'France',
)
)
)
);
So I am expecting a simple example which could give me a basic idea how this can be done.
To be honest, I don't see your problem here. Since form collections extend Fieldset which extends Element, you can just add it to the form as a regular element. The view helpers will take care of the rendering recursively.
Step 1: Create a form collection (create an instance of Zend\Form\Element\Collection). If the elements have to be added dynamically in some way, I'd create a factory class for this purpose.
Step 2: Add it to the form. (For example using $form->add($myCollectionInstance).)
Step 3: Render it. Zend\Form\View\Helper\Collection is a pretty good view helper to render the whole form without any pain.
You can also create a new class extending Zend\Form\Element\Collection and use the constructor to add the fields you need. Thus, you can add it to the form using the array you've pasted in your question. Also, you could directly use it in annotations.
Hope this helps.
If you just want to fill in a select list with option values you can add the array to the select list in a controller:
$form = new MyForm();
$form->get('countr')->setOptions(array('value_options'=>array(
'country1' => 'Brazil',
'country2' => 'USA',
'country3' => 'Mexico',
'country4' => 'France',
));
the array can be fetched from db.
this is a different example for using form collections in the simplest way.
In this example it creates input text elements in a collection and fills them in. The number of elements depends on the array:
class MyForm extends \Zend\Form\Form
{
$this->add(array(
'type' => '\Zend\Form\Element\Collection',
'name' => 'myCollection',
'options' => array(
'label' => 'My collection',
'allow_add' => true,
)
));
}
class IndexController extends AbstractActionController
{
public function indexAction
{
$form = new MyForm();
$this->addElementsFromArray($form, array(
'country1' => 'Brazil',
'country2' => 'USA',
'country3' => 'Mexico',
'country4' => 'France',
));
//the above line can be replaced if fetching the array from a db table:
//$arrayFromDb = getArrayFromDb();
//$this->addElementsFromArray($form, $arrayFromDb);
return array(
'form' => $form
);
}
private function addElementsFromArray($form, $array)
{
foreach ($array as $key=>$value)
{
$form->get('myCollection')->add(array(
//'type' => '\Zend\Form\Element\SomeElement',
'name' => $key,
'options' => array(
'label' => $key,
),
'attributes' => array(
'value' => $value,
)
));
}
}
}
index.phtml:
$form->setAttribute('action', $this->url('home'))
->prepare();
echo $this->form()->openTag($form);
echo $this->formCollection($form->get('myCollection'));
echo $this->form()->closeTag();
When I define attributes in form builder and same attributes as default in custom field the other are ignored. In form builder I have:
$builder
->add('validityOfADecisionOnDisability', new JQDateType(), array(
'attr' => array(
'rel' => 'permanent',
)
))
and custom field
class JQDateType extends AbstractType {
public function getDefaultOptions(array $options)
{
return array(
'widget' => 'single_text',
'format' => 'yyyy-MM-dd',
'attr' => array(
'class' => 'datepicker'
)
);
}
and it renders html
<input type="text" rel="permanent" required="required"
name="profile[validityOfADecisionOnDisability]"
id="profile_validityOfADecisionOnDisability">
without class. But when I add class to attributes in builder
$builder
->add('validityOfADecisionOnDisability', new JQDateType(), array(
'attr' => array(
'rel' => 'permanent',
'class' => 'datepicker',
)
))
eevrything works as expected. How should I define attributes in JQDateType() ? I tried to use array_merge() and array_merge_recursive() in JQDateType::getDefaultOptions() but it didn't help.
This was a bug that is fixed in Symfony 2.1.
#Koral I guess you can use annotation in your Entity class is better than 'getDefaultOptions' ,you can see here :
http://symfony.com/doc/current/book/validation.html
Yes you can validate all fields of your forms directly in your Entity Class,for example :
/**
* #Assert\Min(limit = "18", message = "You must be 18 or older to enter")
*/
protected $age;
Sounds like a bug. You should open a ticket on https://github.com/symfony/symfony/issues
For a form I'm trying to add a selectbox which contains a list of items from my database.
My form is situated in /application/forms/News/Edit.php
In my controller I want to fetch this list which I want to use in my form.
How can I add that list from my controller to my form?
This is how my code in Edit.php looks like:
$this->addElement(
'select',
'view_status',
array(
'label' => 'View status',
'multioptions' => array(
//THIS SHOULD BE FILLED WITH DYNAMIC CONTENT FROM MY CONTROLLER
)
)
);
You can pass the options of your select in the first param of the form constructor. When initialising the form, Zend_Form look for a set method postfixed by the option name:
class App_Form_News_Edit extends Zend_Form
{
public function setViewStatusOptions($options)
{
$this->view_status->setMultioptions($options);
}
}
$form = new App_Form_News_Edit(array('viewStatusOptions' => array(..)));
Just use the constructor or _init function of your forms class to set any custom values you would have.
It would get you something looking like (in your controller):
$myForm = new form_News_Edit($myArrayOfValues);
Then in your forms class :
public function __construct($myArrayOfValue){
....
$this->addElement(
'select',
'view_status',
array(
'label' => 'View status',
'multioptions' => $myArrayOfValue
)
);
}
yvoyer's Solution is good too but takes out some of the business logic for the form out of it.
In your controller's action, you could initialize the options you wants depending on the action. You should set the optoions before sending the form to the view.
$Form = new form_News_Edit();
$Form->getElement('view_status')
->setMultioptions($arrayOptions);
$this->view->assign('Form', $Form);