I get something strange with Symfony2 forms. I create a form with a propel entity, values are fine except the "select" (choices) field, that have no selected value.
I tried few tricks like:
$params['choices'] = array('N/A'=> 'N/A');
$params['data'] = array('N/A');
$params['preferred_choices'] = array('N/A');
Even with this, there is no preselected value. What's wrong ?
You can use data attribute for default selected item.
$param['data'] = 'N/A'
This is part of the Abstract "field" type ?
Fore example form,
$form = $this->createFormBuilder()
->add('category', 'choice', array(
'choices' => array(
0 => 'Books',
1 => 'Electronics',
2 => 'Hardware`
),
'data' => 1
))
->getForm();
In this example when the form loads the option Electronics should be selected as default
'empty_value' => 'Select Choice',
$builder->add('gender', 'choice', array(
'choices' => array('m' => 'Male', 'f' => 'Female')
'empty_value' => 'Select Choice',
));
I finally solved my problem. There were 2 things:
* reloading with Firefox, the previously selected value seems to be kept, so I coulnd't really test the changes until I closed the current tab and reopened one;
* I passed a single dimension array as values for the "choice" field, so Symfony2 re-indexed it with integer and my entity string value couldn't be hydrated to the symfony2 integer value of the field.
Related
i am making a shopping website and i got a probleme with some form. it's about the size part. I am gonna show some screenshots it's gonna be easier to understand :
what type of field is this kind of form ?
and then i would like the get this to show a list for client
i dont ask you to do the job for me but if you had some stuff (like a tutorial or some documentation about this kind of form) or some cluee i would really appriciate
Thx !
I'm not sure, but I think you are looking for Symfony's Form Types Reference.
In this case, you are probably talking about a choice field. A choice field can be rendered as a set of checkboxes / radio buttons (as in the first image), or as a <select> element (dropdown list), as in the second image, depending on wether the expanded option is set to true or false.
Radio buttons:
$builder->add('size', 'choice', array(
'choices' => array('s' => 'S', 'm' => 'M', 'l' => 'L', 'xl' => 'XL'),
'expanded' => true,
));
Dropdown list:
$builder->add('size', 'choice', array(
'choices' => array('s' => 'S', 'm' => 'M', 'l' => 'L', 'xl' => 'XL'),
'expanded' => false,
));
The default value of expanded is false, so if you don't specify it, the field will be rendered as a dropdown list.
If you have all available sizes stored in a table in your database, you might want to look at the entity field type as well. The entity type basically extends the choice type, but retrieves the available choices from the database:
$builder->add('size', 'choice', array(
'class' => 'MyWebshopBundle:Size',
'property' => 'name',
'expanded' => false,
));
This will fetch all Size entities from the database, and uses their name property in the dropdown list.
It's a choice type field
$form = $this->createFormBuilder($data)
->add('size', 'choice',
array('choices' => array(
1 => 'X',
2 => 'XL',
...
),
'data' =>'selectionnez la taille'
))
->getForm();
The option multiple can switch between radio button (false) and checkboxes ( true)
If you prefer a list like this you have to set the expanded attribute to false, true gives checkboxes or radios.
http://symfony.com/doc/current/reference/forms/types/choice.html
In my form I have a input field with multiple checkboxes.
This works as expected.
When for some reason (eg an obligated field in the form is empty upon submit) the form after submit is not posted, all other fields maintain there input except the field below, all checkboxes become unchecked.
What can I do to make this field remember it's settings?
$options = array(
'1' => 'one',
'2' => 'two',
'3' => 'three'
);
echo $this->Form->input('checkboxes',array(
'type' => 'select',
'multiple' => 'checkbox',
'options' => $options,
'default' => array(1,2,3)
));
FormHelper uses the $this->request->data to fill the fields. You need to keep (or fill) your data in request data array and the cakephp will maintain your data.
I'm trying to implement a ManyToMany relation in a form between 2 entities (say, Product and Category to make simpe) and use the method described in the docs with prototype and javascript (http://symfony.com/doc/current/cookbook/form/form_collections.html).
Here is the line from ProductType that create the category collection :
$builder->add('categories', 'collection', array(
'type' => 'entity',
'options' => array(
'class' => 'AppBundle:Category',
'property'=>'name',
'empty_value' => 'Select a category',
'required' => false),
'allow_add' => true,
'allow_delete' => true,
));
When I had a new item, a new select appear set to the empty value 'Select a category'. The problem is that if I don't change the empty value, it is sent to the server and after a $form->bind() my Product object get some null values in the $category ArrayCollection.
I first though to test the value in the setter in Product entity, and add 'by_reference'=>false in the ProductType, but in this case I get an exception stating that null is not an instance of Category.
How can I make sure the empty values are ignored ?
Citing the documentation on 'delete_empty':
If you want to explicitly remove entirely empty collection entries from your form you have to set this option to true
$builder->add('categories', 'collection', array(
'type' => 'entity',
'options' => array(
'class' => 'AppBundle:Category',
'property'=>'name',
'empty_value' => 'Select a category'),
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true
));
Since you use embedded forms, you could run in some issues such as Warning: spl_object_hash() expects parameter 1 to be object, null given when passing empty collections.
Removing required=>false as explained on this answer did not work for me.
A similar issue is referenced here on github and resolved by the PR 9773
I finally found a way to handle that with Event listeners.
This discussion give the meaning of all FormEvents.
In this case, PRE_BIND (replaced by PRE_SUBMIT in 2.1 and later) will allow us to modify the data before it is bind to the Entity.
Looking at the implementation of Form in Symfony source is the only source of information I found on how to use those Events. For PRE_BIND, we see that the form data will be updated by the event data, so we can alter it with $event->setData(...). The following snippet will loop through the data, unset all null values and set it back.
$builder->addEventListener(FormEvents::PRE_BIND, function(FormEvent $event){
$data = $event->getData();
if(isset($data["categories"])) {
foreach($data as $key=>$value) {
if(!isset($value) || $value == "")
unset($data[$key]);
}
$event->setData($data);
});
Hope this can help others !
Since Symfony 3.4 you can pass a closure to delete_empty:
$builder
->add('authors', CollectionType::class, [
'delete_empty' => function ($author) {
return empty($author['firstName']);
},
]);
https://github.com/symfony/symfony/commit/c0d99d13c023f9a5c87338581c2a4a674b78f85f
I have a form with 2 selects. Based on the value of the first select, it updates the values of the second select using AJAX. Doing this makes the form not being valid. So, I made the next change:
$form=$this->getAddTaskForm(); //the form
if(!$form->isValid($_POST)) {
$values=$form->getValues();
//get the options and put them in $options
$assignMilestone=$form->getElement('assignedMilestone');
$assignMilestone->addMultiOptions($options);
}
if($form->isValid($_POST)) {
//save in the database
}else {
//redisplay the form
}
Basically, I check if it is valid and it isn't if the user changed the value of the first select. I get the options that populated the second select and populate the form with them. Then I try to validate it again. However this doesn't work. Anybody can explain why? The same "value was not found in the haystack" is present.
You could try to deactivate the validator:
in your Form.php
$field = $this->createElement('select', 'fieldname');
$field->setLabel('Second SELECT');
$field->setRegisterInArrayValidator(false);
$this->addElement($field);
The third line will deactivate the validator and it should work.
You can also disable the InArray validator using 'disable_inarray_validator' => true:
For example:
$this->add( array(
'name' => 'progressStatus',
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'options' => array(
'disable_inarray_validator' => true,
),
));
Additionaly you should add you own InArray Validator in order to protect your db etc.
In Zend Framework 1 it looks like this:
$this->addElement('select', $name, array(
'required' => true,
'label' => 'Choose sth:',
'filters' => array('StringTrim', 'StripTags'),
'multiOptions' => $nestedArrayOptions,
'validators' => array(
array(
'InArray', true, array(
'haystack' => $flatArrayOptionsKeys,
'messages' => array(
Zend_Validate_InArray::NOT_IN_ARRAY => "Value not found"
)
)
)
)
));
Where $nestedArrayOptions is you multiOptions and $flatArrayOptionsKeys contains you all keys.
You may also add options to select element before checking for the form validation. This way you are insured the select value is in range.
I'm building a multi-step form in Drupal 6. For some reason, the id attribute of the form element have an extra "-1" the first time the step 1 form is displayed.
For example, if the form name is "user-registration", the first time I access the step 1 form, the id is "user-registration-1". Then, if I go to step 2, the id is "user-registration". If I go back to step 1, the id remains "user-registration".
I'd like to know if there's a way for me to set the id attribute or to prevent Drupal from adding the extra "-1".
Thanks.
You can set the id yourself.
$form['#attributes'] = array('id' => 'user-registration');
Drupal 6.x has a form API property for both '#id' an '#attribute'. I had the same problem and found that the '#id' property was blank, which accounted for the blank 'id' in the form field. Then I used '#attribute' => array('id' => 'name of id'), which gave me a second 'id' in the form field. Remove the id in the '#attribute' and add another form API property for '#id'.
$form['foo'] = array(
'#type' => 'textfield',
'#title' => t('Foo'),
'#required' => FALSE,
'#id' => 'text-foo',
);
This worked for me:
$form = array( '#id' => 'myformid' );