Validate Form in Zend Framework 2 with subforms - php

I have a form with a subform. My question is how to validate that? I don't have any idea how to validate this form with subforms. This is the code:
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'manual',
'attributes' => array(
'type' => 'hidden',
'value'=>'1',
),
));
$this->add(array(
'name' => 'id',
'attributes' => array(
'type' => 'hidden',
),
));
$subForm = new \Zend\Form\Form();
$subForm->setName('name');
$subForm->add( array(
'name' => 'ca',
'type' => 'text',
));
$subForm->add( array(
'name' => 'en',
'type' => 'text',
));
$subForm->add( array(
'name' => 'es',
'type' => 'text',
));
$this->add($subForm);
$this->add(array(
'name' => 'acronym',
'attributes' => array(
'type' => 'text',
'placeholder' => 'acronym',
'class' => 'docnet-form-acronym-entity',
),
));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'class' => 'btn',
'value' => 'add',
'id' => 'submitbutton',
),
));
I made this form because I had an array to the element name. To list it it works but now I want to edit and I can't get validated.

I think you should use a Zend\Form\Fieldset instead of a sub form. It makes the validation a lot easier. ZF2 actually has a useful example in the docs on collections.

Related

cannot pass data from form to model zend 2.3

I am trying to insert data into seviral tables using tablegateway. I am getting the following error.
Fatal error: Call to a member function saveStudent() on a non-object in C:\xampp\htdocs\disability\module\Admin\src\Admin\Controller\AdminController.php on line 48
I tryed to implement the solution given here Zend\Form: Call to a member function insert() on a non-object in Zend/Form/Fieldset.php
But nothing changed error is the same. Here is my form's code
<?php
namespace Admin\Form;
use Zend\Form\Element;
use Zend\Form\Form;
class AddstudentForm extends Form
{
public function __construct($name = null)
{
// we want to ignore the name passed
// parent::__construct('addstudent');
parent::__construct('AddstudentForm');
$this->add(array(
'name' => 'fio',
'type' => 'Text',
'options' => array(
'label' => 'Фио',
),
));
$this->add(array(
'name' => 'gender',
'type' => 'Zend\Form\Element\Radio',
'options' => array(
'label' => 'Пол',
'value_options' => array(
'0' => 'М',
'1' => 'Ж',
),
),
));
$this->add(array(
'name' => 'birthdate',
'type' => 'Text',
'options' => array(
'label' => 'Дата рождения',
),
));
$this->add(array(
'name' => 'edge',
'type' => 'Text',
'options' => array(
'label' => 'Возраст',
),
));
$this->add(array(
'name' => 'university',
'type' => 'Text',
'options' => array(
'label' => 'Учебное заведение',
),
));
$this->add(array(
'name' => 'group',
'type' => 'Text',
'options' => array(
'label' => 'Группа/класс',
),
));
$this->add(array(
'name' => 'department',
'type' => 'Text',
'options' => array(
'label' => 'Факультет',
),
));
$this->add(array(
'name' => 'grate',
'type' => 'Zend\Form\Element\Radio',
'options' => array(
'label' => 'Курс',
'value_options' => array(
'0' => '1',
'1' => '2',
'2' => '3',
'3' => '4',
'4' => '5',
'5' => '6',
),
),
));
$this->add(array(
'name' => 'enterence',
'type' => 'Text',
'options' => array(
'label' => 'Год поступления',
),
));
$this->add(array(
'name' => 'financesource',
'type' => 'Zend\Form\Element\Radio',
'options' => array(
'label' => 'Источник финансирования',
'value_options' => array(
'0' => 'Бютжет',
'1' => 'Контракт',
),
),
));
$this->add(array(
'name' => 'studyform',
'type' => 'Zend\Form\Element\Radio',
'options' => array(
'label' => 'Форма обучения',
'value_options' => array(
'0' => 'Дневная',
'1' => 'Заочная',
),
),
));
$this->add(array(
'name' => 'homeaddress',
'type' => 'Text',
'options' => array(
'label' => 'Домашний адрес',
),
));
$this->add(array(
'name' => 'actualaddress',
'type' => 'Text',
'options' => array(
'label' => 'Фактический адрес',
),
));
$this->add(array(
'name' => 'phone',
'type' => 'Text',
'options' => array(
'label' => 'Телефон',
),
));
$this->add(array(
'name' => 'workplace',
'type' => 'Text',
'options' => array(
'label' => 'Место работы',
),
));
$this->add(array(
'name' => 'services',
'type' => 'Zend\Form\Element\Textarea',
'options' => array(
'label' => 'Услуги',
),
));
$this->add(array(
'name' => 'submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Сохранить',
'id' => 'submitbutton',
),
));
}
}
and controller:
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* #link http://github.com/zendframework/Admin for the canonical source repository
* #copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* #license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Admin\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Admin\Model\Admin;
use Admin\Form\AddstudentForm;
class AdminController extends AbstractActionController
{
protected $StudentTable;
public function indexAction()
{
return array();
}
public function getStudentTable()
{
if (!$this->StudentTable) {
$sm = $this->getServiceLocator();
$this->studentTable = $sm->get('Admin\Model\StudentTable');
}
return $this->StudentTable;
}
public function addstudentAction()
{
$form = new AddstudentForm();
// $form->get('submit')->setValue('Сохранить');
$request = $this->getRequest();
if ($request->isPost()) {
$admin = new Admin();
$form->setInputFilter($admin->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$admin->exchangeArray($form->getData());
$this->getStudentTable()->saveStudent($admin);
// Redirect to list of albums
// return $this->redirect()->toRoute('admin');
}
}
return array('form' => $form);
// return array();
}
public function fooAction()
{
// This shows the :controller and :action parameters in default route
// are working when you browse to /admin/admin/foo
return array();
}
}
What could be wrong with that. Or what info do you need?
You have a typo in your getStudenTable() method and therefore $this->getStudentTable() returns null.
$this->studentTable = $sm->get('Admin\Model\StudentTable');
should be
$this->StudentTable = $sm->get('Admin\Model\StudentTable');

