No validations errors to display in symfony 1.4 form - forms

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 ?>

Related

Symfony2 No Errors in Form

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();

Cakephp Controller isn´t processing form data

Hi I´m new with cakephp (v.1.3). I´m trying to do something simple.
I have two tables: fichas[id,... etc] and labos[id,laboratorio,ficha_id] so "labos" belongs to "fichas". (labos.laboratorio is ENUM field).
I would like to view a "ficha" given labos.id and labos.laboratorio so I´ve included the following code in "home.ctp"
<h3>Mostrar Ficha</h3>
<?php echo $this->Form->create('ficha',array('action'=>'localiza'));?>
<?php echo $this->Form->radio('laboratorio',array('A','B','C'),array('A','B','C')); ?>
<?php echo $this->Form->input('id',array('label'=>'Numero','type'=>'text')); ?>
<?php echo $this->Form->end("Mostrar");?>
Then in "fichas_controller.php" added the following:
function localiza(){
$laboratorio=$this->data['Ficha']['laboratorio'];
$id=$this->data['Ficha']['id'];
if(!$id){
$this->Session->setFlash('Por favor introduzca un valor valido');
$this->redirect(array('action'=>'index'));
}
$this->set('fichas',$this->Ficha->findID($id,$laboratorio));
}
Finally in the model "ficha.php" the following:
function findID($id=null,$laboratorio=null){
return $this->find('all',array('conditions'=>array('Labo.laboratorio'=>$laboratorio,'Labo.id'=>$id)));
}
Obviously the file views/fichas/localiza.ctp exists
The thing is when I press the submit button in the form it just reloads the home.ctp page. Looks like the controller´s code is not being executed because i´ve tried to force the error message that should load the index action changing the if condition to true but the same result. I´ve changed the name of the function in the model expecting an error to ocurr but I get the same result.
I have another two forms in the home.ctp page but calling another actions and models.
One of them its almost identical and it works fine.
I can´t figure out the error.
Thanks in advance for any help.
Marcelo.
The array key $this->data['Ficha'] likely doesn't exist. You've created the lowercase "ficha" form, this name should be capitalized, otherwise the data is available in $this->data['ficha']. So the form creation call would look like this:
<?php echo $this->Form->create('Ficha',array('action'=>'localiza'));?>
You can debug in two ways on Cake
Configure::write('debug', 2);
debug($this->data);
OR
The other PHP ways
print_r($this->data);
This way, you will know if you are passing the data->params properly.
Why is your model has first charcter in lower-case? It should be
Fichas
Labos
Then you can issue a direct find on the controller, if you only want.
$d = $this->Fichas->find('all', array();
You might have added the home.ctp file into another controller. Try adding the controller in the following line:
<?php echo $this->Form->create('ficha',array('controller' => 'fichas', 'action'=>'localiza'));?>
Hope it helps.

I'm not specifying the form action but it (automatically) gives different values in some cases

I'm creating my form using the Form helper, so the action of the form is specified automatically....
this form is used for editing a post..
so, the URL has the structure: mywebsite.com/posts/edit/id
and the form's action should be automatically generated as posts/edit/id
but the problem is, in some cases, I open the HTML code and I find that the form's action is only posts/edit without the id which causes the update to fail...
I spent a lot of time to figure out what situation brings this wrong action:
i'm generating fields dynamically (using javascript & ajax) depending on the post's category..
when the value of one of the dynamically generated fields is invalid, the generated action becomes posts/edit !!
I really need help, cuz I don't know why this is happening !!!
and I don't wanna waste more time digging into the core of cakephp...
so, if any of cakephp experts has an idea about this, plz help me !!
thank you in advance !
Use the url parameter, which allows you to explicitly define a url for the form:
echo $form->create('Post', array('url' => $html->url(array('action'=>'edit', $id))));
It sounds like $id probably isn't getting set, because it should be getting passed along if it is. You need to make sure it's set to edit the record in question. Make sure your javascript is including the hidden field with the record's id in it.
Normally done like this, with the form helper: echo $this->Form->input('id');
Also, if one of the fields is invalid, the form shouldn't actually be submitting properly, if you are using cake's validation, so this is to be expected.

Zend Framework: Post to different action then return to original action if fails validation AND keep form fields

This might sound like an odd scenario, but I've got two forms on one page. One is just posting back to itself. I made the second post to another action to keep the code cleaner. Maybe not the right choice...
The problem I'm having now is that if that second form doesn't validate, I redirect back to the page with the form but I don't know how to keep my form fields filled in with the original information the user entered. Is there a way to do that and keep posting to two separate actions, or do I need to just bite the bullet and have both forms post back to the same action and deal with the messy logic?
I would submit both forms to the same action. There really shouldn't be anything too messy about it. In each form include a hidden field to signify which form is being submitted.
Application_Form_Login:
/* other form elements */
$this->addElement('hidden', 'login', array(
'value' => 1
));
Application_Form_Register:
/* other form elements */
$this->addElement('hidden', 'register', array(
'value' => 1
));
Controller:
$loginForm = new Application_Form_Login();
$registerForm = new Application_Form_Register();
if($this->_request->isPost()) {
if($this->_request->getPost('login')) {
if($loginForm->isValid($this->_request->getPost())) {
// validated, redirect
$this->_helper->redirector('profile', 'user');
}
}
if($this->_request->getPost('register')) {
if($registerForm->isValid($this->_request->getPost())) {
// validated, proceed as needed
}
}
}
$this->view->loginForm = $loginForm;
$this->view->registerForm = $registerForm;
View:
echo $this->loginForm;
echo $this->registerForm;
With this type of a setup, if either of your forms fail validation, isValid() will preserve any data that has been entered and you still redirect on a successful validation of one or both of the forms.
Personally, I think that each form should post to its own controller, as you have. This keeps the code for processing that form in a single place. The issue here is that you want to return to the original page on failed validation. But why? Why not simply redisplay the form in the target controller, just like you would if there were a single form on the page?
For example, consider a login form that appears on every page of a sie (perhaps because it in the site template/layout). It posts to something like AuthController::loginAction(). If the login fails, then you don't typically send him back to the page from which he came. You leave him at the login page, with the form as pre-filled from the $_POST as you want it to be (probably a username, but not his password).
See this answer for a similar discussion.
Update: Had another thought in this. If you really want to handle the processing in two different controllers in order to keep him on the page from which he posted the form, at least extract that form processing out into an action helper. This way, you could at least keep that form-processing DRY.
Update: Rob Allen has just written a great blog post "A form in your layout" in which he describes a method that uses an action-helper with a preDispatch() method that instantiates and processes the form. Very nice.
How do you redirect? I don't see the problem if you just display the form page again. You can prefill you forms using Zend_Form::populate().
Well, I would just keep both forms submitting on the same page.
I don't see why your code should get any less readable. Learn how to use action helpers and your controllers will suddenly look extremely simple and readable:
public function indexAction()
{
$request = $this->getRequest();
// send forms to view, so we can print them
// but also so we can access them in action helpers
$this->view->form = $this->_getForm('Form1', '/');
$this->view->form2 = $this->_getForm('Form2', '/');
if ($request->isPost())
{
// process the first form
if (isset($_POST['form_submit_button']) && $this->view->form->isValid($_POST))
{
$this->_helper->form($this->view->form->getValues());
}
// process the second form
else if (isset($_POST['form2_submit_button']) && $this->view->form2->isValid($_POST))
{
$this->_helper->form2($this->view->form2->getValues());
}
}
Each form's processing would have its own action helper.

dojo.data is undefined Flitering select

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.