Best JavaScript Solution for Client-Side Form Validation and Interaction

Best method for Form-Validation (Javascript)

You can use a client side form validation library like http://jqueryvalidation.org/
Read Best JavaScript solution for client-side form validation and interaction? for more details.

Flexible and powerful form-validation solution

Disclaimer: I have a horse in this race; I'm the author of the following library.

I've answered a similar question previously that you might want to check out. I'd like to suggest a framework that I've designed called Regula. It does most of what you're asking. Validation rules (or constraints) can be attached directly on the element using the data-constraints attribute.

For example, you can do something like this:

<input type="text" name="something" data-constraints='@Required' />

You can even set things like the error message or labels:

<input type="text" name="something" data-constraints='@Required(label="something" message="{label} is required.")' />

Custom validation is also easy. You do need to define a validator in JavaScript once, but then you can use it after that:

regula.custom({
name: "MustBe42",
defaultMessage: "The answer must be equal to 42",
validator: function() {
return this.value == 42;
}
});

And then:

<input type="text" name="something" data-constraints='@MustBe42' />

Parameters are also supported:

regula.custom({
name: "MustBeSpecifiedNumber",
params: ["number"],
defaultMessage: "The answer must be equal to {number}",
validator: function(params) {
return this.value === params.number;
}
});

And then:

<input type="text" name="something" data-constraints='@MustBeSpecifiedNumber(number=10)' />

You asked about validation groups, and that can be done in Regula as well:

<input type="text" name="street" data-constraints='@Required(groups=[AddressGroup])' />
<input type="text" name="city" data-constraints='@Required(groups=[AddressGroup])' />
<input type="text" name="state" data-constraints='@Required(groups=[AddressGroup])' />
<input type="text" name="zip" data-constraints='@Required(groups=[AddressGroup])' />

Then you can validate with:

var constraintViolations = regula.validate({
groups: [regula.Group.AddressGroup] //AddressGroup property is automatically added
});

As far as HTML5 support and Asynchronous Validation, those features will be available in version 1.3 of Regula, which is currently in Alpha. I have a few minor features and documentation to update, but you should be able to checkout what is in on GitHub currently and it should work for you. HTML5 and Asynchronous Validation is mostly done.

With regard to HTML5 constraints, you can use the native attributes, or use Regula-wrapped versions which provide you more options like assignment to groups and custom messages. For example:

<input type="text" name="something" required="true" /> 

Will be recognized by Regula and validated. But you can also do this:

<input type="text" name="something" data-constraints='@HTML5Required(groups=[MyGroup], message="{label} is required!", label="something")' /> 
<input type="text" name="somethingElse" data-constraints='@HTML5Required(groups=[MyGroup], message="{label} is required!", label="somethingElse")' />

You can't normally do that with just the native HTML5 validation. An important thing to note however, is that the browser must support HTML5 validation for this to be able to work. Regula doesn't attempt to emulate HTML5 functionality since it involves more than just simple validation; it involves specific UI components as well. So for cross-browser compatibility you will need to use a polyfill or shim of some sort.

Asynchronous validation is also possible:

regula.custom({
name: "AsyncConstraint",
async: true,
defaultMessage: "{label} did not validate properly.",
validator: function(params, validator, callback) {
jQuery.ajax({
url: "myurl",
dataType: "json",
data: someData,
success: function(data) {
callback(data.successful)
}
});
}
});

Then you can annotate your element with:

<input type="text" name="something" data-constraints='@AsynchronousConstraint' /> 

and validate with:

//Simply calling validate will validate all constraints on all elements
regula.validate(function(constraintViolations) {
//do stuff with constraintViolations
});

It is also easy to do conditional validation and use pre-existing validators:

regula.custom({
name: "ConditionalRequired",
defaultMessage: "The answer must be equal to {number}",
validator: function(params, validator) {
var result = true;
if(some condition is true) {
result = validator.required(this, params, validator);
}

return result;
}
});

The validator object basically gives you access to the raw validator-functions for each of the constraints.

Regula has a bunch of other features as well, such as compound constraints (basically like in JSR-303).

