How to allow empty values in symfony2 validators
Solution 1
You must explicitly set 'required' => false
in your FormBuilder
class for all optional fields. Here's a paragraph describing field type options.
Edit. Getting quite a few downvotes. By default all validators treat null
values as valid, except NotNull
and NotEmpty
. Neither of the two was used in the question. The question is implicitly about how to turn off the client-side required
attribute that is turned on by default.
Solution 2
Setting the required
option is not the solution:
Also note that setting the required option to true will not result in server-side validation to be applied. In other words, if a user submits a blank value for the field (either with an old browser or web service, for example), it will be accepted as a valid value unless you use Symfony's NotBlank or NotNull validation constraint.
http://symfony.com/doc/current/book/forms.html#field-type-options
For my custom validators, I add a
if (null == $value) {
return true;
}
to the isValid()
method. However, I'm not sure what would be the best way for the standard validator classes.
Solution 3
if i understand correctly you want server side validation only if value is entered. I am exactly in the same scenario. I want to validate a URL only if the URL is provided. The best way i came across was to write my own custom validation class. You can write a generic custom validation class.
I followed this link https://symfony-docs-chs.readthedocs.org/en/2.0/cookbook/validation/custom_constraint.html except for few changes because of symfony's latest version. Here is the implementation
Acme\BundleNameBundle\Validator\Constraints\cstmUrl
namespace Acme\BundleNameBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\Url;
/**
* @Annotation
*/
class CstmUrl extends Url
{
public $message = 'The URL "%string%" is not valid';
}
Acme\BundleNameBundle\Validator\Constraints\cstmUrlValidator
namespace Acme\BundleNameBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\Url;
use Symfony\Component\Validator\Constraints\UrlValidator;
class CstmUrlValidator extends UrlValidator
{
public function validate($value, Constraint $constraint)
{
if(!$value || empty($value))
return true;
parent::validate($value, $constraint);
}
}
Validtion.yml
Acme\BundleNameBundle\Entity\Student:
Url:
- Acme\BundleNameBundle\Validator\Constraints\CstmUrl: ~
inside Controller just bind the constraint you normally would do
'constraints'=> new CstmUrl(array("message"=>"Invalid url provided"))
I am sure there can be other better ways of doing it, but for now i feel this does the job well.
Solution 4
Just in case anyone else comes across this same question. I prefer to personally solve it by adding the following attribute inside my Twig template:
{{ form_row(form.<field>, {'required': false}) }}
Solution 5
Here is the trick I found actually :
https://github.com/symfony/symfony/issues/5906
You need to write a data transformer that does nothing, and then add it to your field. After that, juste call the submit() method with the second param to false.
Note that it's ok with Symfony 2.3.
Related videos on Youtube
Comments
-
canni almost 2 years
I would like to apply validators on a object properties only when value is not empty ie.
Now standard symfony behavior:
class Entity { /** * @ORM\Column(type="string", nullable=true) * @Assert\Email() */ protected $email; (...) }
that object will not pass validation if an email is null, or empty string, is there a way to tell validator to assert as a valid, an empty value, and validate only if field has data?
PS I know that I can write callback validator, but writting callback for every field just to have "allowEmpty" feature isn't so nice.
-
Vlad over 11 yearsThis is not the correct answer. 'required' option enforces only client-side validation.
-
kgilden over 11 years@TyrionLannister You are indeed correct. However, none of the default validators result in an empty value being treated invalid except when having
NotNull()
andNotEmpty()
constraints. Seeing as the asker had neither of those constraints, it was implicit that the problem was with the client-side HTML5required
attribute. -
Luke over 10 yearsI don't think you want to hard code this in your template. If you want to use the
required
approach, use gilden's suggestion instead and add it to the form builder.. -
Anton Babushkin over 10 yearsYeah in most circumstances I think that would be a better approach (that way the attribute validation requirements propagate across other templates), however in some situations (i.e. simple apps) placing it into a Twig template isn't too terrible :)
-
pscheit about 10 yearsthis shouldl be the accepted answer, because the accepted answer only applies for simple fields not for embedded type fields
-
Andrzej Ośmiałowski about 10 years@gilden with all due respect,
required
attribute have nothing common with empty value approved. It's only used by HTML5 client-side validation and it's not related to the validation (the server-side one) at all. -
kgilden about 10 years@AndrzejOśmiałowski absolutely, please check the comment above yours. That's exactly what I said :)
-
tom10271 over 5 yearsWhat if he simply does not know the correct way to achieve it is to set NotNull or NotEmpty constraint? I found this explanation is hilarious. Even so I am sure he will regret how many bugs he made when he tries to send the form data via XHR with data in JSON format, The form will be passed and you will get nothing. This is exactly what I am facing now. This is an answer to a certain extent only, not a full answer.