form filters in zendframework 2

I've been developing a web site using zend framework 2, I created a form with zend, and I added some filters on its inputs, but it seems they're not working. I made some researches and almost all examples I found, put the filters in the model methods, which I don't really appreciate. So my question is how to set correctly the filters and validators in the Form class ?
Here is the way I defined my Form Class :
class AddPizzaForm extends Form
{
public function __construct()
{
parent::__construct('addpizzaform');
$this->add(array(
'name' => 'pizza_name',
'type' => 'text',
'required' => true,
'filters' => array('StringTrim', 'StringToLower'),
'options' => array('label' => 'Pizza name')));
$this->add(array(
'name' => 'ingredients',
'type' => 'textarea',
'options' => array('label' => 'Ingredients')));
$this->add(array(
'name' => 'small_price',
'type' => 'text',
'options' => array('label' => 'Small price')));
$this->add(array(
'name' => 'big_price',
'type' => 'text',
'options' => array('label' => 'Big price')));
$this->add(array(
'name' => 'family_price',
'type' => 'text',
'options' => array('label' => 'Family price')));
$this->add(array(
'name' => 'party_price',
'type' => 'text',
'options' => array('label' => 'Party price')));
$this->add(array(
'name' => 'add_pizza',
'type' => 'submit',
'attributes' => array(
'value' => 'Add New Pizza',
'id' => 'submitbutton')));
}
}
Thank you so much.

Validation Form in ZF2

