Lately, we’ve been doing some extensive use of embedded grids in order to streamline the CRM 4.0 interface. One of the things I’ve found myself wanting to do is be able to detect when a record in the grid is clicked and to get the ID of that record. For this article, I’m going to assume you are already familiar with embedded grids and will skip setting one up.
the technique I’m about to demonstrate is very simple and straightforward: we’re going to attach a custom function to one of the embedded grid’s event handlers. Seems easy enough, so let’s get to it…
The Grid Object
The CRM Grid has plenty of properties, methods and events that make it work. Ideally, we want to be able to hook into an OnClick event, but we’re out of luck since the grid does not support such an event. One event that is implemented is the onselectionchange event. That’ll work just fine for our needs. (Note: You can get all sorts of insight into the grid object by taking a look at the various source files in the <crm web root>/_static/_grid/ directory).
Set Up the Custom Function
The first thing I want to do is create the custom function that we want to run when a record is clicked. For this example, I want to simply display the Id of the selected record(s):
var bFired = false;
GridClick = function() {
// check to see if this event has been fired already
if(bFired == false) {
// get array of selected records
var frameDoc = document.getElementById("IFRAME_myiframe").contentWindow.document;
var a = frameDoc.all['crmGrid'].InnerGrid.SelectedRecords;
var selectedItems = new Array(a.length);
for (var i=0; i < a.length; i++)
{
selectedItems[i] = a[i][0];
}
alert(selectedItems);
bFired = true;
}
else {
// toggle our fired flag back
bFired = false;
}
}
The first thing you’ll notice is that I use a boolean variable name bFired. The reason I use this is to serve as a flag to determine if the event has been fired or not. I use this flag because the GridClick function is going to run twice each time you select a record (remember, we’re not using ‘onclick’, but ‘onselectionchange’). The rest of the code is standard “get the record id from the grid” javascript that you should have seen before – the only difference is we’re accessing a grid that’s inside an IFRAME.
Attach Our Function to the Grid Event
Next, we need to create a function that will tell the grid to run our GridClick function whenever the onselectionchange event fires:
AttachGridEvent = function() {
if(crmForm.all.IFRAME_framename.readyState == "complete") {
var frameDoc = document.getElementById("IFRAME_myiframe").contentWindow.document;
frameDoc.all['crmGrid'].InnerGrid.attachEvent("onselectionchange", GridClick);
}
}
When the above function runs, we check the readyState of the IFRAME (more on this in a bit…). If the IFRAME has been fully loaded and initialized, then we use the attachEvent method to add our GridClick function to onselectionchange event.
Run The Attach Function
One of the first things you run into when trying to work with DOM objects in an IFRAME’s document is that you have to wait until the document has been loaded in order to work with its objects. In the CRM world, an entity form’s onLoad javascript runs without regard for IFRAMEs on the form. So, our problem is we need to delay attaching our GridClick function until the IFRAME has finished loading the grid (if we don’t set up some kind of delay, then we’ll run into null reference errors because the ‘crmGrid’ object does not exist yet).
The easiest way to determine if an IFRAME’s document has finished loading is to check its readyState property. The best way to do this is to have our AttachGridEvent function run every time the IFRAME’s onreadystatechange event is fired:
crmForm.all.IFRAME_myiframe.onreadystatechange = AttachGridEvent;
So, every time the IFRAME’s readyState changes, our function runs. But our function only attaches our custom GridClick function to the grid when the IFRAME’s readyState reaches “complete” status.
Wrap-Up
So, there you have it. Not very complicated, eh? The trick is just knowing which events and method you have access to.
Cheers!
Comments