Drupal form validation functions - drupal

Is there anyway say Drupal to validate form elements like email fields, passwords, numeric fields validate automatically lets say bind a system validator
$form['email] = array(
'#title' => t('Email'),
'#type' => 'textfield',
'#validate_as' => array('email', ...),
...
);

To validate a numeric field in Drupal use:
'#element_validate' => array('element_validate_number')
No need to create a custom validation function.
http://api.drupal.org/api/drupal/includes%21form.inc/function/element_validate_number/7

Rimian is both correct and wrong.
The good thing as Rimian points out, is that you can attach any validation function to your form fields using the #element_validate.
However I'm not aware of a set of form api validation functions you can call to test most common things like, if the value is:
a int
a positive int
a valid date (such a function exists in the date module though)
a email-address (you can use valid_email_address to check the email, but you need a function to raise validation error)
So while you can do this, it's a bit more work than you were hoping for, as you will need to create these validation functions yourself. But once you have done this, you can reuse them with #element_validate.
The use of #element_validate is mostly centered around complex validation fx date validation, location validation and such, as it requires some work to create these validation functions. Most of the time, you don't need to validate that many numbers etc (which you quite easily could do within a normal validation function using a loop). So I'm not sure how much this will be of help to you, but it's definitely a possibility.

The Form API Validation module does exactly what you request: http://drupal.org/project/fapi_validation
For client-side validation there is also http://drupal.org/project/clientside_validation (which can use rules provided by Form API Validation).

Yep!
Though I have not experimented with it much.
http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html/6#element_validate
$form = array(
'#type' => 'fieldset',
'#title' => t('Input format'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => $weight,
'#element_validate' => array('filter_form_validate'),
);

Related

Populate 3 selection lists using queries on the same entity, using Symfony2 buildForm()

I have an entity Machine which has a relation MM with other entity Piece. The pieces can be from 3 different types. Currently the form Machine is built with a selection list in which the whole array collection Machine.pieces is fetched. My idea is to build 3 different selection lists with a subset of Machine.pieces each.
I have tried two different approaches but I have no been able to accomplish it.
Use a MachineRepository class where a method
public function findPiecesByPieceType($pieceTypeID)
returns the proper query->getResult().
Then I add a choiceType in MachineType but I am not able to populate it from MachineController. I have used $form->get('pieces')->setData($arrcollectPieces) and other methods to add choices but I always get error.
How could I add choices from the controller to a Form?
In the form I use a queryBuilder
->add('pieces', EntityType::class, array(
'label' => 'label_pieces',
'class' => 'AppBundle\Entity\Piece',
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('p')
->where('p.pieceType = :pieceType')
->setParameter('pieceType', 1);
},
)
)
this works but when I try to add more queryBuilders (->add('pieces2'... and so on) I have the error because
Neither the property pieces2 nor one of the methods getPiecess2(), pieces2(), isPieces2(), hasPieces2(), __get() exist and have public access in class AppBundle\Entity\Machine.
How can I use the various queryBuilders not bounded to a method name in that way?
Maybe both approaches are incorrect and I should solve this in a different way?
(Posted on behalf of the OP).
How to make it using 1.
In MachineController forget setData(), instead turn the arrayCollection into 2 arrays (arKeys, arValues) and send them to the form as the 3rd parameter in createForm().
$form = $this->createForm(<type>, <data>,
array ('p_keys' => array(...), 'p_values' => array(...)));
From MachineType.ConfigureOptions() we can fetch them
$resolver->setDefined(["p_keys",'p_values']);
and they will be available in MachineType.buildForm()
$options['p_keys'];
$options['p_values'];

Symfony Unit Testing - Set Value for Javascript Rendered Elements

In Unit Testing, How can I set a value to the Select box options in which drop down options are rendered from Javascript ?
When I set a value, I am getting Invalidargument exception.
Note: Form is a general HTML Form
Referred links: symfony unit tests: add/modify form action
Thanks for # Matteo comments.
In Unit testing,
For setting values for the Select box, which are not available in the Drop down,
Use Posting the data instead of submitting the form,
$this->client->request('POST', $postUrl, $formValueArray);
$formValueArray = array('data' => 'value');
or
$formValueArray = array(
'myform' => array(
'data' => 'value'
))
);
Note: It can be used to set all the form fields which are not available in the forms.

