I'm trying to validate a form in a symfony 2.3 project,
So I have a 'Customer' field :
$builder
->add('customer',
'entity',
array('property'=> 'item',
'multiple' => true,
'expanded' => true,
'class' => 'OrdersBundle:Customer',
'required' => true, 'empty_value' => '',
'query_builder' => function(\Ella\OrdersBundle\Repository\CustomerRepository $er) {
return $er->createQueryBuilder('q')->andWhere("q.is_delete = 0")->orderBy('q.item', 'asc');
}));
I'm trying to return an error when user didn't select anything, so i do this :
properties:
customer:
- Choice: { min: 1, minMessage: 'message' }
Or
properties:
customer:
- NotBlank:
message: message
and other things, but nothing works , an idea of what I'm doing wrong ??
In the doc they say we could use an array, but this doesn't work either ...
Actually Symfony return :
Either "choices" or "callback" must be specified on constraint Choice
For the Choice validator you either need to specify an array with the available allowed choices or a callback function, from the docs:
This constraint is used to ensure that the given value is one of a given set of valid choices. It can also be used to validate that each item in an array of items is one of those valid choices.
What you could use may be the Count validator:
customer:
- Count:
min: 1
max: 99
minMessage: "Min message"
maxMessage: "You cannot specify more than {{ limit }}"
Related
I have a form in Symfony 2.7.10 which definition looks like this:
<?php
// ...
class RecipeType extends AbstractType
{
// ...
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// ...
->add('meal_schema', 'choice', [
'label' => 'Mealtime schema',
'choices' => [
'breakfast' => 'Breakfast',
'second_breakfast' => 'Second breakfast',
'lunch' => 'Lunch',
'dinner' => 'Dinner',
'snack' => 'Snack',
'supper' => 'Supper',
],
'multiple' => true,
'expanded' => true,
'label_attr' => ['class' => 'col-md-2'],
'required' => true,
])
}
// ...
}
This is how validation looks in validation.yml file:
My\Real\Namespace\Entity\Recipe:
properties:
name:
- NotBlank: ~
mealSchema:
# Look below
Name field validation works, but mealSchema validation doesn't.
Settings which I've already tried without success:
# This one works but assigns error to form instead of field so it's displayed on top of the page
- NotBlank:
message: Mealtime schema should not be blank
# This doesn't work
- Choice:
callback: [RecipeMealSchemaChoices, getChoiceKeys] # This method isn't even called
min: 1
minMessage: "Please select meal schema"
# This also doesn't work
- Count:
min: 1
max: 99
minMessage: Mealtime schema should not be blank
maxMessage: Max meal time exceeded
Ok, I solved it.
My mistake was to not provide information about mealSchema field in my entity when asking on stackoverflow. If I'd do that then I would realise that the entity field is in fact a smallint.
My colleague wanted to emulate a MySQL "SET" field type in Doctrine so he used an array as entrypoint values and converted it to bit values in setter method (and the other way around in the getter method).
That's why none of the choice-related validation rules worked. For now, I've made 2 quick solutions:
Change all fields' names in RecipeType from underscore to camelCase because that is how they are named in our entity. This helped for the error being attached to the form instead of the field.
Used a NotNull validator because the default value of mealSchema was null, not an empty array.
I have a "teachers" field in a form.
I would like to be able to select a blank value.
But in the symfony doc, I read that I have to set the multiple to false and the required to false, to add an empty_value and an empty_data. I understand the required. But why is this necessary to set the multiple to false ?
How can I add an empty_value with a multiple => true field ?
Here is my builder :
$builder->add('teachers', 'entity', [
'class' => 'Ent\UserBundle\Entity\User',
'multiple' => true,
'query_builder' => function(\Doctrine\ORM\EntityRepository $er) use ($options) {
$qb = $er->createQueryBuilder('u');
$qb->where($qb->expr()->eq('u.group', '\'ROLE_TEACHER\''));
return $qb;
}
]);
You cant specify at the same time multiple and empty_value. Because multiple mean that you have got checkboxes at form or select with multiple choices. In the first case, you can uncheck all checkboxes and recieve empty array, in second you can do the same with ctrl button.
symfony doc
I have an entity field type with multiple selection :
$builder
->add('products', 'entity', array(
'class' => 'Acme\MyBundle\Entity\Product',
'choices' => $this->getAvailableProducts(),
'multiple' => true,
))
;
I would like to add a min/max constraint on this field,
use Symfony\Component\Validator\Constraints\Choice;
...
'constraints' => array(new Choice(array(
'min' => $min,
'max' => $max,
'multiple' => true,
'choices' => $this->getAvailableProducts()->toArray(),
))),
But in this case, when the form is bound, the value bound for the 'products' field is a doctrine ArrayCollection, the validator throw an exception if an array is not given. "Expected argument of type array, object given"
Does it mean I have to use a 'choice' field in order to use the min/max constraint ?
As you have multiple set to true the validator will receive a collection after binding your form.
You can validate the number of entites in the collection using the count validation constraint.
The Count validation constraint
Validates that a given collection's (i.e. an array or an object that
implements Countable) element count is between some minimum and
maximum value.
I have a formbuilder where I am adding some values from an entity:
$builder->add('affiliation', 'entity', array(
'class' => 'SciForumVersion2Bundle:UserAffiliation',
'multiple' => true,
'expanded' => true,
'query_builder' => function(EntityRepository $er) use ($author,$user) {
return $er->createQueryBuilder('ua')
->where("ua.user_id = {$user->getId()}")
->andWhere("ua.affiliation_id not in ( select pa.affiliation_id FROM SciForumVersion2Bundle:PersonAffiliation pa where pa.person_id = {$author->getPersonId()} )");
},
'required' => true,
));
In my controller, I would like to check if there is something in my form. If there is something, I will display one view, if there is nothing, I will display another view.
Is this possible and if so, how?
Thank you.
Simply try it:
$data = $form->getData()
function getData() documentation Book
If you want to get the current data (just after rendering the form) in your form type you can use the builder supplied in each form type by standard.
It works exactly as a normal form response, so you can use:
$builder->getData();
and use if clauses to add different fields depending on what you want to generate.
I am using symfony2 and have a form to save the relation of one user to some rules. These rules are set by the admin user of the company. In this form, after I selected a user to update, I have to select which rule this user have permission.
The problem is that I may have more then one rule with the same name (it's another entity) but the values are different. So, when I build the selectbox I must show the name and the value like:
Quantity of items - 10
Quantity of items - 20
Value of the item - 200
Value of the item - 500
But now I just can show without the "- $value" using the code bellow:
$form = $this->createFormBuilder()->add('myinput', 'entity', array(
'class' => 'myBundle:Rule',
'property' => 'childEntity.name',
'label' => 'Filas Permitidas',
'expanded' => false,
'multiple' => true,
'choices' => $this->getDoctrine()
->getRepository('MyBundle:Rule')
->findAll(),
'required' => true,
))->getForm();
So, as property I wanted to get $myEntity->getChildEntity()->getName() and the $myEntity->getValue().
Is there some way to do this?
Yes, define a getUniqueName() method in the entity class like:
public function getUniqueName()
{
return sprintf('%s - %s', $this->name, $this->value);
}
And edit the property form option:
'property' => 'childEntity.uniqueName',
You also can omit the property option and define the __toString() method same way in order to not repeat the setting of the property option in every form.