I am not a newbie in Symfony and I've done a lot of forms in it. This problem first arose when I tried embedded forms. There were no errors that could be rendered in a template but method $form->getErrorsAsString() says that there are errors in a form.
After embedded forms didn't work, I tried the most simple example there is.
$ustanovaEntity = new Author();
$form = $formFactory->createBuilder('form', new Author())
->add('title', 'text')
->add('add', 'submit')
->getForm();
This is the most basic form and it does not show any errors. $form->getErrors() return an empty array but still, $form->getErrorsAsString() shows that there is an error if I leave title blank.
Also, I checked form_div_layout.html.twig in the error block and the errors twig variable is blank. There are no errors. Still, $form->getErrorsAsString() show errors do exist.
I tried reinstalling symfony, i tried deleting vendor directory and coping the same dir from diffrenet symfony project, i tried even simple examples, i tried... Nothing works.
I am seriously starting to think that something is wrong with my head.
Anyone help?
EDIT
I installed a fresh symfony edition and putted all the files from my project to that new symfony insall. Still didn't work.
I also tried the most simple approach...
{{ form(form, {'attr': {'novalidate': 'novalidate'}}) }}
Still not working.
If you just want to get errors from all child forms, you can do:
$form->getErrors(true);
This will traverse through root and all child forms and get all errors. See FormInterface::getErrors method
The reason for this is that your errors aren't on base form, they are on child forms, to get errors of child form you just get it from it's parent and get it's errors:
$form->get('title')->getErrors();
If you want all errors from child forms to actually be on root form, you need to turn on error bubbling, for example:
$form = $formFactory->createBuilder('form', new Author())
->add('title', 'text', ['error_bubbling' => true])
->add('add', 'submit')
->getForm();
Like this, you will get all errors from children that have error bubbling enabled on the root form, as you are trying to do from the start:
$form->getErrors();
Have in mind that hen using error bubbling, error's won't be available on actual child form where it appeared, so now this will be empty:
$form->get('title')->getErrors();
Related
I've been breaking my head on the Symfony2.1 form validation. What I want is just a regular list on top of the form with the errors it contains after validation. An extensive search did not result in the wanted solution.
There are a couple of questions left:
How can I globally disable field-specific errors, so errors won't appear aside of the field? I know about the error_bubbling, but it shouldnt be needed to set this for each field.
How can I parse all the error in a simple list on top of the form? I know how to override the Twig templates, but this does not result in a group of errors that is accessible by the form_errors function
What I found / investigated so far:
Make all form validation errors show up at top in symfony?
Form-wide error_bubbling in Symfony 2? > is terrible if you've got more then 4 forms
http://symfony.com/doc/current/book/forms.html > does not has the right solution
https://stackoverflow.com/a/8216192/1794894 > could be a solution, but is not a nice one
There are 2 methods i can think of for disabling the errors:
Hide them with CSS.
Override the Twig templates and remove the error output.
As to listing out all the error on the top, that is a bit harder. Best bet would be to pull the list of form fields and loop through them outputting the errors.
I have a problem with all my forms in symfony 1.4. They work with good datas, my new objects are created ... But when i give bad datas, my forms do nothing as expected but have no errors.
My code in my action :
$this->form = new EtablissementForm();
$this->form->bind(
$request->getParameter($this->form->getName()),
$request->getFiles($this->form->getName())
);
Edit :
Solved. I guess i need some sleep. This was really a dumb mistake. I was sure i had removed a new E...Form(); In my view for my action, actually i did it ... in another file.
So my $form was overwritten by an empty form. So the problem is solved.
if ($this->form->isValid())
{
//some things and a redirect
}
In a nutshell, my form works with good datas. But i don't have any errors to display when i'm giving bad datas. And my form don't add something in my database. Validations works cause it raise exception in bind, but i just get an empty form to display.
Your view needs to have proper scope to $form. Your code above may be incomplete. In the action you show above, if the action ends, and you go to your view, and your view has the following, your validation errors should appear inline with your form.
<?php echo $form ?>
I want to know if it is possible to access all of my form's errors without using form_bubbling since it gives the error to the parent and individual objects loose their error...I need both the form to know globally if there are errors to display a global "please fix your errors" message and the individual elements to know if they contain errors because I will add an error CSS class to invalid form inputs.
Thanks in advance!
Most efficient way I found to get the numbers of errors of a form, regarless its form_bubbling is trueor false is to add, in the controller, some variable indicating it :
return $this->render('Acme:Contrats:index.html.twig', array(
'myform' => $form->createView(),
'myformHasErrors' => !$form->isValid(),
));
If anyone find another one, please comment/answer this.
After speaking to people in Symfony's IRC channel, there exists two ways to do this in a Twig template:
form.has('errors') for a boolean stating whether or not the form contains errors.
form.vars.errors|length for the number of errors contained in the form.
Problem solved. All of this can be used without using error_bubbling.
Is there any way to do that with a decorator or do I need to dig deeper into ZF?
If you have multiple validators attached to one form element and want only the first error message to pop up, you can set breakChainOnFailure option to TRUE for each validator. In this case, if one of the validators fails, all the subsequent validators are skipped.
$element->addValidator(
new Zend_Validate_StringLength(array('min' => 6, 'max' => 12)),
true)
->addValidator(new Zend_Validate_Alnum());
if $foo is in an instance of Zend_Form and there is an form element username inside this form then
$foo->username->getMessages() ; will return array of errors messages to show only one you simply need to do array_pop($foo->username->getMessages()); . Basically zend decorators uses error view helper to display the messages . You need to extend the default decorator and remove the view helper simply by echo
There are many ways you can do this. My personal favorite is to extend the validator you want to use to only return one custom message. For the email validator this is especially helpful since it shows some crazy error messages that you may not want to show anyway. You can see this method here: http://clintberry.com/2010/07/zend-form-email-validator-customizing-error-messages/
I am having a few problems with Dojo Filtering Selects when using the Zend Framework Forms and need some help to find out what I have missed as this is driving me mad.
I am currently getting this errors in firebug:
dojo.data is undefined
dojo.data.ItemFileReadStore is not a constructor
Below is the code that I am using to create the filter select and provide the json data to the calling controller.
Zend_Form Element (Dojo Enabled)
$industry = new Zend_Dojo_Form_Element_FilteringSelect('industry');
$industry->setAutocomplete(true)
->setStoreId('industrystore')
->setStoreType('dojo.data.ItemFileReadStore')
->setStoreParams(array('url' => $baseUrl.'/dojo/industry'))
->setAttrib("searchAttr", "title")
->setRequired(true)
->removeDecorator('DtDdWrapper')
->removeDecorator('label')
->removeDecorator('HtmlTag');
Dojo Controller
public function industryAction(){
$db = Zend_Db::factory($this->config->database);
$result = $db->fetchAll("SELECT * FROM industries");
$data = new Zend_Dojo_Data('industryid', $result);
$this->_helper->autoCompleteDojo($data);
$db->closeConnection();
}
The annoying thing is all my other Dojo elements on this form and other forms work well it is just whenever I do Filtering Selects that I hit these problems, and this problem causes all the other elements in a form to fail too.
Thanks in advance.
The problem is actually with how Zend Framework initializes the dijits and data stores before the toolkit is fully loaded, in this case specifically the methods assigning the store to the dijit. I ran into this issue as well and found the best way to work around the issues was to either pass the data store from the controller to a JavaScript variable defined in the view or do what your did with a specific autocomplete action. Based on your example I would make the following changes.
In your form I would simplify the element:
$industry = new Zend_Dojo_Form_Element_FilteringSelect('industry');
$industry->setAutocomplete(true)
->setRequired(true)
->removeDecorator('DtDdWrapper')
->removeDecorator('label')
->removeDecorator('HtmlTag');
In your view you want to connect the store to your dijit and make sure that you have loaded the dojo.data.ItemFileReadStore module:
<?php $this->dojo()->onLoadCaptureStart()?>
function(){
dijit.byId('industry').store = new dojo.data.ItemFileReadStore({ url: '/controller/industry' });
}
<?php
$this->dojo()->onLoadCaptureEnd();
$this->dojo()->requireModule('dojo.data.ItemFileReadStore');
?>
As I mentioned I ran into a similar issue which I answered here . Another issue I discovered is that the data store does not like dealing with labels declared anything other than "name" for the label declaration in the Zend_Dojo_Data.