How i can a validate input data in my from email and password fields, if email field must contains only valid E-mail address and password between 6 and 12 length characters?
My form code:
namespace Notes\Form;
use Zend\Form\Form;
use Zend\InputFilter\InputProviderInterface;
use Zend\InputFilter\InputFilter;
use Zend\Validator\ValidatorInterface;
use Zend\InputFilter\Factory as InputFactory;
class AuthorizationForm extends Form
{
public function __construct($name = null)
{
parent::__construct('auth');
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'email',
'attributes' => array(
'type' => 'text',
'style' => 'width: 250px;',
),
));
$this->add(array(
'name' => 'password',
'attributes' => array(
'type' => 'password',
'style' => 'width: 250px;',
),
));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Login',
'id' => 'submitbutton',
'class' => 'fbutton green',
),
));
$this->add(array(
'type' => 'Zend\Form\Element\Checkbox',
'name' => 'save_login',
'options' => array(
'label' => 'Remember me ',
'checked_value' => '1',
),
));
}
}
Thanks for answers!
Add these validators into your Model file:
// For email validation
'validators' => array(
array('regex', true, array(
'pattern' => '/[A-Z0-9._%-]+#[A-Z0-9.-]+\.[A-Z]{2,4}/i',
'messages' => 'Your error message here...'))
),
// For character length validation
'validators' => array(
array(
'name' => 'Between',
'options' => array(
'min' => 6,
'max' => 12,
),
),
),
I hope this helps.
There is inbuilt validator for email validation that will go like this,
'validators' => array(
array('EmailAddress',true)
)
also for more detailed information visit the following,
http://zend-framework-community.634137.n4.nabble.com/ZF2-How-to-validate-a-password-and-email-in-zend-framework-2-td4657533.html

Rendering and process same form twice in Zend Framework 2?

I have a requirement of rendering and processing the same form again if user check a select box. I looked into form collections but it didn't exactly access my problem because I don't need to render a set of fields instead my requirement is to render the complete form again. So what I added another function getClone($prefix) to get the clone of form which returns me the clone of form object after adding a prefix in the name of form. Like this
<?php
namespace Company\Form;
use Zend\Form\Form;
use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
class CompanyAddress extends Form implements InputFilterAwareInterface {
protected $inputFilter;
public function __construct($countries, $name = 'null') {
parent::__construct('company_address');
$this->setAttribute('method', 'post');
$this->setAttribute('id', 'company_address');
$this->add(array(
'name' => 'street_1',
'attributes' => array(
'id' => 'street_1',
'type' => 'text',
),
'options' => array(
'label' => 'Street *',
)
));
$this->add(array(
'name' => 'street_2',
'attributes' => array(
'id' => 'street_2',
'type' => 'text',
),
'options' => array(
'label' => 'Street 2',
)
));
$this->add(array(
'name' => 'country_id',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'id' => 'country_id',
),
'options' => array(
'label' => 'Country',
'value_options' => $countries
)
));
$this->add(array(
'name' => 'city_id',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'id' => 'city_id',
),
'options' => array(
'label' => 'City ',
'value_options' => array()
)
));
$this->add(array(
'name' => 'zip',
'attributes' => array(
'id' => 'zip',
'type' => 'text',
),
'options' => array(
'label' => 'ZIP',
'value_options' => array()
)
));
$this->add(array(
'name' => 'address_type',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'id' => 'zip',
),
'options' => array(
'label' => 'Type',
'value_options' => array(
'' => 'Select Type',
'default' => 'Default',
'invoice' => 'Invoice',
'both' => 'Both',
)
)
));
}
public function getClone($prefix){
$form = clone $this;
foreach($form->getElements() as $element){
$name = $element->getName();
$element->setName("$prefix[$name]");
}
return $form;
}
public function getInputFilter() {
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add($factory->createInput(array(
'name' => 'street_1',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array('message' => 'Street cannot be empty'),
),
),
)));
$inputFilter->add($factory->createInput(array(
'name' => 'street_2',
'required' => false,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
),
)));
$inputFilter->add($factory->createInput(array(
'name' => 'city_id',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array('message' => 'City cannot be empty'),
),
),
)));
$inputFilter->add($factory->createInput(array(
'name' => 'country_id',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array('message' => 'Country cannot be empty'),
),
),
)));
$inputFilter->add($factory->createInput(array(
'name' => 'zip',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array('message' => 'ZIP cannot be empty'),
),
),
)));
$inputFilter->add($factory->createInput(array(
'name' => 'address_type',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array('message' => 'Address Type cannot be empty'),
),
),
)));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
}
and than in my action I did this
public function testAction() {
$countries = $this->getServiceLocator()->get('Country')->getSelect();
$companyAddressForm = new CompanyAddressForm($countries);
$clone = $companyAddressForm->getClone('address2');
if($this->request->isPost()){
$data = $this->request->getPost();
$companyAddressForm->setData($data);
$clone->setData($data['address2']);
$isFormOneValid = $companyAddressForm->isValid();
//$isFormTwoValid = $clone->isValid();
}
$view = new ViewModel();
$view->companyAddressForm = $companyAddressForm;
$view->clone = $clone;
return $view;
}
This is working as I expected it to work, forms are rendering and validating correctly, I want to know whether it is a correct way or a hack?
If both of the forms are exactly the same then you don't need to declare and validate two forms in the controller action.
Reason:
If there are two forms rendered your HTML page. Only one of the forms can be posted by the users at a time and you need to validate only one form at a time. What you are doing now is to validate the same form with the same post data over again. So either $isFormOneValid, $isFormTwoValid are both true or both false.
Instead, declare only one form, render it twice in your view, and upon post, validate it with the post data. If the two forms differ in properties, filters, validators, etc. then you can create two methods like $form->applyForm1Validarots() and $form->applyForm2Validarots, check the value of your select element, and call the appropriate method to apply the validaorts / filters before calling isValid() on it.
Hope I helped

