Friday, February 06, 2009

Grid Buttons...a better way

I've received some comments on my previous post regarding grid buttons in CRM and using the getSeleted('crmGrid') method via Jscript within the ISV.config file and how it is risky since it is an undocumented method and is very subject to change. One of the other limitations with that method is that all of the GUID's that are retrieved are placed in the URL query string. While that easy to access I quickly found out that there is a character limit on how many characters you can put into that query string. Using the getSelected('crmGrid') method really only allows you access to about 50 records or less. If you select more it will look like your button and code worked, when in fact it never did anything to the select records that push the count beyond 50.

I have seen mentioned of using "window.dialogArguments" to gain access to what is selected on the grid. I looked for documentation, posts, anything and I found minimal information on how to use this within MSCRM. MSCRM 3.0 had zero documentation on this. So, I was reluctant to even try the 4.0 SDK. But surprisingly enough there is a great article in the 4.0 SDK. It's titled "Walkthrough: Capturing the GUID Values of Records Selected in a Grid". It steps you through the set up of a button and webpage and even gives you code for your webpage. However, a lot of the coding I do ends up in the codebehind page (.cs page) which resides on the server. And the code the SDK gives is all Jscript...and getting Jscript to talk to server-side code isn't seemless, you have to make them talk to each other. And the SDK left that part out completely. So, I am posting a way that I have figured out on how to make this work from a webpage and still being able to use codebehind to access strongly the typed development via the webservices of MSCRM. If someone else has any other way that they have accomplished this I'd love to see what you've done, because either everyone knows how to do this and isn't sharing because it's so easy, or few people know about it and those who do are keeping it to themselves, or I'm just not looking in the right places.

The above mentioned walkthrough will get the GUID's via Jscript but not make the GUID's available to the server-side code. Please note that the article mentions that you MUST set up your button tag in the ISV.config file as WinMode 1 or 2. 0 WILL NOT WORK. This is key in the passing of data from one webpage to another, so be aware of that. Once that's set up , in order to pass data from script to server-side code the use of a hidden field can be used. Below is the HTML page (minus the codebehind references) used to get all of the GUID's when a button from the grid is clicked:

<html>
<head>
<title>GUIDs for records seleced in Grid</title>
<script type="text/jscript">
function listselecteditems() {
var placeholder = document.getElementById("test");
var hiddenfield = document.getElementById("HiddenField1");
var sGUIDValues = "";
var selectedValues;
//Make sure window.dialogArguments is available.
if (window.dialogArguments) {
selectedValues = new Array(window.dialogArguments.length - 1);
}
else {
placeholder.innerText = "window.dialogArguments is not available.";
return
}
selectedValues = window.dialogArguments;
if (selectedValues != null) {
for (i = 0; i < selectedValues.length; i++) {
sGUIDValues += selectedValues[i] + "\n";
}
//placeholder.innerText = sGUIDValues;
var hidden = sGUIDValues;
form1.HiddentField1.value = hidden;
form1.submit();
}
else {
placeholder.innerText = "No records were selected.";
}
}
</script>
</head>
<body onload="listselecteditems()">
<form id="form1" runat="server">
<div runat="server" id="test">
<input id="HiddentField1" type="hidden" runat="server" />
</div>
</form>
</body>
</html>


Take note of the "hidden input". That is a textbox where I put all of the GUID's. This tag MUST have the runat="server" option or else your codebehind will never see the control. But that control is the key to getting access to the GIUD's in your server-side (codebehind) code. One other comment, the form1.submit(); must also be present or else what is on the page never goes to the server. And since your server-side code is…on the server, the values will never be read. So, submit the values to the server and you'll be ready to access your GUID's from your codebehind.

Once you have that you can do whatever you need to with the GUID's. Here's an example page load that I did:

protected void Page_Load(object sender, EventArgs e)
{
CrmService crmService = new CrmService();
crmService.Credentials = System.Net.CredentialCache.DefaultCredentials;
string rawString = HiddentField1.Value.ToString();
rawString = rawString.TrimEnd();
string[] ids = rawString.Split(new char[] { '\n' });
int r = 0;
while (r < ids.Length) {
ids[r] = ids[r].Replace("{", "").Replace("}", "");
try {
if (ids[r] != null && ids[r] != "") {
//Use a method to do whatever you need to off of the GUID's found
//Update a given field, create a related object, etc.
updateSomething(crmService, ids[r]);
}
}
catch { //Error code }
r++;
}
}


Once you have the GUID's in your codebehind, the rest is up to you and your imagination, or the needs of your system. That should get you going with what you need.

Happy coding!

David Fronk
Dynamic Methods Inc.

5 comments:

Jeremy Hofmann said...

Actually I had this same need today and was also wondering if it was just too easy or if it was some kind of secret :)

Thanks for the post! Hopefully it will make it into the SDK someday.

Rody van Sambeek said...

Is there no cleaner way of performing this in Dynamics CRM? The javascript repost of the form seems like an unwanted "hack" to me.

Dynamic Methods said...

Rody,

I am unaware of any cleaner way to do this. Searching the internet and the SDK lead me to this solution. I know it's not elegant but it works. If any one else has done this in a cleaner way I'd like to see it myself, but so far I haven't. Sorry.

David Fronk
Dynamic Methods Inc.

Söderåsen said...

Hi, I am a begginer CRM programmer and I am trying to follow your solution. I had this problem with test.htm page from this "Walkthrough: Capturing the GUID Values of Records Selected in a Grid". If the page is under CRM/ISV/test.htm it works but not if I have the jscript at "http//localhost/test.htm". My question is how I can do to connect the test.htm with mypage.aspx ?? Thanks a lot !!

Dynamic Methods said...

Soderasen,

Your test.htm page needs to BE your mypage.aspx. Whatever is in the body of the test.htm page needs to be setup in the mypage.aspx. Don't try and have one page get all of the GUID's and then pass them to another page. Just have one page to do it all.

David Fronk
Dynamic Methods Inc.

Post a Comment