Sylius custom fields are not validated in form - forms

I am overriding the register page (overriding the Customer object) ; I have added "Type", which is a ChoiceType expanded (3 radio buttons), and I have added the defaultAddress fields (in which I have added 3 fields).
When I display the form, all these fields have a red star to show there are required, but when I submit the form, if I don't put anything in these fields, the form is submitted anyway and I have a database error because these fields are empty.
Here is my code :
CustomerRegistrationTypeExtension.php :
$builder->add('type', ChoiceType::class, [
'choices' => array('Particulier' => Customer::TYPE_PARTICULIER, 'Professionnel' => Customer::TYPE_PRO, 'Projet à but non lucratif' => Customer::TYPE_PROJET),
'expanded' => true,
'label' => 'Vous êtes',
'choice_attr' => array('onclick' => 'alert(\"click\")')
])
->add('siren', TextType::class)
->add('denomination', TextType::class)
->add('defaultAddress', AddressType::class);
AddressTypeExtension.php
$builder->add('showOnMap', CheckboxType::class)
->add('geocodeLat', HiddenType::class)
->add('geocodeLng', HiddenType::class);
_address.html.twig :
{{ form_row(form.showOnMap, {'label' : 'address.showMap.label'}) }}
{{ form_row(form.geocodeLat)}}
{{ form_row(form.geocodeLng)}}
_form.html.twig
{{ form_row(form.type) }}
Any idea ?
Thanks !

Red asterisk near the field is just an UI feature. To require some fields, you must specify theirs validation configuration. Check out Symfony validation documentation to get required info, all of it should perfectly work in Sylius ;)
One important thing - remember to set sylius in groups parameter when defining constraints, it is a default validation group in Sylius.

Related

Symfony 4 - Default value form not working

I have a little problem I don't understand.
I want to display my errors in the same location at the top of the form, I used form_errors(form)
Then in my form, I added a default value to my fields.
        
$resolver->setDefaults([
'data_class' => Whitelist::class,
'error_bubbling' => true
]);
Currently, it does not work and my errors appear in their respective fields.
But if I put this option 'error_bubbling' => true to my field, it works. Why by default it does not work?
->add('firstName', null, [
'label' => "Prénom de votre personnage",
'error_bubbling' => true
])
Sorry for my english, thanks.
'error_bubbling' => true means that the error will "bubble" up to the form, where you are trying to display it.
From the docs:
error_bubbling
type: boolean default: false unless the form is compound
If true, any errors for this field will be passed to the parent field or form. For example, if set to true on a normal field, any errors for that field will be attached to the main form, not to the specific field.

How to add an error to a constraint in form?

