Saturday, September 01, 2007

Javascript – define functions and programmatically attach events

Since we're on the subject of javascript I might as well add some more stuff. First of all, how to define you own functions, then how to programmatically bind a function to an event, for instance, onchange of a field.

This mainly concerns Microsoft CRM but the technique can also be used in SharePoint, although javascripts aren't as common.

First off, how to define a function.

There are actually several different ways, for instance the normal:

function myfunc1(param1, param2)

{

alert("myfunc1");

}


 

And the one with a weird sort of syntax:

var myfunc2 = function(param1, param2)

{

alert("myfunc2");

}


 

In CRM 3, these can actually be defined within the onLoad, hence creating some ways of code reuse. These functions will be available for all event in the page since they have been declared in the onload.

This leads me to another point, that a function has to be defined before it can be used. Hence, in the example above, myfunc2 can call myfunc1, but not the other way around. If you try, you will get strange error messages saying stuff like "null is not 'null'".

Secondly, you can bind events to functions using code. There are several ways of doing this as well (what did you think!?) and they mainly differ based on which browser you are using. If you want to read some more on the subject, if you want some more info on event binding in javascript, please have a look at this very instructive page: http://developer.apple.com/internet/webcontent/eventmodels.html

First the simple method by just setting the onchange attribute.

crmForm.all.ext_myfield.onchange = myfunc2;


 

or

document.getElementById("objectid").onchange = myfunc2;


 

This has the advantage of a quite simple syntax and, if you want it, the override of previous events.

The second way of doing this is using the attachEvent method. As far as I've read, there are some differences with syntax between browsers, but since neither MS CRM nor SharePoint work in any acceptable way in anything but IE, this is not a big issue. Here is some example syntax:

crmForm.all.ext_myfield.attachEvent("onchange", myfunc2);

or

document.getElementById("objectid").attachEvent("onchange", myfunc2);


 

The main advantage of this method is that you can attach several functions to one event, hence, not overriding other handling.

Bellow is an example html-file which demonstrates this:

<html
xmlns="http://www.w3.org/1999/xhtml">

<head>

<script
type="text/javascript">

var myfunc1 = function()

{

alert("myfunc1");

}

var myfunc2 = function()

{

alert("myfunc2");

}

var loading = function()

{

alert("running");

document.getElementById("btTest").attachEvent("onclick", myfunc1);

document.getElementById("btTest").attachEvent("onclick", myfunc2);

}

</script>

</head>

<body
onload="loading();">


<button
id="btTest">Click me</button>

</body>

</html>

If you copy this to a file called test.htm and test it, you will see that when clicking the button, myfunc2 will be executed first and then myfunc1.

So, all put together, this can be used to a great extent in MS CRM 3, where you can now put all code in one place, the onLoad script, define some functions and then bind the onchange event of all the attributes you like in the same code. Remember to define the functions before you attach the events.

I havn't seen CRM 4 / Titan yet, and I don't know what features it will have in this aspect, but if it includes the feature to be able to add a global javascript file that will be included on all pages, this would be very very useful when using techniques like this.

And remember, javascript is an ugly beast, but it is very useful! J

Gustaf Westerlund

Humandata AB

2 comments:

  1. Thank you so much!

    I spent a good hour or so trying to find out how to bind an "onchange" event to a sharepoint field. Your code coupled with the _spBodyOnLoadFunctionNames.push("FunctionNameGoesHere"); function (which you place inside the PlaceHolderMain area worked wonders!

    Using that _sp function allowed me to load your "loader" function and bind several events to various fields.

    Thank you again, really appreciate the article.

    Cliff

    ReplyDelete
  2. Hi!
    Thanx!

    Yes, it is a very usefull technique. I use it a lot myselft but nowdays only in MS CRM.

    ReplyDelete