Problem/Motivation
Currently the Field Validation (field_validation) integration is by default limited to those validations known to clientside_validation_field_validation_regular()
.
This is great since those validations ensure that whatever can be done on the client side is done there.
However it would be nice to be able to run more complex validations using the remote validation functionality that's shipped with jQuery.validate.
There already examples for "remote" validations e.g. drupalURL
/ phone
/ captcha
. Although those validations use synchronous (blocking) ajax calls which can lead to bad user experience.
Proposed resolution
The attached patch contains:
- Generic remote validation integration for any Field Validation rule.
If a rule can't be re-created on the client side the validation methodfieldValidationAjax
is used - all Field Validation rules are collected and executed at once.
The ajax callback is done usingjQuery.validator.methods.remote()
, this ensures maximum compatibility with jQuery.validator and is a non-blocking (async) approach. Further this ensures we'll have context specific error messages.
The integration is as generic as possible, however further testing is needed to see if there are any uncovered scenarios. - Generic integration with High-performance JavaScript callback handler. The code does it's best to handle dependencies to be able use the JS callback.
- Enhanced the ajax handling for the remote validation. Supports now progress (throbber) and works around some quircks with the success handler of jquery.validation
- Integration with
Drupal.states.Trigger.states
, which means you can now use#states
to write something like this:
$form['email_retype'] = array( '#type' => 'textfield', '#states' => array( // Hide the email re-type field as long as the email field hasn't valid data. 'invisible' => array( ':input[name="email"]' => array('clientside_validation' => FALSE), ), ), );
This is globally available and independent from "Field Validation". Available states are:
- clientside_validation (!clientside_validation): TRUE on initialization. Set once the validation is run
- clientside_validated (!clientside_validated): FALSE on initialization. TRUE if the validation is done, reset to FALSE as soon as the value is changed.
- Integrate with Conditional Fields - which means you can now configure the
#states
in the Field UI!
Remaining tasks
Reviews needed.
User interface changes
None.
API changes
If someone already uses hook_clientside_validation_rule_alter()
the new implementation might duplicate or interfere with that custom validation.
Comment | File | Size | Author |
---|---|---|---|
#7 | interdiff-2413877-6-7-do-not-test.diff | 9.01 KB | das-peter |
#7 | clientside_validation-enhance-field_validation-integration-2413877-7.patch | 19.93 KB | das-peter |
Comments
Comment #1
das-peter CreditAttribution: das-peter commentedOh, something was very wrong with the first patch :(
However, here's the follow up.
This brings:
Drupal.states.Trigger.states
, which means you can now use#states
to write something like this:This is globally available and independent from "Field Validation"
#states
in the Field UI!Comment #2
das-peter CreditAttribution: das-peter commentedNext patch with some enhancements for the JS integration.
Hope I'm able to save a bit time by doing this. Performance is a hard requirement here.
Comment #3
das-peter CreditAttribution: das-peter commentedEnhanced the configurability of the integration with the JS module. Adjusting just the dependencies might not be enough. So now modules are able to alter the whole definition.
Also added the missing
clientside_validation_field_validation.api.php
for the new hook.Comment #4
das-peter CreditAttribution: das-peter commentedDarn, missed one variable replacement.
Comment #5
das-peter CreditAttribution: das-peter commentedUpdated patch.
New stuff:
Comment #6
das-peter CreditAttribution: das-peter commentedMade states integration more defensive.
clientside_validation.js
is loaded sometimes on pages whereDrupal.states
isn't available.Comment #7
das-peter CreditAttribution: das-peter commentedUpdated JS integration. Switched to JS 2.x due to security reasons. This also helped to decrease the code needed as JS 2.x brings some required alter hooks I was adding here.
All in all less code is needed to get the same functionality :)
The JS integration still is optional, so no dependency there.
Comment #9
Jelle_SFixed in latest dev (1.x). Thanks for the patch! Any chance you'd want to do something similar for 2.x?
Comment #10
das-peter CreditAttribution: das-peter commentedHoly freaking cow! I didn't expect that this goes in so smooth :)
Thank you so much!
Hmm, about the 2.x stuff, I'd like to - but it's unlikely that I'll find time in near future. All this work was done for a customer project, which will take at least until August and absorbs almost all of my work-time.
Comment #11
cravecode CreditAttribution: cravecode commentedIs there any way to get an example of how to use this? I'm currently trying to implement a "remote" validation rule for a custom webform component. Thanks!
Comment #12
mibfire CreditAttribution: mibfire commented@das-peter could you privide us an exmaple? and thx your great work!
Comment #13
skaduHi there, how does this handle validation configurations that require multiple fields? I have an "emails must match" rule that was working until the latest version of this module (7.x-1.42). The ajax validation seems to only ever send one value to the server for validation, which (AFAIK) means that rules depending on multiple values will always fail.Am I going crazy? Or is this a real issue?Had a bit more time to look into this. Any rule that is not matched in the function clientside_validation_field_validation_regular is sent through via AJAX (instead of being ignored on the client side), as mentioned in the proposed resolution section.
The problem with this approach is that certain Field_Validation rules use groups of fields to perform their validation (Equal Values on Multiple Fields, Unique Values, etc...). In these cases, the AJAX validation kicks in and attempts to validate against nothing (since the AJAX request only sends the value of the current field being validated.
The old way this worked, is the client side validation just failed silently and then during server side processing, the validator kicked in. Currently, this AJAX validation causes any field with group based validation to fail, every single time.
I am about to be away from my computer for several days, so I can't offer a solution yet, but I would imagine there should be some sort of exclude for rules that use group based validation as a short term solution.
Comment #14
Jelle_S