I'm trying to write my first form in ZF2 and my code is
namespace Frontend\Forms;
use Zend\Form\Form;
use Zend\Validator;
class Pagecontent extends Form
{
public function __construct($name = null)
{
// we want to ignore the name passed
parent::__construct('logo');
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'content_yes_no',
'type'=>'text',
'required' => true,
'validators' => array(
'name' => 'Alnum',
'options'=>array(
'allowWhiteSpace'=>true,
),
),
));
}
}
I want to know can I set validators like this?
Please advice
You've got to surround validators by another array:
'validators' => array(
array(
'name' => 'Alnum',
'options' => array(
'allowWhiteSpace'=>true,
),
),
),
To setup filters and validators you need an inputFilter. Typically you will find the inputFilter defined in the form class or associated model class. Here is a template for a form.
<?php
/* All bracket enclosed items are to be replaced with information from your
* implementation.
*/
namespace {Module}\Form;
class {Entity}Form
{
public function __construct()
{
// Name the form
parent::__construct('{entity}_form');
// Typically there is an id field on the form
$this->add(array(
'name' => 'id',
'type' => 'Hidden',
));
// Add a csrf field to help with security
$this->add(array(
'type' => 'Zend\Form\Element\Csrf',
'name' => 'csrf'
));
// Add more form fields here
$this->add(array(
'name' => 'example',
'type' => 'Text',
'options' => array(
'label' => 'Example',
),
));
//Of course we need a submit button
$this->add(array(
'name' => 'submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Submit',
'id' => 'submitbutton',
),
));
}
}
The form defines all of the elements that will be displayed in the form. Now, you can either create the inputFilter in the form's class or in a model that is associated with the form's class. Either way it would look like:
<?php
/* All bracket enclosed items are to be replaced with information from your
* implementation.
*/
namespace {Module}\Model;
/*
* Include these if you require input filtering.
*/
use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
class {Model} implements InputFilterAwareInterface
{
/*
* Add in model members as necessary
*/
public $id;
public $example;
/*
* Declare an inputFilter
*/
private $inputFilter;
/*
* You don't need a set function but the InputFilterAwareInterface makes
* you declare one
*/
public function setInputFilter(InputFilterInterface $inputFilter)
{
throw new \Exception("Not used");
}
/*
* Put all of your form's fields' filters and validators in here
*/
public function getInputFilter()
{
if (!$this->inputFilter)
{
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add($factory->createInput(array(
'name' => 'id',
'required' => true,
'filters' => array(
array('name' => 'Int'),
),
)));
// This example input cannot have html tags in it, is trimmed, and
// must be 1-32 characters long
$inputFilter->add($factory->createInput(array(
'name' => 'example',
'required' => false,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 32,
),
),
),
)));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
}
Then when you are programming your controller's action you can bring it all together like this:
if($request->isPost())
{
$model = new Model;
$form->setInputFilter($model->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid())
{
// Do some database stuff
}
}
Notice that we get the inputFilter from the model and use the form's setInputFilter() method to attach it.
To summarize, You must create a form class to place all of your form elements in, then create an inputFilter to hold all of your filters and validators. Then you can grab the inputFilter in the controller and apply it to the form. Of course this is just a couple ways to skin a cat though.
You can use Input Filter component:
<?php
namespace Frontend\Forms;
use Zend\Form\Form;
use Zend\Validator;
use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilter;
class Pagecontent extends Form
{
public function __construct($name = null)
{
...
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add($factory->createInput(array(
'name' => 'content_yes_no',
'required' => true,
'filters' => array(),
'validators' => array(
array(
'name' => 'Alnum',
'options' => array(
'allowWhiteSpace' => true,
),
),
),
)));
$this->setInputFilter($inputFilter);
}
}
// your controller
$form = new \Frontend\Forms\Pagecontent();
$form->setData($request->getPost());
if ($form->isValid()) {
// your code
}
Related
I am developing a project with ZF2 and Doctrine. I am attempting to use Doctrine Hydrator in the form creation as shown in this tutorial. In this method, an ObjectManager object is created in the controller and passed to the new form when it is instantiated. Passing the ObjectManager object from the controller to the form creates a problem when I want to use ZF2's FormElementManager because ZF2 requires that I get an instance of the form class through the Zend\Form\FormElementManager instead of directly instantiating it. To work around this requirement, I have created form and fieldset factories based upon the answer to the question How to pass a Doctrine ObjectManager to a form through ZF2 FormElementManager. The method presented in the answer to the question works for typical fieldset elements, but I need to determine how to include a collection element. The tutorial uses the ObjectManager object in the collection element in the parent fieldset, and I need to figure out how to add the collection using a factory.
TagFieldset from the tutorial that I am trying to emulate:
namespace Application\Form;
use Application\Entity\Tag;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
class TagFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct(ObjectManager $objectManager)
{
parent::__construct('tag');
$this->setHydrator(new DoctrineHydrator($objectManager))
->setObject(new Tag());
$this->add(array(
'type' => 'Zend\Form\Element\Hidden',
'name' => 'id'
));
$this->add(array(
'type' => 'Zend\Form\Element\Text',
'name' => 'name',
'options' => array(
'label' => 'Tag'
)
));
}
public function getInputFilterSpecification()
{
return array(
'id' => array(
'required' => false
),
'name' => array(
'required' => true
)
);
}
}
new TagFieldsetFactory:
namespace Application\Form;
use Zend\Form\Fieldset;
use Application\Entity\Tag;
class TagFieldsetFactory
{
public function __invoke($formElementManager, $name, $requestedName)
{
$serviceManager = $formElementManager->getServiceLocator();
$hydrator = $serviceManager->get('HydratorManager')->get('DoctrineEntityHydrator');
$fieldset = new Fieldset('tags');
$fieldset->setHydrator($hydrator);
$fieldset->setObject(new Tag);
//... add fieldset elements.
$fieldset->add(['...']);
//...
return $fieldset;
}
}
BlogPostFieldset from the tutorial that I am trying to emulate:
namespace Application\Form;
use Application\Entity\BlogPost;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
class BlogPostFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct(ObjectManager $objectManager)
{
parent::__construct('blog-post');
$this->setHydrator(new DoctrineHydrator($objectManager))
->setObject(new BlogPost());
$this->add(array(
'type' => 'Zend\Form\Element\Text',
'name' => 'title'
));
$tagFieldset = new TagFieldset($objectManager);
$this->add(array(
'type' => 'Zend\Form\Element\Collection',
'name' => 'tags',
'options' => array(
'count' => 2,
'target_element' => $tagFieldset
)
));
}
public function getInputFilterSpecification()
{
return array(
'title' => array(
'required' => true
),
);
}
}
new BlogPostFieldsetFactory:
namespace Application\Form;
use Zend\Form\Fieldset;
use Application\Entity\BlogPost;
class BlogPostFieldsetFactory
{
public function __invoke($formElementManager, $name, $requestedName)
{
$serviceManager = $formElementManager->getServiceLocator();
$hydrator = $serviceManager->get('HydratorManager')->get('DoctrineEntityHydrator');
$fieldset = new Fieldset('blog_post');
$fieldset->setHydrator($hydrator);
$fieldset->setObject(new BlogPost);
//... add fieldset elements.
$fieldset->add(['...']);
//...
return $fieldset;
}
}
in module.config.php:
'form_elements' => [
'factories' => [
'UpdateBlogPostForm' => 'Application\Form\UpdateBlogPostFormFactory',
'BlogPostFieldset' => 'Application\Form\BlogPostFieldsetFactory',
'TagFieldset' => 'Application\Form\TagFieldsetFactory',
],
],
When I add the fieldset elements In my new BlogPostFieldsetFactory I replace this code from the original fieldset:
$this->add(array(
'type' => 'Zend\Form\Element\Text',
'name' => 'title'
));
with this:
$fieldset->add(array(
'type' => 'Zend\Form\Element\Text',
'name' => 'title'
));
How do I replace the collection element from the original fieldset:
$tagFieldset = new TagFieldset($objectManager);
$this->add(array(
'type' => 'Zend\Form\Element\Collection',
'name' => 'tags',
'options' => array(
'count' => 2,
'target_element' => $tagFieldset
)
));
maybe i'm getting your question wrong.... but if you replaced this
$this->add(array(
'type' => 'Zend\Form\Element\Text',
'name' => 'title'
));
whith this:
$fieldset->add(array(
'type' => 'Zend\Form\Element\Text',
'name' => 'title'
));
then you probably can replace this:
$tagFieldset = new TagFieldset($objectManager);
$this->add(array(
'type' => 'Zend\Form\Element\Collection',
'name' => 'tags',
'options' => array(
'count' => 2,
'target_element' => $tagFieldset
)
));
with this:
$tagFieldset = new TagFieldset($objectManager);
$fieldset->add(array(
'type' => 'Zend\Form\Element\Collection',
'name' => 'tags',
'options' => array(
'count' => 2,
'target_element' => $tagFieldset
)
));
now, if you cant pass the $objectManger to the form... well if you look at the code you have this thing available $serviceManager, that thing looks like a DI container, im sure you can get the $objectManager instance from there, and if is not available, you can probably put an instance of it inside.
So de final code probably ending looks like this:
$objectManager = $serviceManager->get('DoctrineObjectManager') //or something like this
$tagFieldset = new TagFieldset($objectManager);
$fieldset->add(array(
'type' => 'Zend\Form\Element\Collection',
'name' => 'tags',
'options' => array(
'count' => 2,
'target_element' => $tagFieldset
)
));
I have a problem with Zend Framework 2 and Date element. The attribute I'm trying to store is a DateOfBirth, but this attribute maybe empty. For example the date is unknown. The column in the database allows NULL. The Doctrine class attached to it has a attribute that let's it know it allows null. But Zend Framework 2 still gives me this error:
"Value is required and can't be empty".
Even though I set the required attribute=false, also the allow_empty=true, but nothing works.
The attirbute it a member of a nested fieldset within a form. The nesting looks as follows:
UserManagementForm
User (fieldset)
Person (fieldset)
DateOfBirth (element)
Couple examples i tried:
Form not validating correctly zend framework 2
https://github.com/zendframework/zf2/issues/4302
Here is the code I am using at the moment. Hopefully you see something that I'm missing. I don't know if it due to the fact that it is nested, but the rest works perfect, only the date element is causing me trouble.
UserManagementForm
<?php
namespace Application\Form;
use Zend\Form\Form;
class UserManagementForm extends Form
{
public function __construct()
{
parent::__construct('usermanagementform');
$this->setAttribute('method', 'post');
$fieldset = new \Application\Form\Fieldset\User();
$fieldset
->setHydrator(new \Zend\Stdlib\Hydrator\ObjectProperty(false))
->setObject(new \Application\Entity\User())
->setOptions(array('use_as_base_fieldset' => true))
;
$this->add($fieldset);
$this->add(array(
'name' => 'btnSubmit',
'type' => 'submit',
'attributes' => array(
'class' => 'btn-primary',
),
'options' => array(
'column-size' => 'sm-9 col-sm-offset-3',
'label' => 'Save changes',
),
));
}
}
?>
User (Fieldset)
<?php
namespace Application\Form\Fieldset;
use Zend\Form\Fieldset;
class User extends Fieldset
{
public function __construct()
{
parent::__construct('User');
$fieldset = new \Application\Form\Fieldset\EmailAddress();
$fieldset
->setHydrator(new \Zend\Stdlib\Hydrator\ObjectProperty(false))
->setObject(new \Application\Entity\EmailAddress());
$this->add($fieldset);
$fieldset = new \Application\Form\Fieldset\Person();
$fieldset
->setHydrator(new \Zend\Stdlib\Hydrator\ObjectProperty(false))
->setObject(new \Application\Entity\Person());
$this->add($fieldset);
}
}
?>
Person (fieldset)
<?php
namespace Application\Form\Fieldset;
use Zend\Form\Fieldset;
class Person extends Fieldset
{
public function __construct()
{
parent::__construct('Person');
$this->add(array(
'type' => 'date',
'name' => 'DateOfBirth',
'required' => false,
'allowEmpty' => true,
'options' => array(
'label' => 'Date of birth',
'column-size' => 'sm-9',
'label_attributes' => array(
'class' => 'col-sm-3',
),
'format' => 'd-m-Y',
),
));
}
}
?>
'required' isn't an attribute of element but an validator attribute.
The solution consist to implement Zend\InputFilter\InputFilterProviderInterface
use Zend\InputFilter\InputFilterProviderInterface;
class UserManagementForm extends AbstractSbmForm implements InputFilterProviderInterface {
public function __construct()
{
... without change
}
public function getInputFilterSpecification()
{
return array(
'DateOfBirth' => array(
'name' => 'DateOfBirth',
'required' => false,
);
);
}
}
I have a Registration form.
namespace User\Form;
use Zend\Form\Form;
class Register extends Form {
public function __construct() {
parent::__construct('register');
$this->setAttribute('action', 'new-account');
$this->setAttribute('method', 'post');
//$this->setInputFilter(new \User\Form\RegisterFilter); - used this prior to learning Fieldset
$this->add(new \User\Form\RegisterFieldsetUser);
// Submit
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Register',
'class' => 'btn btn-primary',
),
));
}
}
and the User fieldset:
(to make this short I've only left on field)
namespace User\Form;
use Zend\Form\Fieldset;
class RegisterFieldsetUser extends Fieldset {
public function __construct() {
parent::__construct('user');
// User Identifier
$identifier = new \Zend\Form\Element\Email();
$identifier->setName('identifier');
$identifier->setAttributes(array(
'id' => 'user-email',
'placeholder' => 'Email'
));
$identifier->setLabel('Your email:');
$this->add($identifier);
}
public function getInputFilterSpecification() {
return array(
'identifier' => array(
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'break_chain_on_failure' => true,
'options' => array(
'messages' => array(
\Zend\Validator\NotEmpty::IS_EMPTY => 'You really have to enter something!',
),
),
),
array(
'name' => 'EmailAddress',
'options' => array(
'messages' => array(
\Zend\Validator\EmailAddress::INVALID_FORMAT => 'Hmm... this does not look valid!',
),
),
),
),
),
);
}
}
this is my action:
public function registerAction() {
$registerForm = new \User\Form\Register;
if ($this->getRequest()->isPost()) {
// Form processing
$formData = $this->getRequest()->getPost();
if ($registerForm->isValid()) {
// Yeeeeei
} else {
$registerForm->setData($formData);
return new ViewModel(array(
'form' => $registerForm,
));
}
} else {
return new ViewModel(array(
'form' => $registerForm,
));
}
}
Now, if I submit the form without entering anything, I get the message : "Value is required and can't be empty" (which is NOT the message I have set). But it's not an issue with the messages I set, because if I submit the form with an invalid email address ("asd/") then it doesn't say anything, no validation error. So, I assume no validation happens here.
Any clue why?
Before learning to use filedset, I had an InputFilter which worked perfectly fine, but following the book's learning curve, I got to using Fieldset.
I'm just a zf newb, learning from this book I've bought from leanpub (Michael Romer's "Web development with zf2"). I don't know the version used in the book (it was last updated in august 2013), but I use the latest (2.2.5).
If you want to add filter specification by getInputFilterSpecification method your form class (or fieldset class) MUST implement InputFilterProviderInterface. So:
<?php
use Zend\InputFilter\InputFilterProviderInterface;
class RegisterFieldsetUser extends Fieldset
implements InputFilterProviderInterface
{
...
}
I'm in the process of creating a form that let's the user schedule an event at a specified date, time and timezone. I want to combine the input of those three form fields and store them in one datetime column in the database. Based on the input I want to convert the specified date and time to UTC.
However I'm not completely sure how to write the form code for this. I was writing a Fieldset class extending Fieldset and adding the three fields to this fieldset:
<?php
namespace Application\Form\Fieldset;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterInterface;
use Zend\InputFilter\InputFilterProviderInterface;
use Zend\Stdlib\Hydrator\ClassMethods;
class SendDateFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct()
{
parent::__construct('senddate');
$this->add(array(
'name' => 'date',
'type' => 'Text',
'options' => array(
'label' => 'Date to send:',
)
)
);
$this->add(array(
'name' => 'time',
'type' => 'Text',
'options' => array(
'label' => 'Time to send:',
)
)
);
$this->add(array(
'name' => 'timezone',
'type' => 'Select',
'options' => array(
'label' => "Recipient's timezone",
'value_options' => array(
-12 => '(GMT-12:00) International Date Line West',
-11 => '(GMT-11:00) Midway Island, Samoa',
-10 => '(GMT-10:00) Hawaii',
),
),
)
);
}
public function getInputFilterSpecification()
{
return array(
'date' => array(
'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'Date',
'break_chain_on_failure' => true,
'options' => array(
'message' => 'Invalid date'
),
),
),
),
'time' => array(
'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
),
),
'timezone' => array(
'required' => true,
),
);
}
}
I then add this fieldset to my form like so:
<?php
namespace Application\Form;
use Zend\Form\Form;
class Order extends Form
{
public function __construct()
{
parent::__construct("new-order");
$this->setAttribute('action', '/order');
$this->setAttribute('method', 'post');
$this->add(
array(
'type' => 'Application\Form\Fieldset\SendDateFieldset',
'options' => array(
'use_as_base_fieldset' => false
),
)
);
}
}
Of course I will add other fieldsets to the form, the base fieldset for the order information itself and another fieldset with recipient info.
I have two questions about this:
What would be the most elegant way to handle the three fields and
store them as 1 datetime (converted to UTC) in the database? I have
an Order service object too that will be responsible for handling a
new order, so I could take care of it in the method responsible for
handling a new order in that service class or is there a better way?
I only posted a small snippet of the list of timezones in the
SendDate fieldset. Is there a cleaner way to do render this list?
Okay, so as promised I'll share my solution to this problem. Hopefully it will help someone else in the future.
I ended up using the SendDateFieldset which I initially had already.
Application\Form\Fieldset\SendDateFieldset:
<?php
namespace Application\Form\Fieldset;
use Application\Hydrator\SendDate as SendDateHydrator;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterInterface;
use Zend\InputFilter\InputFilterProviderInterface;
class SendDateFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct()
{
parent::__construct('senddate');
$this->setHydrator(new SendDateHydrator());
$this->setObject(new \DateTime());
$this->add(array(
'name' => 'date',
'type' => 'Text',
'options' => array(
'label' => 'Date to send:',
)
)
);
$this->add(array(
'name' => 'time',
'type' => 'Text',
'options' => array(
'label' => 'Time to send:',
)
)
);
$this->add(array(
'name' => 'timezone',
'type' => 'Select',
'options' => array(
'label' => "Recipient's timezone",
'value_options' => array(
// The list of timezones is being populated by the OrderFormFactory
),
),
)
);
}
public function getInputFilterSpecification()
{
return array(
'date' => array(
'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'Date',
'break_chain_on_failure' => true,
'options' => array(
'message' => 'Invalid date'
),
),
),
),
'time' => array(
'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'Callback',
'options' => array(
'callback' => function($value, $context)
{
// #todo: check if date and time is in the future
return true;
}
),
),
),
),
'timezone' => array(
'required' => true,
),
);
}
}
As you can see in this fieldset I now use a plain DateTime object as entity. To populate the DateTime object I use a custom hydrator for this fieldset: SendDateHydrator, which looks like this:
<?php
namespace Application\Hydrator;
use Zend\Stdlib\Hydrator\AbstractHydrator;
use DateTime;
use DateTimeZone;
class SendDate extends AbstractHydrator
{
public function __construct($underscoreSeparatedKeys = true)
{
parent::__construct();
}
/**
* Extract values from an object
*
* #param object $object
* #return array
* #throws Exception\BadMethodCallException for a non-object $object
*/
public function extract($object)
{
throw new Exception\BadMethodCallException(sprintf(
'%s is not implemented yet)', __METHOD__
));
}
/**
* Hydrate data into DateTime object
*
* #param array $data
* #param object $object
* #return object
* #throws Exception\BadMethodCallException for a non-object $object
*/
public function hydrate(array $data, $object)
{
if (!$object instanceof DateTime)
{
throw new Exception\BadMethodCallException(sprintf(
'%s expects the provided $object to be a DateTime object)', __METHOD__
));
}
$object = null;
$object = new DateTime();
if (array_key_exists('date', $data) && array_key_exists('time', $data) && array_key_exists('timezone', $data))
{
$object = new DateTime($data['date'] . ' ' . $data['time'], new DateTimeZone($data['timezone']));
}
else
{
throw new Exception\BadMethodCallException(sprintf(
'%s expects the provided $data to contain a date, time and timezone)', __METHOD__
));
}
return $object;
}
}
The hydrate method takes care of creating the DateTime object using the timezone specified by the user using a selectbox.
To generate the select with timezones in the form I made a small service which uses DateTimeZone to generate a list of timezones and formats them nicely. The end result is an associative array that can be passed to the value options of the select. The keys of this array are official timezone identifiers that DateTimeZone can handle. I pass this list in the factory class responsible for creating the form where I use this selectbox:
Application\Factory\OrderFormFactory:
<?php
namespace Application\Factory;
use Application\Service\TimezoneService;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Application\Form\Order as OrderForm;
class OrderFormFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$orderForm = new OrderForm();
/* #var $timezoneSvc TimezoneService */
$timezoneSvc = $serviceLocator->get('Application\Service\TimezoneService');
// Set list of timezones in SendDate fieldset
$orderForm->get('order')->get('senddate')->get('timezone')->setValueOptions(
$timezoneSvc->getListOfTimezones()
);
return $orderForm;
}
}
The generated fieldset in the form looks like this:
When saving the order the orderservice converts the DateTime to a UTC time before storing it in the database.
I try to validate with the form but I cant get error messages.
//this is my code:
$form = new TestForm();
$form->setInputFilter(new TestFilter());
$data = array('id'=>'','email'=>'myemail#myemail.com');
$form->setData($data);
if($form->isValid()){
echo 'ok';
} else {
echo 'not ok <br/>';
$messagesForm = $form->getMessages();
$filter=$form->getInputFilter();
$messagesFilter=$filter->getMessages();
var_dump($messagesForm);
var_dump($messagesFilter);
}
/////////////////
Output
not ok
//messagesForm
array
empty
//MessagesFilter
array
'id' =>
array
'isEmpty' => string 'Value is required and can't be empty' (length=36)
_
How is possible? The filter is ok, but I can't get error messages from the form
Could be a bug or I made something wrong?
FULL code:
TestFilter:
_
<?php
namespace mvc\filter;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\Factory as InputFactory;
class TestFilter extends InputFilter
{
public function __construct()
{
$factory = new InputFactory();
$this->add($factory->createInput(array('name'=>'id','required'=>true)));
$this->add($factory->createInput(array('name'=>'email','required'=>true)));
}
}
?>
_
TestForm
_
namespace mvc\form;
use Zend\InputFilter\Factory;
use Zend\Form\Element;
use Zend\Form\Form;
class TestForm extends Form
{
public function prepareElements()
{
$this->add(array(
'name' => 'id',
'attributes' => array(
'type' => 'text',
'label' => 'Your name',
),
));
$this->add(array(
'name' => 'email',
'attributes' => array(
'type' => 'email',
'label' => 'Your email address',
),
));
}
}
?>
_
I have not worked with ZF2 yet but try to add validators to your elements:
use Zend\Validator;
$this->add(array(
'name' => 'id',
'attributes' => array(
'type' => 'text',
'label' => 'Your name',
),
'validator' => new StringLength(array('max'=>20))
));
}
you must specify 'validators', example of a getInputFilter:
use
Zend\InputFilter\InputFilter,
Zend\InputFilter\Factory as InputFactory,
Zend\InputFilter\InputFilterAwareInterface,
Zend\InputFilter\InputFilterInterface;
class User implements InputFilterAwareInterface
{
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add($factory->createInput(array(
'name' => 'email',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 100,
),
),
),
)));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
You may do it this way by retrieving input filter from your model and then setting it to a form:
...
$form = new ItemForm();
$form->setInputFilter($user->getInputFilter());
$form->setData($params);
if ($form->isValid()) {
...
}
...