Using Symfony 3.2 on Ubuntu 16.04
I created a FormType.php with several fields. One of them is a phone number, so I added a constraint where only numbers could be accepted. Here is the code for the phone form
->add('authorPhone', NumberType::class, array('label' => 'Numéro de téléphone',
'required' => true,
'attr' => array(
'class' => 'validate',
'id' => 'icon_telephone'
),
'constraints' => array(new Regex("#^0[1-9]([-. ]?[0-9]{2}){4}$#"))
))
After that, in my controller I added an error to tell that numbers only need to be filled in
public function indexAction()
{
$form = $this->createForm(FormType::class);
$form->get('authorPhone')->addError(new FormError('error message'));
return $this->render('app/main/index.html.twig', array(
'form' => $form->createView()
));
}
But when I look at my page the error message is actually showing without having filled the field. And of course I don't want that.
(you can see under "Numéro de téléphone", which means phone number)
I only want numbers in my phone number field, and if there are letters, an error should be displayed or something saying it's not right.
Standard how to to this stuff in Symfony is to define an entity with contraints and error messages and then create entity bound form which will handle validation based on entity's contraints automatically.
But if you need, for some reason, independent form, it can be done to. The addError() method is for adding error "state" the the form field (e.g. for own validation) and you're adding the error by default right after the form is created. That's the reason why the error shows constantly.
UPDATED:
The right way to assign an error message to a form field is by the invalid_message property (which is showed when the entered value doesn't correspond with the field type). But when there's a constraint used for validation, then the err message has to be set according to the constraint validator - so, in your case, by associative array with pattern and message keys.
Next thing need to be corrected is TextType instead of NumberType, because when the NumberType is used, then it won't allow to enter dashes and also automatically trims leading zeros in numbers - so bad for phone numbers :-)
->add('authorPhone', TextType::class, array(
'label' => 'Numéro de téléphone',
'required' => true,
'attr' => array(
'class' => 'validate',
'id' => 'icon_telephone'
),
'constraints' => array(new Regex(
array(
'pattern' => '#^0[1-9]([-. ]?[0-9]{2}){4}$#',
'message' => 'Phone error message'
)
)),
))
And last thing to review - in the controller (after form declaration) has to be form submission handling routine:
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
....
You can learn more in Symfony's form submission handling: http://symfony.com/doc/current/forms.html#handling-form-submissions
Form rendering is fairly simple. Twig syntax to render whole form:
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
or, if you want to selectively render fields one by one:
{{ form_start(form) }}
{{ form_row(form.authorPhone) }}
{{ form_row(form.submit) }}
{{ form_end(form) }}
It'll renders complete field including labels and errors

Laravel - fill <select> element with old input (edit/update)

I have to edit a few value's from the database.
with a textfield or area i can just fill the formfield with the old date like this
{{ Form::text('hours', Input::old('hours', $vacature->hours), array('class' => 'form-control', 'placeholder' => 'Aantal uren')) }}
where Input::old('hours', $vacature->hours) takes care of the old input retrieved from the model.
When i try do to the same with select fields, it does not work.
{{ Form::select('employmentType',Input::old('employmentType', $vacature->employmentType), array('vast' => 'Vast dienstverband', 'Freelance' => 'Freelance'), null, array('class' => 'form-control')) }}
I'm stuck on this for quite a while now. So i hope i can get some help here!
You should rearrange the passed arguments:
{{ Form::select('employmentType', array('vast' => 'Vast dienstverband', 'Freelance' => 'Freelance'), Input::old('employmentType', $vacature->employmentType), array('class' => 'form-control')) }}
Basically you should pass:
field name
options (key => value pairs)
selected value (you set old value if there is one or a default value if there isn't)
field attributes
or:
Form::select('fieldName', $options, $selectedValue, $fieldAttributes)
If you don't succeed at first try "slicing" the problem into steps:
see what do you get as an "old" value, see how the select behaves when you pass a static slected value to it etc.
Take care
I believe that when you use Laravel's form and you bind it to a model, you can just use the Redirect::back()->withInput(); method and laravel will do the job for you.
here's how you can do this from the Laravel doc :
Form::model($user, array('route' => array('user.update', $user->id)))
Doc page.

Symfony2 how not to escape characters used in entity field property

I am using Symfony 2.1.8 and I have form with an entity which has many-to-one relation on it.
I use entity field for this member and i call it in the buildForm() as:
$builder->add('direction', 'entity', array(
'class' => 'CompanyBundle:Direction',
'property' => 'enTranslation.arrowedTitle',
'empty_value' => false,
'label' => 'Connection Direction',
'required' => false
));
enTranslation.arrowedTitle is a function that returns a string which including '⇒' (character set for right arrow)
when i call {{ form_widget(form.direction) }} i see the string as it is,(not the arrow but the &rArr) For displaying purposes, arrows must be showed, but i see &rArr in the field.
For simple string rendering, |rawfilter is used, but it does not work on widget. What should I do in order to display ⇒ instead of '&rArr ;' in the form? Thanks for any help.
You will have to create a form theme for at minimum the field type who's label includes that character.
Symfony/Twig escapes values by default for safety.
See this section of the documentation for more info:
http://symfony.com/doc/current/cookbook/form/form_customization.html#form-theming

Symfony2 Forms : Changing the default prefix in Form Labels

I am rendering a form, and every widget has an ID like : form_username, form_password, etc
and every corresponding label has a for field as for="form_username"
can I customize this ID and For attribute pair? Because I am rendering 2 forms on a page, and their field names are clashing...
edit : Here is an example code where I want to customize the Form Name.
$form = $this->createFormBuilder($user, array('validation_groups' => array('registration')))
->add('username', 'text')
->add('email', 'email')
->add('password', 'repeated', array('type' => 'password'))
->getform();
You need to provide different names for the forms when you create them in your controller:
$builder1 = $this->get('form.factory')->createNamedBuilder(new FooFormType(), 'foo1');
$builder2 = $this->get('form.factory')->createNamedBuilder(new FooFormType(), 'foo2');