tags:

views:

42

answers:

1

Hi all, I have a task to change envelope icons on the main Activities view page (Work Place, My Work -> Activities) for every row in the grid, depending on the custom status of the row in crm 4.0. I need to do it using JavaScript. Does anybody know if there is a way to do that and where should the JavaScript code be placed? I am assuming that I need to intercept grid onLoad event, go through the grid, check the condition and flip the url of the icon. But I cannot figure out how to hook into that event...

Thanks very much!

I got several very useful advices and here is what I got so far.
1. I added SiteMap to load a custom page, instead of default one (/workplace/home_activities.aspx)
2. Here is the code of the custom page, placing onreadystatechange in the html was the only way I could get this function to run. Do not know why.

 
HTML>
HEAD>
TITLE>
script language="javascript" type="text/javascript">
function Run()
{
 var objIframe = getIframe();

   if(objIframe.readyState == "complete")
   {
    var docFrame = objIframe.contentWindow.document;
    var grid = docFrame.getElementById("crmGrid");

    var allRecords = grid.InnerGrid.AllRecords;

    for(var i=0; i 

function getIframe()
{
   return document.getElementById("wraperActivitiesFrame");
}
/script> /HEAD> body > iframe id="wraperActivitiesFrame" src="/workplace/home_activities.aspx" WIDTH="100%" HEIGHT="100%" onreadystatechange="Run()"> /HTML>

The issue I am having now is that the function does not run again when I try to page the grid. I have 2 pages of Activities; when the page loads for the first time - I have my alert boxes, but when I click on "page 2" arrow - nothing happens. Why??? What I am doing wrong?

A: 

You kinda can hook into that event. You create a "wrapper" HTML page that you load in CRM instead of the default activities grid via Sitemap. This wrapper contains a full-size IFrame in which you load the actual grid, and in the IFrame's onreadystatechange handler (for readyState == 4), you traverse the grid's DOM (jQuery might make this a little easier, but I haven't used jQuery much myself) and do whatever changes you need to do (that means the JavaScript goes within the wrapper HTML page). If you call this via setInterval and put a try-catch around it, this will even be safe against grid refreshes and browsing through the pages.

GCATNM
Thank you for your answer! Have you done something like this or it is a concept thing? I just looked at the actual .aspx page, which renders the Activities grid. There are a lot going on in there. In order to created that "wrapper" page I assume I have to copy everything that original page does and add some of custom code?
Tanya
We have done things like this on various occasions (that's how I am sure it can be done in a refresh/paging safe manner).You don't need to copy anything. The wrapper page is really just a HTML page with nothing but an IFrame and some JavaScript; this is only an "invisible" layer to hold the JavaScript logic, because you can't add JavaScript to the CRM main window (let alone the Outlook client) or the grid.In the IFrame, you load the original .aspx, just like CRM would, and when it's rendered, go into its DOM and make your changes.
GCATNM
You don't need to look at the "raw" .aspx file in the CRM installation folder, because the grid as rendered in the CRM window probably isn't even in there. You just need to look at the grid's DOM structure in CRM with something like the IE Developer Tools to know how to traverse the grid and what elements to manipulate.
GCATNM
Thank you so much for helping me! Sorry to bother you, but can you look at the code I have and tell me if I am doing right or wrong?<HTML><HEAD><TITLE></TITLE><script language="javascript" type="text/script">function Run(){ document.frames("wraperActivitiesFrame").document.onreadystatechange = wraperActivitiesFrame_OnReadyStateChange;}function wraperActivitiesFrame_OnReadyStateChange(){ alert("Yahoo!");}</script></HEAD><body onload="Run();"> <frameset> <FRAME src="/workplace/home_activities.aspx" id="wraperActivitiesFrame" /> </frameset></body></HTML>
Tanya
I have not done any traversing in the code. I am just trying to hook into the event and see if I the function runs or not. I changed the SiteMap in the customazation area so that the page above is being called instead of default home_activities.aspx. I do not seem to have much success with it and I am not sure what I am doing wrong. Thank you!!
Tanya
Two things immediately strike my eye:- Don't use a frameset, but an IFrame. This would be<iframe id="wraperActivitiesFrame" src="/workplace/home_activities.aspx"></iframe>(the separate closing tag is important; IE does not always interpret XHTML correctly).- Write the onreadystatechange handler as a closure and check for the actual readyState value: document.frames["wraperActivitiesFrame"].document.onreadystatechange = function(){ if (4 == this.readyState) alert("Hotbot!"); };Note the square brackets to access the actual frame; document.frames is an object/quasi array, not a function.
GCATNM
readyState 4 means "complete" (actually, checking for the string "complete" instead of the number 4 will work as well); there are a few other values like "loading" that precede it, but those are completely irrelevant in this case. Oh, and it may be that IE decides to be a b*tch and make things more complicated. We have never really determined a pattern, but there are (1) cases whre document.frames[frameid] is not enough, but you actually need to reference the IFrame twice, like document.getElementById("wraperActivitiesFrame").document.frames["wraperActivitiesFrame")
GCATNM
and (2) occasions where you get readyState 4 twice and the first time is useless (meaning that the loading is not actually complete yet), so you cannot actually use the page yet but need to remember that it occurred so you can react on the second occurrence. But thinking about it, in this simple case you'd probably run into neither of those issues.
GCATNM
Iframe worked! You rock! And I can traverse through the grid. Now the only issue I have is when I click "Next page" hte function does not run. How did you deal with it? I appreciate your help very much!
Tanya
Put what you have inside the `if(objIframe.readyState == "complete")`clause in another function and call it via `setInterval()`. That is, if your new function is called `modifyGrid()`, in the `if` clause you would put `setInterval(modifyGrid, 2000);` to have the function go through the grid every two seconds. You might have to additionally enclose the code within `modifyGrid()` in a `try-catch` block (with an empty catch) so it will just quit and not throw any errors if you change the page while it's running and thus pull the DOM from beneath its feet.
GCATNM