Writing a single library for SSJS and CSJS validation – failed attempt #1

In this article I will demonstrate my first futile attempt to consolidate CSJS and SSJS libraries so that we only have to write validation once. I will also discuss JavaScripts Closures which unless you have already encountered them will make your head hurt thinking about it 🙂

Introduction

I was reminded in one of the comments on my blog last week about how it is still a pain in the butt to have to write client side JavaScript validation (to provide a good user interface) and server side JavaScript validation (to ensure data integrity and because CSJS validation is easy to break). So I set out to try and simplify this process by trying to copy a basic SSJS JavaScript validation routine in CSJS. I figured if the average XPage developer is now used to writing validation in SSJS then why confuse things. Try and mimic the basic functionality client side and away we go – simple right?

Comparing two fields in SSJS

So here is my basic example – comparing two password fields which have been submitted

<xp:validateExpression message="Passwords Must Match">
   <xp:this.expression><![CDATA[#{javascript:
        if (getComponent("Password").getSubmittedValue() != getComponent("ConfirmPassword").getSubmittedValue())
          {
            return false;
          } else {
            return true;
          }
        }]]>
   </xp:this.expression>
</xp:validateExpression>

Here’s my form in Firefox – the Password field is the one we are going to look at in the examples. I want to test if the Password and ConfirmPassword fields have the same value – in the client and on the server. The above code does it on the server. (originally posted here)

fail1

So the trick is to try and mimic getComponent(“Password”).getSubmittedValue() in client side JavaScript and then the code which is already written can serve to validate on the client side as well – well that is the plan anyway.

Not as simple as you’d have thought

So I started by learning about how to chain JavaScript functions and would you believe it is rather mind-bendingly simple and yet amazing complex to get your head around at the same time.

Reading:

http://stackoverflow.com/questions/9338439/how-to-chain-functions-without-using-prototype/9338486#9338486

http://stackoverflow.com/questions/6256016/how-can-i-call-any-function-in-a-chain-of-functions-without-the-chaining

But the basic premise it to be able to “return this” from the original function which therefore returns a function – which means you can then .doSomething to it.

First – Prototypal inheritance

A cool part of the JavaScript language is that you can create prototype (copy) of an object and it inherits all the traits of the originator – the problem I ran into with this is that you have to create a object in the first place to then chain the function to it – that did not mimic the exact syntax I was looking for – maybe another day. (example from this website)

function Pet(name, species){
  this.name = name;
  this.species = species;
}
function view(){
  return this.name + " is a " + this.species + "!";
}
Pet.prototype.view = view;
var pet1 = new Pet('Gabriella', 'Dog');
alert(pet1.view()); //Outputs "Gabriella is a Dog!"

Then closures

OK for those of you who do not understand JavaScript closures:

  1. Join the club
  2. Sit down with a good cup of tea and a blanket
  3. This is going to hurt

As far as I understand it (and it would not be the first time I was wrong) – a JavaScript closure is basically a function within a function which has access to the locally scoped variables after the function has returned.

In the spirit of Hammer Horror films – a closure is a function within a function which can live on after the original function is finished. It can then feed off the innards of the function which is now dead – nice!

Told you your head would hurt – go read this, it might help http://www.crockford.com/javascript/private.html

So I created the getComponent function like this

var getComponent
getComponent = function(key){
    var temp = dojo.query('[id$=:'+key+']')[0].value
    console.log(temp)
    return this
}

And when I run that you can see we get the value from the field logged and then “window” returned which is the namespace for the functions

fail4
Within the getComponent function I then added the getSubmittedValue()

fail5

Without the need for the console.log – we now get “Marky” returned

How does that work then? You’re right my head hurts……

Yeah me too !

  1. We saw the getComponent function on its own created the temp value and returned itself (making it chainable)
  2. The getSubmittedValue function was then called within the getSubmitted function
  3. getSubmittedValue does not have a parameter passed to it through the originating call
    getComponent(“Password”).getSubmittedValue()
  4. But because it is a closure it does have access to the temp variable which was created when the original getComponent function was called
  5. uuurgh *shakes head*
  6. So anyway it works and woooooo – I got what I wanted !!!
  7. WHY do closures work like this? I haven’t figure that out yet. I think it is cos in this case the getSubmitted function is still in memory even though it has been “completed” it still exists and can therefore still be “used” – but that is just a  guess on my part.

This then allows be to create a generic checkPasswords function which should run with the same “JavaScript” for client side or server side – man I was dancing around the room after spending the entire week trying to figure this out 🙂

var getComponent
getComponent = function(key){
    var temp = dojo.query('[id$=:'+key+']')[0].value
    getSubmittedValue = function(){
        return temp
    }
    return this
}

function checkPasswords(){
	if (getComponent("Password").getSubmittedValue() != getComponent("ConfirmPassword").getSubmittedValue()){
      return false;
    } else {
      return true;
    }
}

checkPasswords()

Implementation
Then I tried to implement it in my XPage – and got the face palm moment – ServerSide JavaScript Libraries and Client Side JavaScript libraries are discrete and nether the two shall cross…..

You cannot include an SSJS library on your “web page” and you cannot include a CSJS library in your Server Side code

SON OF A BISCUIT EASTER !

Conclusion

So there’s my fail – but even after elation and then facepalm I am not down about this at all.

I am actually very happy about how much I heave learned about JavaScript this week – I have always considered myself “ok” at JavaScript but never advanced enough to start to write it as a “JavaScript developer”. I think that path has started and I am going to be writing about it I am sure.

If anyone has any suggestions or insight on how I can possibly move this forward please let me know. I would love to be able to create a single method for doing SSJS and CSJS validation without the need for duplicative coding.

🙂