Comment unsuccessful. Please correct the errors below.

CRM and jQuery, Part 1

My biggest grievance about client-side development in CRM is that it mandates this vicious  "write some script-paste to form-publish-receive a bomb-review-sprinkle alerts-tweak the code-publish-receive an error-write some script-..." cycle. Verbose, lengthy, difficult to develop, difficult to debug. I do not like developing in Javascript.

Correction.

I did not like developing in Javascript until I discovered jQuery. There is certainly a number of Javascript libraries available with Prototype and jQuery leading the pack. Choosing between the two is not unlike C# vs. VB or Peach vs. Grapefruit. I see the main distinctive feature of either library not so much as a neat and concise code but as the ability to express Programmer Intent extremely well (incidentally, this post uses Ruby as an example; combined with the fact that Ruby on Rails is a driving force behind Prototype, it all starts to make sense). And while Prototype does a fantastic job in encouraging OOP and has a spectacular Script.aculo.us effects library, jQuery won me over with its size, documentation, elegant syntax and method chaining.

What can it do? Well, how about planets revolving around the Sun. Convinced? Read good introduction to jQuery for Javascript programmers and let's move on. [more]

Script injection

jQuery is small, very small but pasting source into every CRM form that needs it is certainly not an option so we need to inject reference to the script into a CRM form. The ways to do it are described here, here and here. I have made only minor modifications to the original methods to ensure that script is loaded reliably.

The jury is still out whether script injection is a supported customisation or not. I guess, some will see it as a Javascript equivalent of HttpModule and therefore explicitly unsupported. On a supported side let's not to forget the fact that, unlike HttpModules, all script code from multiple files can be piled up together and copied into onLoad event without any external references.

After downloading and placing jQuery script into <CRM site>/ISV/scripts/ folder on CRM server, add the code below to onLoad form event. Note that the original source library is great for testing, learning and development, in production you'd want to settle for minified and compressed or, at very least, packed version.


var script = document.createElement('script');
script.language = 'javascript';
script.src = '/ISV/scripts/jquery-1.2.3.js';
script.onreadystatechange = function()
{
   if (event.srcElement.readyState == "complete" ||

      event.srcElement.readyState == "loaded")
         jQueryIsReady();
};
document.getElementsByTagName('head')[0].appendChild(script);

function jQueryIsReady()
{

// jQuery is loaded and initialised
// custom code should be inserted here

}

Note that script injection requires the script file to be placed in ISV/scripts folder which by itself could be a challenge for offline clients. I have some ideas how to solve this problem but they are still incubating so for now I am just going to ignore offline mode. We are all set to walk through some samples.

jQuery samples

I am not going to invent tasks to be accomplished with the script. All challenges are real requests that came from developers and users. To make code samples shorter and reading easier, I'm not going to repeat injection code; instead I'll be writing only the code that lives inside jQueryIsReady function.

Highlight all business required elements

Highlight method certainly depends on developer's imagination and taste. Since I set a bar very low in a taste department, my choice of highlighting is to draw a red border around the element.


$("*[RequiredLevel=2]").css("border","1px solid red");

That was certainly easy. This code in jQuery notation reads something like this: "select all elements that have attribute RequiredLevel set to 2 and then for each element add css property to draw a border around it." Note how we use CRM RequiredLevel documented attribute to find out all required fields.

Change label background for all business required elements

To demonstrate chaining we'll do it at the same time as drawing the ugly red border above.


$("*[RequiredLevel=2]").css("border","1px solid red").each(
   function() {
      $("label[for=" + this.id + "]")
         .css("background-color", "yellow");
   });

This one is a bit trickier. What we're doing here is, after drawing a border for every business required element we find <label> HTML tag that has for attribute set to the element id and then we set label's background to yellow. I'm sure that the same task can be accomplished more elegantly but I'm still in the process of learning and digging jQuery myself.

Hiding an entire row of a CRM form

This sample comes from Michael Höhne and the original code looks like this:


//the field you want to hide
var field = crmForm.all.name;
//search the enclosing table row
while ((field.parentNode != null) && (field.tagName.toLowerCase() != "tr")) {
    field = field.parentNode;
}
//if we found a row, disable it
if (field.tagName.toLowerCase() == "tr") {
    field.style.display = "none";
}

Let's see how we can do the same in jQuery.


// name is the id of the field you want to hide
// as in crmForm.all.name
$("#name").parents("tr:first").hide();

What we're doing here is for the element with id name we find the very first <TR> parent and hide it. Mission accomplished. While we are at it, let's fix a small but annoying problem that hiding a table row still leaves child elements behind which can be easily seen by tabbing to the presumably "hidden" input fields. To solve this problem we are going to hide all children but not until we teased user for 2 seconds with a slowly disappearing row.


$("#name").parents("tr:first").hide(2000,
   function() {
      $(this).find("*").hide();
   });

Where to from here

The samples above are just that, samples, to demonstrate elegance and power of jQuery as applied to common client-side tasks. While coding shortcuts are cute, they are certainly not the ultimate goal which is to turn client-side script development into a sensible and manageable process unlike the mess that it is now.

Stay tuned for the next instalment.

Posted by: George Doubinski
Last revised: 05 Dec, 2012 05:25 PM

Comments

casper
casper
26 May, 2014 08:45 AM

I am really new to CRM services and here I got a very good piece of information here. The data shared over here has explained well the various forms and codes to be used up filing making use of the CRM services. Good post visit

Your Comments

Comment unsuccessful. Please correct the errors below.
Used for your gravatar. Not required. Will not be public.
Posting code? Indent it by four spaces to make it look nice. Learn more about Markdown.

Preview