Client Side Validation Implementation
tjholowaychuk - May 14, 2008 - 19:01
| Project: | Validation API |
| Version: | 6.x-1.0-alpha1 |
| Component: | Code |
| Category: | feature request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | postponed |
Jump to:
Description
Not sure if you are aware of this jQuery plugin or not, but it will suit this module well.
http://jquery.bassistance.de/validate/demo/
http://plugins.jquery.com/project/validate

#1
I used the plugin mentioned above for a personal framework, works wonders. This module could be whipped up in nearly an hour or so utilizing this plugin I would defiantly suggest taking a look.
#2
I also would push for adding one of these. I have been involved with using the first one, the jQuery Validation Plugin from bassistance.de, and have been rather pleased with it.
I guess am just confused by what this Validation API will all do, as it seems like it is only planned to do validation using Ajax. Are there any solid plans to do pure client side JavaScript validation? I worry about Ajax validation due to cache and speed issues. Also, the jQuery Validation plugin already offers some limited Ajax validation out of the box.
#3
Pff.. that would be a waste if it was just Ajax, as far as I knew the whole point of this was to lower HTTP requests
#4
One eventual advantage is lowering HTTP requests, but the whole point is creating dynamic validation that can be linked to any form in Drupal. The phone CCK widget is a perfect example of something that could potentially be deprecated in its current form. Imagine if you wanted to only accept phone numbers from Madagascar. Even the phone CCK widget doesn't do that - you'd have to make a new widget or code a module with a form alter that would add a #validate or #element_validate to the form that would check the passing of phone widgets to a new validation hook no matter their content type. That's all assuming you know to do that.
What if instead you could just point at the textfield on the node edit form, click "add validator", enter a numerical mask or regular expression into a form, and click OK? Or what if you could just download a Madagascar validator from a validation collection and import it? The javascript validation, whatever its final form, is just an extra tasty topping.
If on top of it all, you only had to write *one* validator that worked in PHP and translated to Javascript ok, that'd be even better! However, the validation is still going to need to be hardened the most on the server side since Javascript is so easily turned off. Having some AJAX to utilize that server-side validation is another convenience to the user and is still less than a full page refresh. Going and implementing a 100% client-side validation engine I think is the biggest waste of time in the near timeline given the increasing use of things like NoScript or the Web Developer toolbar.
#5
In my small PHP framework UltraLite, I created a JS validator that works seamlessly with PHP as well. Masks, patterns, emails, urls, matches for passwords etc. Sure we may not be able to do this for ALL fields, and may not want to do this for all fields, but direct feedback to the user for even obvious things such as required fields would be beneficial.
#6
I can't think of any ideal options for doing the client side validation, but here is my take on the ideas I've had.
1. Javascript validation rules in addition to PHP validation rules: I don't like this because it requires 2 rules to be maintained for each validator once you get anything more complex than a regex.
2. Ajax submits in an attempt to add functionality similar to http://jquery.bassistance.de/validate/demo/ : This is nice because it allows you to only have one rule, in PHP, which will be evaluated with an Ajax submit. The speed would probably make this unusable though, especially if you were trying to do validation as often as is done in that demo.
3. Switching the form submit into an Ajax submit similar to http://drupal.org/project/ajax_validation : This would work, but doesn't allow for immediate feedback as the user is filling out a form. The preferred behavior is something like the Password Strength check.
4. Some combination of 2 and 3 where config would dictate if onblur of an element triggered validation for it. Still wouldn't be as slick or as speedy as the jquery demo, but it might be a nice compromise. Maybe some form of 1 in there as an option too....not so sure about that though.
#7
#8
How similar are JS and PHP's regular expressions? If all validation could be expressed in regex (even though there are functions like is_numeric() and such), you could potentially re-use the same code on both ends? Or is this just fantasy? ;)
I agree that #1 only would be a huge pain. Servers are cheaper than programmer hours required to write two version of every validator; especially the trickier ones.
#9
It's too bad so many comments are worried about writing regular expressions. First of all, I'm surprised anyone is planning on creating regular expressions from scratch. These kinds of regex's to test email or phone numbers have been written hundreds of times. Why try and invent them from scratch and go through hours and hours of testing your new ones when you could make use of existing ones? The point of using one of the above JavaScript validation libraries is also to avoid having to rewrite them from scratch. The first one, the jquery.bassistance.de library, makes it as easy as dumping a PHP array with the rules defined into JSON for simple validation setup. This is the approach I've implemented before, only from Perl to JSON instead of PHP.
I guess I'm disappointed in the plans to not make use of an existing validation jQuery plugin that offers good usability and that has been tested and refined. And to say that using a JavaScript validation library is worse than Ajax validation because users can hack it doesn't really hold true. You can hack any Ajax version just as well, it's all JavaScript in your browser at the end of the day, which is fair game for hacking once its in your browser. The point of client side validation, of any sorts, is not to be the final say, but only to give the user assistance. Server side validation will of course still always be necessary. But if it does weed out some spam, bonus!
I hope this doesn't turn into a crazy heated debate. It is a very good point that there is less code to maintain by only having to maintain PHP rules. I'm just offering up my suggestions/comments based on my experience of working on a similar project for a custom CMS.
#10
It's not about writing regular expressions. The validation doesn't even have to be a regular expression. It's about putting in place a framework by which to have a flexible way to add validation to any field.
Validation could come with some default validators when it gets closer to stable like CCK comes with some default widgets, but admins could go out and grab stuff from places like http://regexlib.com/ if they want regexs of their own. Craig has implemented some import/export functionality so people can share their work or copy between similar sites.
I'm not even anti jQuery validation plugin, but in the progression of the development in this module, I think the focus needs to start at the hard-line serverside validation and progress to the assistance level.
If I may presume to expand on webchick's comment, I think she was eluding to the fact that Craig has started venturing into the Javascript end of this module and is passing along her thoughts on how the serverside validation might be able to just be passed to the Javascript side to save a lot of work on the programming and site configuration ends of using the module. It was an idea that came up early in the proposal for this project and she's just using this as a good opportunity to remind everyone about it.
#11
I still think the jQuery plugin is a great way to go. Essentially providing us with a ton of 'free' work, which would not have to be copied on the PHP since well.. the plugin author wrote it, not us :) Secondly the validation plugin is very expendable I have used it in several projects it works great. JavaScript regular expression patterns pretty much follow the norm but have I believe a few less modifiers (cant remember off hand) but certainly small differences for the most part.
#12
@tjholowaychuk: That plugin is pretty sweet, it just isn't really applicable for this project. The problem is that the plugin contains validations like...
(ignore the php tag, this is javascript but code tags weren't preserving spacing)
<?php
creditcard: function(value, element) {
if ( this.optional(element) )
return "dependency-mismatch";
// accept only digits and dashes
if (/[^0-9-]+/.test(value))
return false;
var nCheck = 0,
nDigit = 0,
bEven = false;
value = value.replace(/D/g, "");
for (n = value.length - 1; n >= 0; n--) {
var cDigit = value.charAt(n);
var nDigit = parseInt(cDigit, 10);
if (bEven) {
if ((nDigit *= 2) > 9)
nDigit -= 9;
}
nCheck += nDigit;
bEven = !bEven;
}
return (nCheck % 10) == 0;
}
?>
So now if I'm trying to apply credit card validation on a field and use this validation, I either have to write a PHP equivalent and hope that I've matched the logic of this Javascript or I deal with the consequences of somebody turning off Javascript and bypassing my validation altogether. And then as you come up with new validations to add, you find yourself forced to write pairs of JS/PHP validations.
I think the route that TapocoL is headed down (option 3 from comment #6 above) is going to be a good start for creating one PHP rule that will allow for form validation without a page refresh of the original form client-side.
#13
My plans are to head down the AJAX path. Which is replacing the current submit with an AJAX request for the validation, then continuing on with the normal submit process on success. However, I do see a benefit towards allowing pure javascript rules to be written in addition to the PHP validation. So, what about requiring a PHP rule, then they have the option to enter in a Javascript rule, as well. Then, if the Javascript rule is created, it will be added to the JS on that page. If not, it will do the AJAX request. However, I believe this idea is out of the scope of GSoC, so I could see this being implemented after SoC in completed.
Thoughts?
#14
Personally I think JS validation would be the best, regardless if we have to write a bit of extra code or not, performance would be my concern for sure, plus as someone above mentioned the Perl-ish regex patterns could most likely be shared between both PHP and JS
#15
As long as server-side is the only way to have a final say on the input, it is the best. With regards to client-side JS vs AJAX, it still all depends on clients having JS turned on. I personally think AJAX is gimmic-y, but facing having to write two sets of validation, which might not even match in functionality, sounds worse than settling for the gimmic way. That's why in this case I favor the venture into AJAX. Then perhaps regex can share itself to JS and there can be JS, PHP, and JS to PHP through AJAX all running on one form. It's the idea of JS trying to match a PHP code validator that bothers me.
#16
I completely agree: write code once, not twice. If that means only AJAX validation, instead of "plain JS" validation, thereby causing extra server load, then so be it. However, it'd still be *essential* IMO to allow for plain JS validation wherever possible, by passing (form item #id, regexp) mappings through
Drupal.settings(which can be updated in AJAX callbacks if necessary).#17
Im curious to see how it will go, I dont think it would really be much of a problem at all with regular expressions thanks to PCRE. I agree that ideally nothing should be duplicated, however I dont see the point of doing it all if your going to be causing several requests to validate a single form, pretty wasteful!
#18
For now, forms will be validated with AJAX (which means ALL PHP validation scripts). However, this could be considered for a change to PHP and JS validations in the future, since the request is a worthwhile discussion. Just to mention, there is a possibility of the ajax section being moved to a different project, which would open up several problems with linking the two projects.
#19
Writing separate JS and PHP is not doable because it takes double the time to develop and maintain. Using a separate library for JS validation causes problems like validators being available in JS, but not in PHP or the other way around. Allowing users to write both JS and PHP validators would make the module itself more complicated. In reply to webchick: not all validators are 'simple' regular expressions, so even if the JS and PHP regex syntax would be equal (which they are not enterily as far as I know), automatically creating JS validators by using the PHP regex can't be done.
The simplest and most robust way to go is PHP validation by AJAX. The only drawback is that this process is dead slow. Validators that don't use other functions may be executed during hook_boot(), but there is no way to know whether validators stand alone or not. Therefore Drupal needs to execute a full boot for every field validation and this takes relatively much parse time and server power. I'd like to see some bechmark results on using AJAX for PHP validation (don't know how to do proper benchmarks myself).
@TapocoL: why move the AJAX part to a separate module? Is it that much code?
#20
Using Ajax all the time would be terrible, granted sometimes necessary. I dont see why we cannot have various types of validators, some sharing PCRE, some Ajax callbacks, etc..
#21
That would require keeping track of what validators are not available to JS, what validators are regular expressions (which might be exchanged with JS), what validators already have a JS counterpart, etc. It can be done, but it's not as simple and robust as full AJAX validation. It would also make the administration panel far more complicated.
#22
Yeah but the performance implications of an entirely Ajax solution is horrendous... what about input masking, and real-time validation, this is NOT going to be done using Ajax thats for sure.
#23
It's already being done using AJAX, which is real-time.
#24
@Xano
http://drupal.org/project/ajax_validation
I talked with the developer a few weeks ago, and we had talked about moving my code to a D6 port there. The AJAX is totally self-sufficient, and you can see in my latest versions that I separated the module already. I just feel people would not be looking for AJAX form validation in a Project about adding validation rules to any form field on a site. Plus, that project's scope is exactly what I completed in the AJAX validation module in this project.