Validate a Collection Field Type in Symfony 2 with allowExtraFields=true

I'm trying to validate a collection form field:
$builder->add(
'autor',
'collection',
array(
'type' => 'text',
'options' => array('required' => false),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'error_bubbling' => false
)
);
I use JavaScript, as suggested in the Cookbook, to dynamically add more text fields to the collection. My problem is, that I don't know, how to validate these fields. The collection validator lets me validate specific fields of a collection by their name but not simply every field of it. How can I manage that?
Even cooler would be, if I could check, if at least one of the fields is notBlank instead of forcing it to every field.
Best regards
You can use the "constraints" option defined in form Field Type that are available on all fields.(http://symfony.com/doc/master/reference/forms/types/form.html#constraints).
In your case, you can add your constraint like this:
$builder->add('autor', 'collection', array(
'constraints' => new NotBlank()),
));
(in this case dont forget to include the constraints provided by the Validation component:
use Symfony\Component\Validator\Constraints\NotBlank; ...)
i didnt test but i think with this every input will be validate againts the constraint you assigned to the field, and as you have the option "error_bubbling" as false, an error message should be attached to the invalid element.
--EDIT--
Since you even use the 2.0 version of Symfony i think this solution solves your problem, however I strongly advise you to update to the 2.3 version.
You can create a Form Event Subscriber(http://symfony.com/doc/2.0/cookbook/form/dynamic_form_modification.html) that will be listening the POST_BIND event.(note that Post Bind event is Deprecated since version 2.3 and will be removed in 3.0);
In your subscriber class, you will validate each of your submited authors as you want and add an error to the form if something is wrong.
Your postBind method could be something like this:
public function postBind(DataEvent $event)
{
$data = $event->getData();
$form = $event->getForm();
if (null === $data) {
return;
}
// get the submited values for author
// author is an array
$author = $form['autor']->getData();
// now iterate over the authors and validate what you want
// if you find any error, you can add a error to the form like this:
$form->addError(new FormError('your error message'));
// now as the form have errors it wont pass on the isValid() method
// on your controller. However i think this error wont appear
// next to your invalid author input but as a form error, but with
// this you can unsure that non of the fields will be blank for example.
}
you can check the Symfony2 Form Component API if you have any doubt about a core method.
http://api.symfony.com/2.0/index.html

Allow multiple date formats in symfony2 form builder

A client requested this. He wants to allow multiple date formats for a birthday field. The documentation didn't give me any clues how to realize it and neither did google.
Anyone who experienced such a request before and has a lead how to achieve this?
Currently it looks like this:
$builder->add('xxx', 'birthday', array('widget' => 'single_text', 'invalid_message' => 'some message (dd-MM-yyyy)', 'format' => 'dd-MM-yyyy'))
If you want to handle different date formats in your form, you ought to look at DataTransformer
It helps you to transform data from one format to another, for example:
2013-03-26 ==transform==> 2013/03/26
2013.03.26 ==transform==> 2013/03/26
26.03.2013 ==transform==> 2013/03/26
Data transformer should NOT be used in this case.
The main point of data transformer is to convert a data back and forth between view <=> norm <=> model.
It's not your case, you don't want a bidirectional transformation.
What you want is to filter the data, and for that, you can use a form event:
$builder->add(
$builder
->create('xxx', 'birthday', [...])
->addEventListener(
FormEvents::PRE_SUBMIT,
function(FormEvent $event) {
$value = $event->getData();
// Do the filtering you want (for example replacement of special chars with a dash)
// $value = preg_replace('[^\d]', '-', $value)
$event->setData($value);
}
)
);
And you are done, the data is filtered on the PRE_SUBMIT event, before validation.
I wrote this example from memory and didn't tested it, maybe you'll should adapt it (and add your field option instead of [...].

Field api, defining new fields and getting/setting values

I'm able to create a field, using
$form['title'] = array( '#type' => 'text', '#value' => 'Drupal');
1) But I want to be able to get/set the value from the database. How would I do it?
2 )P.S. what's the point of having a '#" in front of type and value ?
First of all I don't know what Drupal version are you using.
Secondly try to get some more info from the my answer:
1) Use Database API in order to get values from database.
2) Read more about Form API.
Hope this helps.

Resources