How to add an error to a constraint in form? - forms

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

Related

Sylius custom fields are not validated in form

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.

Using Laravel to Add Dynamic Attributes to Form Fields

I am trying to create a dynamic value for a form attribute that is auto-populated based on a previous setting stored in the database. It works fine in HTML with a little Laravel and looks like:
<input type="text" class="class" id="firstName" placeholder="First Name" value="{{ $user->firstName }}">
But I want to fully generate the entire form in Laravel. I'm unsure how to pass the value into the array. I can't seem to get the form to pull the information. Here is how it is currently looking:
{{ Form::text('first_name', '', [
'class' => 'class',
'id' => 'firstName',
'placeholder' => 'First Name',
'value' => $user->firstName
])}}
Try this:
{{ Form::text('first_name', $user->firstName, [
'class' => 'class',
'id' => 'firstName',
'placeholder' => 'First Name'
])}}
For more information regarding this topic, visit this
See, if that works.
To specify a default value in laravel's form generator, the second value you pass in is made for you:
{{ Form::text('first_name', $user->firstName,
[
'class' => 'class',
'id' => 'firstName',
'placeholder' => 'First Name',
]
) }}
Please note that from laravel 5, being published next week, the form helpers are removed (and for the actual state the installable replacement packages don't work very well/without bugs). So if you are planning on upgrading to laravel 5 better don't use this, instead go with html form elements.

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.

Laravel form with placeholder, class and input::old

I am trying to get used to work with Laravel's blade.
I would like to create a text input called company.
The input field needs to have an id and a class.
I also want to show a placeholder if there is no data in the database, or the data stored if already exists.
Finally, I would like to keep the introduced input in case of errors.
I would like to use something similar at this:
{{ Form::text(
'company',
isset($user->company)?$user->company:array('placeholder'=>'Your company'),
array('class' => 'field required', 'id' => 'company'),
Input::old('company')
) }}
Any help would be appreciated. Thanks!
The easy way, using form model binding:
{{ Form::model($user, [ ...options...]) }}
{{ Form::text(
'company', // refers to $user->company
null, // auto populated with old input in case of error OR $user->company
array('class' => 'field required', 'id' => 'company',
'placeholder' => 'Your company') // placeholder is html attribute, don't use model data here
) }}
And if you don't want form model binding, this is all you need:
{{ Form::text(
'company',
$user->company, // auto populated with old input in case of error
array('class' => 'field required', 'id' => 'company',
'placeholder' => 'Your company')
) }}
Laravel will handle re-populating inputs for you, so long as the key in the POST data is the same as your input’s name attribute.
With Form::text(), the first parameter is the field name, the second parameter is the default value you want, and the third parameter is an array of HTML attributes you want set. So, you would have:
{{ Form::text('company', null, array(
'class' => '',
'id' => '',
'placeholder' => '',
)) }}
Obviously replaced the class, id, and placeholder values with your desired values.
Found it!
It works fine for me if I do this:
{{ Form::text(
'company',
Input::old( 'company', $user -> company ) ,
array( 'class' => 'field required', 'id' => 'company', 'placeholder' => 'Your company' )
) }}

Symfony2: Create form binded to an entity with a field which is not a property

The following (simple) question from me:
$user = new User();
$user->setEventid(2);
$user->setT(new \DateTime('now'));
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
$form = $this->createFormBuilder($user)
->add('email', 'email')
->add('terms', 'checkbox', array(
'label' => 'Read terms?',
'required' => true))
->getForm();
This is my code. Email is property of the user, terms not.
I want them users to save their email and check the terms-checkbox but i just need to save the email, not if they check the box - if they don't they cant submit the form.
You know what i mean? I'm shure its pretty simple to achieve this ;)
Second Question: How can i give the rendered from-tag an id-attribute for further handeling in jquery?
To add a field that doesn't exist in the entity to a form, use this:
->add('terms', 'checkbox', array(
'label' => 'Read terms?',
'required' => true,
'mapped' => false, // this works since Symfony 2.1
'property_path' => false, // this works since Symfony 2.0
))
Symfony generates an ID for each form element; just open the rendered page source and see the ID of the element you need.
If you don't have a 'terms' field in your Entity, it won't be save.
For your second question, it's very simple to set an id to a form in twig, make simply :
{{ form_label(form.name, 'Your Name', { 'attr': {'id': 'foo'} }) }}