Hi,

first of all: thank you for this wonderful approach to forms. Forms are nasty in my world! Not anymore!

Now, what i was wondering, and pardon me if I overlooked something that should be obvious, but how to go about validation logic?

Example:

  • A form field with the number of items someone is interessed in? (can be 1, can be 2450, but should only be numbers!)
  • An id field that expects exactly 10 characters of alphanumerical input? (should only exactly be 10 characters in length!)

Is this something that can be done with the #states-settings?

I could solve this on the client-side of course, but that would not make up for a robust form of course :)

How is your take on thi - if it is not implemented yet, is it a planned feature?

Kudos to you!

Comments

tne_ created an issue. See original summary.

jrockowitz’s picture

Below are some input examples that accomplish what you are looking for.

textfield_number_pattern:
  '#type': textfield
  '#title': 'Text field using number pattern'
  '#pattern': '^[0-9]+$'
html5_number:
  '#type': number
  '#title': 'HTML 5 number element'
  '#min': 0
  '#max': 2450
  '#step': 1
textfiled_alphanumeric_pattern:
  '#type': textfield
  '#title': 'Text field exactly 10 characters'
  '#pattern': '^[a-zA-Z0-9]{10}$'

All the above inputs are provided by Drupal Form API there just not fully documented...yet.

Below are the change records you can use for reference.

New FAPI property #pattern is introduced for native HTML5 pattern attribute
HTML5 support for form elements

Also, there is also a machine name element which I need to setup a working example.

#2693871: Add machine_name element example

jrockowitz’s picture

Status: Active » Needs review
tne_’s picture

Status: Needs review » Active

That works great, thank you.

Of course I should have read "uses FAPI", and it is nice to see D8 adapted symfony validator constraints as plugins.

Would it help to write an example form with the available validator options for starters?

jrockowitz’s picture

I now understand your question a little better. Getting more familiar with Symfony's Validator is on my todo list.

Since YAML forms are just FAPI PHP render arrays, we should first figure out how a Symfony Validator would be integrated into a simple form.

This integration/functionality should be handled in the dedicated contrib module so that any FAPI form (and YAML form) module could leverage Symfony's Validators.

...and the Drupal Symfony Validator is a D7 example of what we are looking for.

Can you please contact the module's maintainer (https://www.drupal.org/u/legovaer) and see if they are going to port their module to Drupal 8?
BTW, also mention to the maintainer that the 'validators' project namespace is available.

tne_’s picture

(Informed the maintainer via irc/pm, let's see if he is around)

legovaer’s picture

I'm the maintainer of DSV and I'll start working on the D8 port ASAP. I'll update this issue as soon as the port is available.

Saphyel’s picture

any updates? I think is important, because html5 doesn't work in all browsers

jrockowitz’s picture

Drupal 8 core does perform server side validation on all HTML5 inputs, this includes email, number, date, url. Even the (regex) #pattern property has server side validation.

For example, here is the Drupal's HTML5 number input validation callback.

I still think it would be great to have Symfony's Validators available to FAPI and YAML forms.

legovaer’s picture

I'm still working on the port. In the meantime, feel free to help me get the D7 version out of the sandbox stage in #2603256.

legovaer’s picture

I just committed the 8.x code. The issue of the original poster can be fixed like this:

A form field with the number of items someone is interessed in? (can be 1, can be 2450, but should only be numbers!)

...
/**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['amount_of_items'] = array(
      '#type' => 'textfield',
      '#title' => t('Type'),
      '#validators' => array(
        'Type' => array(
          'type' => 'int'
        ),
      ),
    );

   return $form;
...
An id field that expects exactly 10 characters of alphanumerical input? (should only exactly be 10 characters in length!)
...
/**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['regex'] = array(
      '#type' => 'textfield',
      '#title' => t('Regex'),
      '#validators' => array(
        'Regex' => array(
          'pattern' => '/^[a-zA-Z0-9]*$/',
        ),
        'Length' => array(
          'min' => 10,
          'max' => 10,
        )
      ),
    );
   return $form;
...
legovaer’s picture

Status: Active » Needs review
jrockowitz’s picture

I found a bug that stops the YAML form module from using #validators.

#2722761: Form elements within nested render array is not supported.

As soon as it is fixed the attached example will start working.

Your module should be updated to full drupal project and I can include some #validator examples.

I did created another ticket to #2722767: Simplify this module's namespace to just be the validators.module.

legovaer’s picture

All suggested tasks from #13 have been completed.

@tne_ you should now be able to accomplish what you suggested here.

jrockowitz’s picture

@legovaer As soon as your project application #2603256: [D7-D8] Validators is approved I will add some #validators examples to the YAML form module.

legovaer’s picture

I just released the Validators module. We can add examples now.

jrockowitz’s picture

Wow, I created a feature branch, started adding #validators to input examples, and realized that when someone adds #validate hooks to a submit button, the form's #validate hooks are not executed. So right now the YAML form module is bypassing the `validators_form_validate()` callback. This is definitely an issue with the YAML form module that I need to think about and address.

Some more notes

- \Drupal\Core\Form\FormBuilder::doBuildForm is what decides if the trigger elements validate handlers are used.
- \Drupal\Core\Form\FormValidator::executeValidateHandlers is what executes that validators.

Possible solutions

- Examine $form['#validate'] and execute all custom callbacks (excludes ::validateForm) .

jrockowitz’s picture

StatusFileSize
new3.27 KB

Here is patch with just email and isbn examples.

I think everyone will understand the #validators: Email example and #validators: Isbn example shows the full potential on the #validators property,

  • jrockowitz committed cb01e03 on 2693855-validators
    Issue #2693855: Validators. Update index.md
    
legovaer’s picture

Status: Needs review » Reviewed & tested by the community

The patch in #18 looks good. Nice that you spotted that issue! Might be worth adding some automated tests to test that functionality.

  • jrockowitz committed 8fdb72c on 2693855-validators
    Issue #2693855: Validators. Make sure trigger element has #validate...
jrockowitz’s picture

I am going to add some automated tests but I am not 100% comfortable with my solution because it seems like a hacky work-around.

  • jrockowitz committed 5cb2783 on 2693855-validators
    Issue #2693855: Validators. Write test for $form['#validate'] handling.
    
jrockowitz’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new5.17 KB

Here is the update patch a test.

  • jrockowitz committed d034383 on 2693855-validators
    Issue #2693855: Validators. Write test for $form['#validate'] handling.
    
jrockowitz’s picture

StatusFileSize
new6.26 KB

Arg!!!. The patch was missing the test because I forgot to add it. If this passes I will merge it tomorrow.

Status: Needs review » Needs work

The last submitted patch, 26: validators-2693855-25.patch, failed testing.

  • jrockowitz committed dae128f on 2693855-validators
    Issue #2693855: Validators. Write test for $form['#validate'] handling.
    
jrockowitz’s picture

Status: Needs work » Needs review
StatusFileSize
new8.27 KB

jrockowitz’s picture

Status: Needs review » Fixed

I merged the patch, pushed a new beta release, and added a link to the Validators module to the project page.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.