I have a simple form and I use jquery UI date-picker for birthday input.
and in the server side I use symfony validation with Date validation.
the problem is that the validation accepts only inputs with this format: YYYY-MM-DD
but in other locals like in UK the format is: DD/MM/YYYY
and the server gives error on it.
Do you have any suggestions?
I use the symfony form object with the inside validation,
so I would prefer not to force a format change manually.
As you can read from the documentation "date", the constraint dates performs validation only format "YYYY-MM-DD".
So you have two choices:
one (the simplest and most logical) is to set the format manually in the form field "format":
$builder->add('date', 'date', array(
'widget' => 'single_text',
'format' => 'dd-MM-yyyy',
));
in this way will be the form itself to reverse the date and pass the correct format to the validator (and the database).
The other is to create a constraint callback "callback", and creating your own logic for validation.
There would also be another way, even if it is inserted in the bonds of strings, and it is the constraint regex "regex".
In this way you will need to create a regular expression very precise (and complex).
For a problem as simple as the first solution is the most suitable!
EDIT:
jquery ui datepicker locks to an input type text, you do not need to create it manually.
As I wrote in the example, if you use the 'widget' => 'single_text' will produce an input type text!
You can set up a class to the date field in order to hook into that with jquery.
A short example:
form:
$builder->add('date', 'date', array(
'widget' => 'single_text',
'format' => 'dd-MM-yyyy',
'attr' => array(
'class' => 'your_class'),
));
javascript:
$(function() {
$( ".your_class" ).datepicker();
});
Related
I'm using the latest version of Laravel.
I am using Validator in my store controller and essentially I have a field called "current" which is required and is expected to be boolean. I also have a 2nd field, which is optional, called "to_date" of which the javascript plugin (moment.js) will provide either a date, or if null, provides a string "Invalid date" to the controller.
I wish to be able to validate "to_date" as a date using Validator if "current" is equal to 0. If "current" is equal to 1 then I wish to ignore validation for field "to_date"
My code started as:
$validator = Validator::make($request->all(), [
'current' => 'required|boolean',
'to_date' => 'date',
]);
But of course this failed because when "to_date" is not provided, the front-end provides a string "Invalid date" which fails the validation. And then I explored Laravel's validation rules a bit more and found 'exclude_if' which seemed to be appropriate.
$validator = Validator::make($request->all(), [
'current' => 'required|boolean',
'to_date' => 'exclude_if:current,1|date',
]);
This still didn't work because whilst it appears to "exclude it" from the $validator array, it still goes to the 'date' validation and fails. And so then I looked at 'bail' which is supposed to discontinue validation when Validator hits its first fail, however this doesn't work either because exclude_if doesn't fail when it runs, and the script still hits 'date' and fails.
Any help/pointers appreciated.
I am sure I can resolve this by wrapping Validator in an if statement and doing some logic to check whether to include "to_date" in Validator but this seems a bit smelly and not very tidy.
Any ideas? :)
The problem is you are intentionally providing bad data "invalid date".
This will trigger the validation failure because data is present.
exclude_if simply excludes the data from the array after validation.
The best solution is to not send bad data, and do required_if:current,0|date and when to_date is empty and required, it will fail the date validation portion.
Tested with Laravel 6.18.7 and your code works correctly for me. If you're still having issues, you might want to check your input.
Example code I used in tinker:
>>> Validator::make([
'current' => 1,
'to_date' => 'invalid-data',
], [
'current' => 'required|boolean',
'to_date' => 'exclude_if:current,1|date',
])->passes();
=> true
I'm looking for a way to bind entity to a form, but I need a specific field of it to be mapped (displayed), but not modified by the user submitting the form.
What I have checked so far:
Using disabled attribute - it's not being submitted and entity's field is set to null
Using HTML readonly attribute - it can still be modified by manipulating HTML
Using read_only field option - same as above
My field is a checkbox, but I'd prefer a generic solution for that kind of fields, because I'll have more of them in the future.
I would also like to avoid additional query.
Any ideas?
The 1st & 3th solutions are not good.
I had the same issue a while ago. This is what I did to solve it:
I used the 2nd solution, and since you have the entity in the application, you can simply override any value the user had changed by manipulating the HTML (whitch is a risk that should be handled).
or, you could draw a HTML checkbox that is not mapped (with random id and name), and it will be not mapped to you entity.
I think I have found the right solution to that problem. It's not very flexible, but converting it to extension should make it fairly easy to deal with. The basic version I created just now can be found here. A little explanation:
Make the field with option mapped set to false
create event handler function (setUnmappedField)
attach EventListener to both PRE_SET_DATA and SUBMIT events.
PRE_SET_DATA makes sure the field has a correct value when initially rendering the form.
SUBMIT makes sure the field's value is reverted back to the initial value even if user changed it before submitting the form.
Disabled and readonly attributes are here for UI/UX, it will work without these attributes as well.
Feel free to use it to build a form extension if you need one. I will probably build an extension to make it more flexible later, once I need it.
#EDIT
I just realised this can be done easier - leaving the field mapped! updated gist here. No need for PRE_SET_DATA listener and mapped=false
I suggest you do a combination of 1 and 2 . See below for sample
->add('trainings', 'entity', array(
'label'=> 'Upcoming training(s)',
'choice_label' => 'CompleteTitle',
'multiple' => 'true',
'expanded' => 'true',
'by_reference'=>false,
'class' => 'TrainingBundle:Trainings' ,
'query_builder' => function (EntityRepository $er) use ($options) {
return $er->getTrainingByParentId($options['parent_id']);
},
)
)
->add('PastTrainings', 'entity', array(
'label'=> 'Past trainings',
'choice_label' => 'CompleteTitle',
'multiple' => 'true','expanded' => 'false',
'disabled' => 'true',
'class' => 'TrainingBundle:Training' ,'mapped'=>false,
'query_builder' => function (EntityRepository $er) use ($options) {
return $er->getTrainingByParentId($options['parent_id']);
},
)
I am trying to validate "2016-05-16 06:00:00.0" with symfony form component. This is my validation rule
$builder->add("start", DateTimeType::class, [
'format' => "yyyy-MM-dd HH:mm:ss.S",
'invalid_message' => 'Really bad format'
]);
For some reason though it is failing to validate. I tried .0 instead of .S in the end, and still no luck.
Either you can add assert for "DateTime" in your entity, where you can add
#Assert\DateTime()
and inside it you can specify formats (default format is Y-m-d H:i:s), see for more details http://symfony.com/doc/current/reference/constraints/DateTime.html
#Assert\DateTime(format = Y-m-d H:i:s)
or you can add this validation constraint in your form by using
->add('fieldname', 'DateTime', array(
'constraints' => new DateTime(format = Y-m-d H:i:s)
))
also add 'use' statement
use Symfony\Component\Validator\Constraints\DateTime;
hope this helps, all the best
I'm using Symfony 2 and FOS User Bundle to create a website that handles user information.
I tried to create the edit page to change an existing profile.
My problem is that I want the birthdate to be an input text (because I'm using a Jquery Datapicker). It perfectly works on my register page but when I try to do the same for the profile/edit page, I have a 500 error saying "The form's view data is expected to be of type scalar, array or an instance of \ArrayAccess, but is an instance of class DateTime. You can avoid this error by setting the "data_class" option to "DateTime" or by adding a view transformer that transforms an instance of class DateTime to scalar, array or an instance of \ArrayAccess.".
Here is how I wrote my User (User.php entity) birthdate parameter:
/**
* #ORM\Column(name="birthdate", type="date")
* #Assert\NotBlank(groups={"Registration", "Profile"})
* #Assert\Date()
*/
protected $birthdate;
In my RegistrationFormType.php (that is working fine):
public function buildForm(FormBuilderInterface $builder, array $options)
{
...
$builder->add('givenname');
$builder->add('familyname');
$builder->add('birthdate', 'text');
...
}
When I try to copy paste this code, I got an error.
The only solution is to do the following:
$builder->add('birthdate', 'date', array('input' => 'datetime'));
This solution does work but is not what I want (it generates three select inputs, I would rather have a text input that uses my Jquery datepicker with my Jquery validation).
Do you have any idea why my error occurs on the edit page and not on the registration page?
Thank you!
I think you need to set the widget option of your date field to text. It's by default set to choice.
From the documentation:
text: renders a three field input of type text (month, day, year).
Example,
$builder->add('birthdate', 'date', array(
'input' => 'datetime',
'widget' => 'text'
));
You can also set it to single_text, which allows you to validate the user's input based on the format option.
Example,
$builder->add('birthdate', 'date', array(
'widget' => 'single_text',
// this is actually the default format for single_text
'format' => 'yyyy-MM-dd',
));
To let it work through a Date Picker, you've then to add the right class to your field.
I'm using Zend_Form for handling a form and I have a problem with localization.
I use following field declaration:
$this->addElement('text', 'area', array(
'label' => 'Area:',
'required' => true,
'filters' => array('StringTrim', 'NormalizedToLocalized')
));
The problem is, I use pl_PL locale and in this locale the decimal point separator is "," not ".". But database (MySQL) stores float with "." separator.
I added NormalizedToLocalized to convert e.g. 40.12 into 40,12 in my html form.
But when passing 40,12 in POST request I want Zend_Form to automatically convert back value 40,12 into 40.12 so that it can be passed to DB (I collect values from form using $form->getValues() method). By now it renders 40,12 successfully but in $form->getValues() I get localized, not not normalized value.
So my question is, whether it is possible to create different filter for rendering and getting value of field in Zend Framework.
Thanks in advance for your help!
The filters are not applied until the form is submitted so 'NormalizedToLocalized' will not have any effect until the form is posted. So if you want decimal points and not commas in your data for storage remove the filter (or use 'LocalizedToNormalized') from the form and apply the filter using Zend_Filter for any data you need to display.
If this field always expects a float type you can use a validator to enforce the value and then use the filter to enforce formating for the database.
$this->addElement('text', 'area', array(
'label' => 'Area:',
'required' => true,
'validators' => array('Float'),
'filters' => array('StringTrim', 'LocalizedToNormalized')
));
I'm not familiar with Zend Framework but looking on filter name, shouldn't it be 'LocalizedToNormalized' ?