$ form-> isValid says this is not valid, but my form does not display an error message - Zend Framework 2

I have a problem with addAction in my CRUD application. On the controller, the logic does not pass the check $ form-> isValid (), but the error message is not displayed on the form.

I tried with this (thanks to Sam):

foreach($form->get('product')->getElements() as $el) { echo $el->getName()." = ".$el->getValue()." > ".$el->getMessages()." <br/>"; } 

This displays only the name and value of the field, but not the error message.

I tried to allow the form to be completely empty, and the error message β€œValue is required and cannot be empty” lights up, but then I fill each field one at a time until I get more error messages, but the form is still invalid.

My form has a Fieldset field as a basic set of fields and a submit button. Inside the product field set, I have an identifier field, a name field, a price field, and a Fieldset brand. Inside my Fieldset brand, I have an id field. Like this:

ProductForm:

 class ProductForm extends Form { public function init() { // we want to ignore the name passed parent::__construct('product'); $this->setName('product'); $this->setAttribute('method', 'post'); $this->add(array( 'name' => 'product', 'type' => 'Administrador\Form\ProductFieldset', 'options' => array( 'use_as_base_fieldset' => true ), )); $this->add(array( 'name' => 'submit', 'type' => 'Submit', 'attributes' => array( 'value' => 'Add', 'id' => 'submitbutton', ), )); } } 

ProductFieldset:

 class ProductFieldset extends Fieldset implements ServiceLocatorAwareInterface { protected $serviceLocator; function __construct($name = null) { parent::__construct('product_fieldset'); $this->setHydrator(new ArraySerializableHydrator()); $this->setObject(new Product()); } public function init() { $this->add(array( 'name' => 'id', 'type' => 'Hidden', )); $this->add(array( 'name' => 'name', 'type' => 'Text', 'options' => array( 'label' => 'Name', ), )); $this->add(array( 'name' => 'price', 'type' => 'Text', 'options' => array( 'label' => 'Price', ), )); $this->add(array( 'name' => 'brand', 'type' => 'BrandFieldset', )); } public function setServiceLocator(ServiceLocatorInterface $sl) { $this->serviceLocator = $sl; } public function getServiceLocator() { return $this->serviceLocator; } } 

BrandFieldset:

 class BrandFieldset extends Fieldset { function __construct(BrandTable $brandTable) { parent::__construct('brand_fieldset'); //$this->setHydrator(new ClassMethodsHydrator(false))->setObject(new Brand()); $this->setHydrator(new ArraySerializableHydrator()); $this->setObject(new Brand()); $brandSelectOptionsArray = $brandTable->populateSelectBrand(); $this->add(array( 'name' => 'id', 'type' => 'Select', 'options' => array( 'label' => 'Brand', 'empty_option' => 'Please select a brand', 'value_options' => $brandSelectOptionsArray, ), )); } } 

This is my new Form statement in addAction:

 $formManager = $this->serviceLocator->get('FormElementManager'); $form = $formManager->get('Administrador\Form\ProductForm'); 

In my Product model, I have inputFilters, the required filter for the id field, the necessary filter for the name field. And for the Brand field, I created another inputFilter and added it to the main input filter:

 $brandFilter->add($factory->createInput(array( 'name' => 'id', 'required' => true, 'filters' => array( array('name' => 'Int'), ), ))); $inputFilter->add($brandFilter, 'brand'); 

The strange behavior is that my editAction works fine and has the same logic.

Is there any form of echo of the internal error message from the form, which helps me to understand WHY the form is invalid.

EDIT 2013-06-01

Here is my complete controller:

 class ProductController extends AbstractActionController { protected $productTable; protected $brandTable; public function indexAction() { return new ViewModel(array( 'products' => $this->getProductTable()->fetchAll(), )); } public function addAction() { $formManager = $this->serviceLocator->get('FormElementManager'); $form = $formManager->get('Administrador\Form\ProductForm'); $form->get('submit')->setValue('Add'); $request = $this->getRequest(); if ($request->isPost()) { $product = new Product(); $product->brand = new Brand(); $form->setInputFilter($product->getInputFilter()); $form->setData($request->getPost()); if ($form->isValid()) { $product->exchangeArray($form->getData()); $this->getProductTable()->saveProduct($product); // Redirect to list of products return $this->redirect()->toRoute('product'); } } return new ViewModel(array( 'form' => $form, )); } public function editAction() { $id = (int) $this->params()->fromRoute('id', 0); if (!$id) { return $this->redirect()->toRoute('product', array( 'action' => 'add' )); } // Get the Product with the specified id. An exception is thrown // if it cannot be found, in which case go to the index page. try { $product = $this->getProductTable()->getProduct($id); } catch (\Exception $ex) { return $this->redirect()->toRoute('product', array( 'action' => 'index' )); } $formManager = $this->serviceLocator->get('FormElementManager'); $form = $formManager->get('Administrador\Form\ProductForm'); $brand = $this->getBrandTable()->getBrand($product->brand); $product->brand = $brand; $form->bind($product); $form->get('submit')->setAttribute('value', 'Edit'); $request = $this->getRequest(); if ($request->isPost()) { $form->setInputFilter($product->getInputFilter()); $form->setData($request->getPost()); if ($form->isValid()) { $this->getProductTable()->saveProduct($form->getData()); // Redirect to list of products return $this->redirect()->toRoute('product'); } } return array( 'id' => $id, 'form' => $form, ); } public function deleteAction() { $id = (int) $this->params()->fromRoute('id', 0); if (!$id) { return $this->redirect()->toRoute('product'); } $request = $this->getRequest(); if ($request->isPost()) { $del = $request->getPost('del', 'No'); if ($del == 'Yes') { $id = (int) $request->getPost('id'); $this->getProductTable()->deleteProduct($id); } // Redirect to list of products return $this->redirect()->toRoute('product'); } return array( 'id' => $id, 'product' => $this->getProductTable()->getProduct($id) ); } public function getProductTable() { if (!$this->productTable) { $sm = $this->getServiceLocator(); $this->productTable = $sm->get('Administrador\Model\ProductTable'); } return $this->productTable; } public function getBrandTable() { if (!$this->brandTable) { $sm = $this->getServiceLocator(); $this->brandTable = $sm->get('Administrador\Model\BrandTable'); } return $this->brandTable; } } 
+7
source share
3 answers

Well, I got the answer: D

This is how addAction should be:

 public function addAction() { $formManager = $this->serviceLocator->get('FormElementManager'); $form = $formManager->get('Administrador\Form\ProductForm'); $form->get('submit')->setValue('Add'); $product = new Product(); $product->brand = new Brand(); $form->bind($product); // I need to bind the product to the form to pass the isValid() validation $request = $this->getRequest(); if ($request->isPost()) { $form->setInputFilter($product->getInputFilter()); $form->setData($request->getPost()); if ($form->isValid()) { $product = $form->getData(); $this->getProductTable()->saveProduct($product); // Redirect to list of products return $this->redirect()->toRoute('product'); } } return new ViewModel(array( 'form' => $form, )); } 

Obviously, I needed to link and remove the product object in the form in order to be able to pass the isValid () check. After that, I retrieve the product object from $ form-> getData ().

0
source

You can also do: $form->setBindOnValidate(false);

0
source

In my case, I went through an invalid input filter. isValid returns false, but $form->getMessages() empty. The OrderForm form had the following:

 $form->setInputFilter(new \Application\Form\UserInputFilter($er)); 

When I changed UserInputFilter to OrderInputFilter , it works.

0
source

All Articles