Regula doesn't have any UI-related logic, like displaying error messages as such. It is only a validation engine and so it only does that. How you want to display the error messages is up to you.

Hopefully you find this useful! As I mentioned before, the current version is 1.3.0; it is in alpha and you can get it from here.

Javascript form-validation framework: Request for Review

I like it a lot already, it keeps my html clean and the ability to build custom validators is great. One thing I added was a short hand for binding the validation and submit functions, and wrapped it up as a jQuery plugin:

if (jQuery) {
(function($)
{
$.regula = function(formId, callback)
{
regula.bind();

$("#" + formId).submit(function()
{
var validationResults = regula.validate();

if (validationResults.length > 0)
{
if (callback)
callback(validationResults);

return false;
}

return true;
});
};
})(jQuery);
}

Infact, I've just blogged about it to as I am that impressed with how clean and easy it is. I'm still going to spend time going through your source, to see how your accomplished it, but its a great start :)

In regards to integrating your framework, I work mostly with ASP.NET MVC, and it would be interesting to see how it translate server-side validation logic into client-side constraints. Something I might look over in the next month or so.

How would you implement Adobe CQ client side validation for form fields?

Since you are dealing with the rendered page, I recommend you add client side validation using a standard validation library, such as the jQuery validation plugin:

jQuery Validation Plugin

It does what you are looking for, such as this sort of thing:

Sample Image

I've used this in CQ pages. Check out the video on that page--it gives a good demo of how to do just what you are looking for. And check out the demos page:

Demos

This isn't the only validation option, so you could also consider others. I think the key is to just approach this problem as a typical HTML/JavaScript need rather than a CQ need.

Also see Best JavaScript solution for client-side form validation and interaction?

Why do we need both client side and server side validation?

Client-side validation just avoids the client from going "but I filled this all in and it didn't tell me anything!". It's not actually mandatory, and in reality, client-side validation is a very new thing (read: 5 years old or less). In practice, all it does is prevent your client (with JS enabled) to know whether the form is okay before reloading a page.
If AJAX is in the game, it is different - it allows you to save bandwidth as well as to provide user with feedback before submission.
Finally, if you're building strictly client-side, peer-to-peer exchange apps (think games), you'll want client-side validation to keep the clients from cheating.

Server-side validation is also crucial due to the fact that client-side validation can be completely bypassed by turning off JavaScript. In a way, JS-driven validation is a convenience and an aesthetic/cosmetic improvement and should not be relied upon. Furthermore, it is trivial to edit the source of a page locally in order to disable or bypass even the most complex of JS validation.

What could a user do if you do not server-side validate? Anything, depending on how you use their data. You could be allowing users to drop entire databases (or worse, leak them), modify anything they like (or worse, read anything they like. Directory traversal flaws are extremely common entrance points for naughty people), and elevate their privileges at will. Do you want to run this risk? Not validating user input is like trusting people and not installing locks on your house.

For a website with high user interaction, is it better client side rendering or server side renderin?

Yours is a good question, but it has an answer that's almost impossible to predict. Taking a web app from a handful of users to a few thousand always uncovers surprising performance bottlenecks.

Will a bottleneck be on raw downbound bandwidth? Will there be a big gain to be had by slimming down your response to api calls and page requests? It's possible, but Heroku and other good host vendors do a good job of bandwidth. Plus, https compresses data as it encrypts it, so repetitive html isn't as costly as it seems. So getting your server to render lots of html is probably acceptable.

Will some bottlenecks be at the app-database interface? It's likely if large amounts of data and complex filtering criteria are in play. Every successful web app needs vigilance on its database. You'll have to add indexes or develop less elegant workarounds for problems you can't presently imagine.

Will you have contention between processes that ingest your data and processes that use it? Probably. But the details of that contention are hard to predict.

tl;dr. You have this thing working. There's no need to rework it now. Deploy what you have. Invite your users, and listen to them. Pay attention to how it performs, and concentrate your tuning and refactoring on areas where they prove necessary.



Related Topics



Leave a reply



Submit