zend framework 2 with doctrine 2 $form->getData() in controller not returning all fields set using $form->setData()

I have set my form for validation using $form->setData().
After validation I am not receiving all of my properties back using $form->getData().
I am using following lines in controller
and somehow $form->getData() is not returning all fields anyone has any idea why?
if ($request->isPost())
{
$company = new Company();
$form->setInputFilter($company->getInputFilter());
$form->setData($request->getPost());
print_r($request->getPost()); // getPost shows all fields fine
if ($form->isvalid())
{
print_r($form->getData()); // is returning only select and text type fields which are in input filter. why?
}
}
my form is looks like this.
class Companyform extends Form
{
public function __construct()
{
parent::__construct('company');
$this->setAttribute ('method', 'post');
$this->setAttribute ('class', 'form-horizontal');
$this->add(array(
'name' => 'id',
'attributes' => array(
'type' => 'hidden'
),
));
$this->add ( array (
'name' => 'title',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'id' => 'title',
'options' => array(
'mr' => 'Mr',
'miss' => 'Miss',
'mrs' => 'Mrs',
'dr' => 'Dr'
),
'value' => 'mr'
),
'options' => array(
'label' => 'Title'
)
));
$this->add(array(
'name' => 'fname',
'attributes' => array(
'id' => 'fname',
'type' => 'text',
'placeholder' => "First Name",
),
'options' => array(
'label' => 'First Name'
)
));
$this->add(array(
'name' => 'surname',
'attributes' => array(
'id' => 'surname',
'type' => 'text',
'placeholder' => "Surname Name",
),
'options' => array(
'label' => 'Surname Name'
)
));
$this->add(array(
'name' => 'companyName',
'attributes' => array(
'id' => 'companyName',
'type' => 'text',
'placeholder' => "Company Name",
),
'options' => array(
'label' => 'Company Name'
)
));
$this->add(array(
'name' => 'address1',
'attributes' => array(
'id' => 'address1',
'type' => 'text',
'placeholder' => "Address Line 1",
),
'options' => array(
'label' => 'Address'
)
));
$this->add(array(
'name' => 'address2',
'attributes' => array(
'id' => 'address2',
'type' => 'text',
'placeholder' => "Address Line 2",
),
'options' => array(
'label' => 'Address'
)
));
$this->add(array(
'name' => 'address3',
'attributes' => array(
'id' => 'address3',
'type' => 'text',
'placeholder' => "Address Line 3",
),
'options' => array(
'label' => 'Address'
)
));
$this->add(array(
'name' => 'btnsubmit',
'attributes' => array(
'id' => 'btnsubmit',
'type' => 'submit',
'value' => 'Add',
'class' => 'btn btn-primary'
),
));
}
}
and This is the input filter which I am using in entity company
public function setInputFilter(InputFilterInterface $inputFilter)
{
throw new \Exception("Not used");
}
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add($factory->createInput(array(
'name' => 'companyName',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 2,
'max' => 255,
),
),
),
)));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
Every single Form-Element has to get validated! Even if the validator is empty like
$inputFilter->add($factory->createInput(array(
'name' => 'title'
)));
Only validated data get's passed from the form.

Categories