Put IT in High Gear – Engage!

Javascipt inside of CRM has historically been essential, but a bit of a messy affair. Things have improved in CRM 2011 with the advent of form libraries, but I think most CRM developers will admit they’ve worked on CRM projects where they wrote some scary spaghetti JavaScript. Sure, it got the job done, but it wasn’t pretty, and there was always the fear that the code was far more fragile than your well architected C# plugins and services; with there always being the hassle with CRM’s test-change-publish javascript debugging module, making javascript often something CRM developers actively look for ways to avoid.

The good news, is that with a little bit of object oriented magic, it’s possible to take a lot of the pain out of using Javascript and CRM, especially now in CRM 2011. Over several of our next few month’s posts, we’ll be walking you through using object oriented javascript to achieve a fairly common CRM goal: showing different forms for an entity based on the value of a certain field.  We’ll start out this post by looking at the basics of object oriented javascript.

Object Oriented What?

That javascript can be written in an object oriented manner at all is somewhat of a little known fact in the web world. For the most part, developers really only use javascript in a procedural fashion, for simple little website flourishes. That’s starting to change with the advent of HTML5 and the growth of powerful web apps, but for many JavaScript’s object oriented capabilities are a well kept secret.

Part of the problem is that object oriented programming (OOP) in javascript looks very different than languages like C# and Java. There are no built in class declarations, no ready made inheritance. In fact, at a fundamental level JavaScript is ridiculously simple. It has less than a dozen built in types of objects,  no built in name spacing, and no type declaration. But this apparently simplicity hides some incredible emergent capabilities.

Objects, Objects Everywhere

Let’s take a look at the basics of OOP in javascript. As we noted earlier, Javascript doesn’t have a lot of the pieces of OOP that we usually expect, like class declarations. So how do we do the javascript equivalent? Like this

Foo = function(){

//Insert constructor logic here

}

Now if we want a new instance of the Foo class we write

myFoo = new Foo();

Alright, but then what about properties, or methods, or passing parameters in the constructor?  Easy, just declare them in your constructor, like so.

Ninja = function(weapon){

this.weapon = weapon;

this.sneak = function(){

alert(“The ninja is sneaking!”)

};

this.attack=function(){

alert(“The ninja attacks you with his ” + this.weapon);

};

}

Now we’ve got a Ninja class that can sneak, and attack with a weapon. It behaves just like we would expect a good object to behave

myNinja = new Ninja(“katana”);

myNinja.sneak();

//outputs “The ninja is sneaking”

myNinja.attack();

//outputs “The ninja attacks you with his katanta”

Javascript even supports private properties, with accessors. Let’s imagine we want to make our ninja more PC and allow the user to declare a gender for the ninja, but not change the gender after the Ninja’s been created.

Ninja = function(weapon, gender){

this.weapon = weapon;

var gender = gender;

this.Gender = function() { return gender};

this.sneak = function(){

alert(“The ninja is sneaking!”)

};

this.attack=function(){

var pronoun;

If (gender == “male”)

{

pronoun = “his”;

}

else if( gender ==”female”)

{

prounoun = “her”;

}

alert(“The ninja attacks you with ” + pronoun + ” ” + this.weapon);

};

}

Simply by leaving off the “this” when we declare  the gender variable, we ensure it’s only available in the Ninja class. If  a user developer wants to retrieve the Ninja’s gender, they just call Gender().

guyNinja = new Ninja(“katana”,”male”);

alert(guyNinja.Gender());

//outputs “male”

guyNinja.attack();

//outputs “The ninja attacks you with his katana”

girlNinja = new Ninja(“dagger”, “female”);

girlNinja.attack();

//outputs “The ninja attacks you with her dagger”

More Inheritance than you can shake an object at

So we have classes, but what about the next key to OOP, inheritance? Here’s where things get a little more complicated. There’s no built in syntax for inheritance in Javascript, instead you roll your own. The basic idea is to create an instance of the base object, copy all of it’s properties and methods to your inherited object, and then override the specific methods as needed. Of course, there are about 15 different ways you can do this, depending on what you need, or what javascript frameworks you’re working in.

