How I can validate only some validation groups based on some fields in the form itself in Symfony2 - validation

I have a big form organized in some validations groups. For every group in the form there is a corresponding checkbox which tell the server to save group data.
When the user post the form, I need to validate only validation groups whose correspond the checked checkboxes because some of their "sub" fields are required, but only if you activate the group. Otherwise the validator must ignore the required fields.
Actually I do that in my controller. I skip the Symfony's normal validation cycle and manually I validate every field checking for the group activation checkbox.
How I can move this validation logic inside the Form class or in a specific Constraint class used by the entity?
EDIT:
As said below is possibile in symfony 2.1, for now i solved:
$request = $this->get('request');
// myEntity knows the business logic to chose validation groups
$myEntity->collectValidationGroups($request);
$form = $this->createForm(new MyEntityType(), $myEntity);

If you are using Symfony 2.1 then you can set validation group based on submitted data. Check this section.

There is another possibilty than the one offered by 2.1.
You can set the validation_groups attribute on the form using $builder->getData():
// inside buildForm method of a form type:
$builder->setAttribute('validation_groups', $builder->getData()->getValidationGroups());

Related

Laravel - delete password value from request when form is not validated

I'm using FormRequest validation in my Laravel controller method. I'm validating (beside others) fields 'password' and 'password_confirmation'. The rules are:
$rules['password'] = 'required|string|min:8|required_with:password_confirmation';
$rules['password_confirmation'] = 'min:8|required_with:password|same:password';
(I'm not using 'confirmed', because the validation message is always only on the first field, not on the confirmation one)
When the password confirmation does not match thus the validation fails all data does get returned to the form, including the passwords. Is there some way to exclude them from returning only in case of failed validation - so that the user has to manually input them again? I presume it has to be done somewhere in the custom FormValidation class, probably overriding one of its methods - however, how would I go about it? Just delete it from the returning array?
in the password fields of your register.blade.php, remove the old('password') from the value attribute.

What to check when validator is not called in symfony 3?

I cannot find general checklist - what to check when it is not called. Can you write it?
For example code snippets where validator is not being called:
$fieldOptions['constraints'] = [
new NotBlank($constraintOptions)
];
$builder->add(
$builder
->create($formField->getId(), EntityType::class, $fieldOptions)
->addModelTransformer(
new EntityCollectionToArrayTransformer($this->registry, $fieldOptions['class'])
)
);
One of things to check - validation groups. Try commenting out any validation groups, so it would work as default. When form adds a collection of forms, those subforms validator constrains also have to have same group. https://symfony.com/doc/3.4/validation/groups.html
When validating just the User object, there is no difference between the Default group and the User group. But, there is a difference if User has embedded objects. For example, imagine User has an address property that contains some Address object and that you've added the Valid constraint to this property so that it's validated when you validate the User object.
If you validate User using the Default group, then any constraints on
the Address class that are in the Default group will be used. But, if
you validate User using the User validation group, then only
constraints on the Address class with the User group will be
validated.
In other words, the Default group and the class name group (e.g. User)
are identical, except when the class is embedded in another object
that's actually the one being validated.

Unique Validator - add error (warning) and return true

What would be the best way to create validator that checks if model value is unique or not, but it does not return false - it only shows message "the value already exists" (I can still save the model)?
Validators usually don't return boolean values, they add errors for given model attribute(s).
One of the ways (with minimal completions) will be using built-in UniqueValidator and saving without running validation.
At first call $model->validate() to fill model with errors.
You can use $model->validate('fieldName') to validate only needed field.
Then call $model->save(false) or $model->save('fieldName') (for just one field).
This will prevent validation before saving and model values will be saved "as is".
Another way for just saving one attribute without triggering events, etc. will be using updateAttributes after calling validate():
$model->updateAttributes(['fieldName' => 'fieldValue']);

Where i need to put validation code?

I have a form with a number of fields.
Some of them are userId, userFirstName, userLastName.
When user inputs incorrect userId value then near userId field page must show error message and add this error into validationSummary(this is standart behavior for asp.net mvc unobtrusive validation). If userId is correct then page must remove errors and autopopulate userFirstName and userLastName(This is not standart behavior)
How can i implement this?
Here is what come to my mind:
Remote validation attribute
It has a bad customization in my case. That's why i decide to don't use it.
Add special method for jquery validation plugin ( for example
jQuery.validator.addMethod("userIdValidation", function(value, element) {
//some logic
return something;
}, "Please specify the correct userId"); )
and put there logic for validation and for autopopulate other fields.
In this case i mix validation and other stuff.
3 . Add special method for jquery validation plugin ONLY for validation and add special handler for input change event for autopopulate.
In this case i need to send TWO ajax requests to server for one thing. And ofcourse it is not good too. So what is the right way? I am confused.
Have you thought about using a partial view to display the userFirstName and userLastName?
You can fire an AJAX request that sends the userId, and then returns a partial view of the name fields. Within the controller being called, you can validate the incoming userId, and then grab the name details in one query. If thevalidation fails, you can return the partial view with empty fields.

Validate single form field only in Symfony2

I'm looking for a way to validate just a single field (object property) against the constraints specified in the annotations of a particular entity.
The goal is to send an AJAX request after the "onBlur" event of a form field, asking the server to validate this single field only, and - depending on the response - add a small "OK" image next to this field or an error message.
I don't want to validate the whole entity.
I wonder what's the best approach for this problem? Thanks for any tips.
The Validator class has the validateProperty method. You can use it like this:
$violations = $this->get('validator')->validateProperty($entity, 'propertyName');
if (count($violations)) {
// the property value is not valid
}
Or, if the value is not set in the entity, you can use the validatePropertyValue method:
$violations = $this->get('validator')->validatePropertyValue($entity, 'propertyName', $propertyValue);
if (count($violations)) {
// the property value is not valid
}
Have a look at validation groups. I think this is what you need. You could add a group "ajax" or and just adding the one constraint to it. Then tell the validator to use that group. THe symfony2 docs have an example included.

Resources