I am quite new to Symfony 2.7. I am facing a problem with Symfony form.
Inside my form i have a form field as follows
Builder->add('passDate', 'hidden')
->add('issueDate','hidden')
Inside my controller function, i need to pass some fix value to database. So here is my form action
$entity->setIssueDate('1950/01/01');
$entity->setPassDate('1950/01/01');
But when i submit it, it show me the error as that these form fields are required, although i set as default date as 1950/01/01. Please help me. Thank you
You can either remove the NotBlank symfomy validator mapping from the two fields or use the empty_data option which will populate default values if the hidden fields weren't filled via JavaScript like this:
$builder->add('passDate', 'hidden', array(
'data' => null,
'empty_data' => '1950/01/01'
)
Related
I am getting trouble with symfony2 forms which is overriding my entity's data by null if the corresponding form input is not submitted.
Here is an example:
Form type:
$builder
->add('customerid', 'text')
->add('field1', 'text')
->add('field2', 'text')
...
Controller :
$customer = new Customer();
$customer->setId('the customerID');
$customerForm = $this->createForm(new CustomerType(), $customer);
if ($request->getMethod() == 'POST') {
$customerForm->bind($request);
...
}
On the view, i don't render the customerid text field.
Only others fields are submitted.
After submitting the form, $customerForm->bind($request); is overriding the previously setted customerID by null even if no empty value was submitted for it.
Is there any way to not override the value if the input fields was not rendered?
Here seems to be the same problem :
https://github.com/symfony/symfony/issues/1341
A patch was submitted but i did not found documentation on how to use it.
Thanks
Any field in the form (whether rendered or not) will have a value, either null or the value of the field.
Which version of Symfony are you using?
I assume you're using <2.3 as I think bind was changed to submit at 2.3.
With bind every field is merged into the object meaning it will replace the data, null or otherwise.
I think the only way to work around this would be to either just not include the unwanted fields in the form or the use an event listener as documented in the cookbook.
If you are using 2.3+ (or you upgrade to 2.3+) then you should be using $form->submit() which has a second argument which allows you to set the form to not overwrite object properties if they are null. eg $form->submit($request->get($form->getName()), false) (true being the boolean to set/unset the overwrite, or $clearMissing on the actual code)
I have a pretty simple form with some fields from a doctrine model.
$this->widgetSchema['fields'] = new sfWidgetFormDoctrineChoice(array(
'model' => 'FieldModel',
'expanded' => true,
'multiple' => true,));
$this->validatorSchema['fields'] = new sfValidatorDoctrineChoice(array(
'model' => 'FieldModel',
'multiple' => true,));
The fields are rendered in the form as checkboxes and I'm able to check and save correctly. This 'fields'-field is converted to a json-structure and saved to the database as text. So far so good.
NOTE: The field 'fields' is stored as TEXT in the database, but the user should be able to select values from a list of checkboxes.
The problem arise when I want to have some of the checkboxes checked by default.
I tried to do:
$this->setDefault('fields', array('key1','key2','key3'));
Where 'keyX' correspond to the actual value of the primary key (string) for Field in the database.
If I do a
$this->getDefault('fields');
I get back exactly what I put in previously.
However, symfony is not outputing any of the checkboxes as checked. I have even tried to remove both the 'expanded' and 'multiple' options to the choice-widget so I get a simple SELECT-box and the provide only one value as default selected.
Setting default values for other widgets (text-inputs, choice, etc) work.
Btw; The Field-model is i18n. Don't know if that matters here, since both storing / retrieving works as expected.
Also; the form is rendered as part of another form by means of include_partial(). Can that sabotage anything? In the 'parent' form class:
$this->embedRelation('TheRelationThatBugsMe');
And then in the _form.php for the 'parent':
include_partial('the_relation_that_bugs_me/form', array('form' => $form['TheRelationThatBugsMe']));
Does anyone have an idea where I might have gone wrong, or at least can give me some pointers as to where I should start digging?
[UPDATE]
If I create a new field in the form 'fields2' (that does not exist as a field in the database) and use the exact same code to create widget, validator and set defaults, then the defaults are rendered correctly. How come it doesn't work setting defaults for a field mapped to a column in the database?
If you're calling setDefault before updateDefaultFromObject gets called in sfDoctrineForm, then the object's values will override form defaults if the object exists. updateDefaultsFromObject contains the relevant logic. You'll have to call setDefault later, or override the method.
My action:
public function executeEdit(sfWebRequest $request)
{
// Get the object
$article = $this->getRoute()->getObject();
// Create the form
$this->form = new ArticleEditForm( $article );
}
You can see that $article is the Doctrine Collection that gets passed to the Form as default values. The $article object contains a fields like "title", "text", "author", etc.
But this causes an error in the Form creation:
500 | Internal Server Error | Doctrine_Record_UnknownPropertyException
Unknown record property / related component "_csrf_token" on "article"
So basically, the form is trying to use the Doctrine Collection to fill out default values for the form elements. But there obviously isn't a csrf_token in that object... But it's still trying to find one to use as the default value...
And what happens if you have a form where there are always extra empty fields that are empty but others have default values that are passed. If those empty fields don't have set values in the Doctrine Collection then you get an error...
Now, obviously I could just make a simple array ahead of time where I specify the default values and pass that:
$defaults = array( 'title' => $article->title, 'text' => $article->text, 'author' => $article->author );
$this->form = new ArticleEditForm( $defaults);
This works. My problem is that the above "article" is an example for simplicity reasons. In reality my form has about 30 fields in it. So the only way that this solution would work is to have to manually specify 30 individual default values in an array. This is a poor solution from a maintenance point-of-view, obviously.
I figure the Symfony developers are smart enough to come up with a good solution but I just can't find it... Any clues?
This problem is all about your form doesn't create _csrf_token. You can add it when creating form in your template page like:
<?php
echo $form->renderFormTag(url_for('article/edit'))
echo $form->render();
?>
<input type="hidden" name="form[_csrf_token]" value="<?= $form->getCSRFToken(); ?>">
<input type="submit" value="Submit" />
</form>
I discovered my problem. My custom form was extending BaseForm. Once I changed this to extend BaseArticleForm then I was able to successfully pass article Doctrine Collections in as default values.
I am using the symfony embedRelation method to embed forms.The code is like this:
public function configure(){
//......
$this->embedRelation('Foos as foos');
$this->getEmbeddedForm('foos')->mergePostValidator(new MenuValidatorSchema());
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
this does not work.
}
When embeding forms in Symfony, the top-level form keeps track of everything. The widget schema, validator schema, defaults, etc. of the embedded form are no longer directly used. You can see what's happening in sfForm::embedForm.
Note that in this case, since it's a post validator, it's perfectly acceptable to add it to the top-level form, i.e.:
$this->mergePostValidator(new MenuValidatorSchema());
If you want the validator schema on the embedded form and it has no current post validator, you can simply do:
$this->validatorSchema['foos']->setPostValidator(new MenuValidatorSchema());
If it has an existing one, you'll have to turn them into an sfValidatorAnd, doing something like:
$this->validatorSchema['foos']->setPostValidator(new sfValidatorAnd(array(
'validators' => array(
$this->validatorSchema['foos']->getPostValidator(),
new MenuValidatorSchema()
)
)));
The syntax of that last option is just one reason why setting post validators on the top-level form is the preferred option when available.
I’m using Zend_Filter_Input to validate form data and want to customize the error messages, if a user does not enter a value. It is important that each field gets a different error message.
With Zend Framework 1.8.0 I used the following array for the “validator” parameter of Zend_Filter_Input:
$validators = array(
'salutation' => array(
new Zend_Validate_NotEmpty(),
Zend_Filter_Input::MESSAGES => array(
Zend_Validate_NotEmpty::IS_EMPTY => "Please enter a salutation"
)
),
/* ... */
);
Since I’ve upgraded to ZF 1.8.4, I always get the default message for empty fields (“You must give a non-empty value for field '%field%'”). Obviously Zend_Filter_Input does not call the Zend_Validate_NotEmpty validator anymore, if the field is empty.
Is there a way to change this behavior or another way to get customized “empty” messages for each field?
It seems that Zend_Filter_Input changed its behaviour when handling empty fields. Empty fields are never processed by rule validators. If a field is empty and allowEmpty is set to true, none of your validators are used. If the field is empty and allowEmpty is set to false, then the default message for empty values is set. Currently there is no way to customize this message for a specific field.
The behavior has not changed. This is a bug (http://framework.zend.com/issues/browse/ZF-7394)
try this:
$validators = array(
'salutation' => array('NotEmpty', Zend_Filter_Input::MESSAGES => 'Please enter a salutation')
);
I don't know why, but seems they changed the constant "isEmpty" with "NotEmpty" (without including it in the Zend_Validate_NotEmpty class).
Sometimes I just go nuts with Zend. :)