For this series, I’ll show you a simple inheritance strategy based on jquery. It’s certainly not the only method, but it’s one that met our set of specific needs. When we came up with this method for inheritance, we were looking for something that didn’t require us to use anything beyond jquery (because we were already using that for other purposes) and could express the details of the inheritance on a single line, so that you could still see class relationships even when we were using code folding in our editor.

Bar = function (){$.extend(true, this, new Foo());

//rest of our constructor logic here

}

Although there are a lot of parenthesis, what’s going on here is pretty simple. We’re declaring a new class named Bar. Whenever someone creates a instance of bar by calling new Bar() the first thing we do is call the $.extend() method. $.extend() is a jquery method that simply copies all of the properties and methods of one object to another. In this case we’re copying all of the properties and methods of a new instance of the Foo class, to “this” the object being instantiated by our Bar constructor. The true parameter tells the extend method to do a recursive copy, to copy any properties and methods of child objects that are themselves a property of our Foo object.

So going back to our ninja, example, let’s create a class named Samurai that inherits from Ninja. Samurai, attack just like Ninja do, but they don’t sneak. We need to override the sneak method to make sure everyone understands that.

Samurai = function(weapon, gender){$.extend(true, this, new Ninja(weapon, gender);

this.sneak = function(){

alert(“Samurai don’t sneak! They’re noble warriors.”);

}

}

If we create a new Samurai, and call it’s methods, we get this.

mySamurai = new Samurai(“female”, “katana”);

mySamurai.sneak();

//outputs “Samurai don’t sneak! They’re noble warriors”

mySamurai.attack();

//outputs “The ninja attacks you with her katana”

Order out of Object Chaos

So we’ve hit on most of the big pieces of object oriented programming, but what about some of the nice to haves, like namespacing? Well again, Javascript doesn’t have anything built in, but you can create your own namespace system out of objects. In this series will be using the same namespacing strategy used by Yahoo in their popular YUI javascript framework. To do that, first we declare a namespace global variable.

if (typeof MyNamespace== “undefined”) {

var MyNamespace= {};

}

Here, we’re checking to make sure no one else is using the variable name, MyNamespace, and then assigning an empty object to it. Next, we’ll create the function that handles creating the namespace

MyNamespace.namespace = function() {

var a = arguments, o = null, i, j, d;

for (i = 0; i < a.length; i = i + 1) {

d = a[i].split(“.”);

o = window;

for (j = 0; j < d.length; j = j + 1) {

o[d[j]] = o[d[j]] || {};

o = o[d[j]];

}

}

return o;

};

There’s a lot going on in those lines of code, but basically, this function expects a lists of strings. For each string it gets, it splits the string into an array based on the “.” character. For each item in that array, it creates an object tree, or assigns new objects as properties to existing ones. So calling

MyNamespace.namespace(“MyNamespace.Fighters”)  will first check to see if a MyNamespace object already exists. Since it does, it will move onto to the next part of the namespace, “Fighters.” Once it sees that “Fighters” doesn’t exist it will create a new empty object at MyNamespace.Fighters and return that object.

If you want to use a certain namespace, just capture the output of the namespace function.

ns = MyNamespace.namespace(“MyNamespace.Fighters”);

Then if you want to make sure the Ninja class is under the Fighters namespace, just do this

ns.Ninja = function(weapon,gender){

//constructor logic here.

}

Further Reading

This was a pretty fast crash course in OOP in Javascript, so if you want to study up further, check out these links. And check back soon for the next piece in this series, where we start looking at how we tie this into framework for the specific CRM problem mentioned at the start of this post; showing and hiding fields on a CRM form.

Basic overview on some OOP Javascript concepts

http://javascript.crockford.com/javascript.html

More on Name spacing and javascript

http://javascriptweblog.wordpress.com/2010/12/07/namespacing-in-javascript/