top | item 3927652

Javascript - Beautiful Validation, No Extras.

34 points| Nijikokun | 14 years ago |gist.github.com | reply

29 comments

order
[+] jashkenas|14 years ago|reply
... or, instead of (ab)using a ternary, the same idea in CoffeeScript:

    return if not username
      error: "No Username Given.", field: 'name'
    else if not password
      error: "No Password Given.", field: 'pass'
    else if username.length < 3
      error: "Username is less than 3 Characters.", field: 'name'
    else if password.length < 4
      error: "Password is less than 4 Characters.", field: 'pass'
    else if not (/^([a-z0-9-_]+)$/i).test(username)
      error: "Username contains invalid characters.", field: 'name'
    else
      false
Hopefully a bit more readable. Link to see the compiled JS output: http://goo.gl/QhR9c
[+] swannodette|14 years ago|reply
The whole point of the OP was revealing the structure of the data being matched (like a routing file). This code completely obscures that. And I'm not sure this is more readable as the number of conditions grow.
[+] PaulHoule|14 years ago|reply
I see validation in Javascript as a "bad smell."

If you want to impress me, develop some system that lets you write validation rules once and have them work on both the client and the server.

Back in my previous existence, before a strange series of events transformed me into an A.I. programmer, I was a generalist web developer. Back in 2001 I was helping some guys make a voice chat site aimed at Brazil, and against my advice, they implemented validation in Javascript and not on the server.

We launched and it all seemed OK for a few weeks until I get a call at 7 pm because the site is all f'ed up.

Well, doing some investigation I find that there's a user with the empty string for his user name and that this has had a bigger impact on the system than one might think.

I nuked the guy with the SQL monitor and added server-side validation that night.

Since then I worked on hundreds of different sites and web applications and I've had to deal with the busted app made by somebody who was too lazy to do server side validation many many times.

On one hand you've got the person who browses without Javascript turned on. Perhaps you're one of the cool kids who makes apps that don't work at all without Javascript, so you don't need to worry about him.

You still need to worry about the people that want to mess with you. If you build a community site that's substantial at all (say 10,000+ users) you're going to get hit. Today it's easier than ever to reverse-engineer client-server communication with Firebug and then use curl or another tool to make phony requests.

Apps built in this style, where all validation is done on the client have a surface area that's 100% soft underbelly.

[+] iambot|14 years ago|reply
while I agree with you that no one should rely solely on client-side validation - I don't believe that the OP was implying that (any) one should only use client-side validation.

Client-side validation is purely a means of reducing multiple requests / round-trips IMHO and it doesn't even have to be as reliable as a good server-side solution, but purely cover the basics, and provide quick feedback to the user while at the same time reducing load on the server.

[+] rollypolly|14 years ago|reply
Lines of code aren't at a premium. Why not favor readability over cleverness when possible?

I pity the person who'll be maintain this.

[+] Flow|14 years ago|reply
Why not simply do a straight exit-early if+return?

  if(!username || username.trim() = '')
     return { error: "No Username Given.", field: 'name' };

  if(!password || password.trim() = '')
     return { error: "No Password Given.", field: 'password' };
and so on.

Is that not clever enough??? Even a monkey would understand this.

[+] hackermom|14 years ago|reply
Why? The snippet of code is simple and functional enough to escape the need of being fiddled with ad infinitum ad absurdum. I can't see a cloud of maintenance need hovering over it.
[+] olavk|14 years ago|reply
I don't like mutating variables in an expression, and I don't get why username += '' is executed twice.

I like the declarative feel of the expression, but since it actually changes state, I find it dangerous, since you generally expect expressions to be side-effect free.

Edit: I guess the second username += '' should have been password += ''

[+] axefrog|14 years ago|reply
Looks reasonably clean, though you can't get an aggregated list of invalid fields doing it this way. Instead, you'll have to discover your errors one by one, as you fix them.
[+] mmuro|14 years ago|reply
If you really want to reduce the amount of JavaScript you write for validation, you should be using the jQuery Form Validation plugin. I know it's an extra but who cares. It's totally flexible and you can validate your form in one line of code.

http://docs.jquery.com/Plugins/Validation/

But yeah, ternary operators are a great way to save line space.

[+] ricardobeat|14 years ago|reply
Nice, clean approach. I wish ternary operations were more common and widely understood; some people might freak out when they see that, specially with the unusual indentation. I had to condition myself to go back to if/else to avoid the blame.
[+] lucian1900|14 years ago|reply
If as an expression is very nice indeed, especially in Lisp (where it comes from).

If you use CoffeeScript however, you also get expression if. Very handy.

[+] nicholassmith|14 years ago|reply
If someone doesn't understand ternary operations they need to take off the developer badge. Given they're a common feature in most languages and make life easier it's a pretty big thing to have glossed over.
[+] mattcole|14 years ago|reply
I actually thought maybe this was a joke. This seems like a pretty brittle and hard to maintain way to go about this.

Surely a better solution is something more declarative which is then wrapped up in a library of some sort that does the heavy lifting.

An example of declarative validation is in ASP.Net MVC 3 and above where you can define validation on the server side models, enable unobstrusive javascript and you get both server and client side validation where the client side work is done by jquery and the server side by the model binding infrastructure that turns http request data into controller inputs.

[+] pygorex|14 years ago|reply
"Trivial" !== "Beautiful" Validating two form fields in JavaScript is remarkably easy, and pretty much any solution will be trivial to implement - and easy to grok.

For more complicated forms using a tool like jQuery Validation plugin makes more sense: https://github.com/jzaefferer/jquery-validation

[+] fleitz|14 years ago|reply
The ternary operator is one of my favorites because it acts like 'if' in a functional language (eg. it always returns a value)
[+] ajanuary|14 years ago|reply
'if's returning a value is from expression oriented languages, not just functional. Functional languages are by necessity expression oriented because it makes no sense to have a statement in a functional language. However, not all expression oriented languages are functional.
[+] beggi|14 years ago|reply
Talking about validation, I've started using standard HTML5 input validation (with polyglots on the client) as the only validation client side, and then backup mechanism to display errors from the server if the data invalidates there.
[+] hackermom|14 years ago|reply
I guess this is an ok way to save some tiny, tiny amount of bandwidth and server resources now and then when a user makes a mistake - but one should still not, under any circumstances, refrain from server-side verification.
[+] randomdrake|14 years ago|reply
I don't think the OP was trying to say that server-side validation shouldn't occur.

That being said, your statement makes me think that you are overlooking an important aspect of client-side validation: instant feedback for the user. It's not necessarily just about saving bandwidth and server resources, but providing a clean and responsive user interface.