Tuesday, July 31, 2007

Pulling the Logged in User via JavaScript

I have been trying to find a good way to make "signatures" work in CRM. Some way for a manager to fill in a field for approval and then automatically put in the name of the manager into a field to prove that it was done by that person. I had found a way through some disabling the field and only opening it for users with a specific security role, but that still relied on the honesty of the managers. Some clients don't always trust their managers 100% unfortunately.

I have since found a post that gave me exactly what I was looking for. JavaScript that reads in the logged in user and puts the name of the logged in user into a text field automatically. So, whenever a specific field gets updated the user who changed it will get his/her name printed out so that all can see that the field was changed/approved by that user. Couple that with some additional JavaScript field level security and you've got a pretty good signature system. (Note that the field level security is NOT supported by Microsoft).

The cool part about finding the logged on user though is that it is supported JavaScript and uses the RetrieveMultiple CRM call to pull back the information desired. I take absolutely no credit for this code. I didn't have to really even change anything other than the output of the name so that it went into a field instead of an alert window. All credit goes to Michael Höhne, Microsoft Dynamics CRM MVP at Stunware. Here is the link to his post:

http://www.stunnware.com/crm2/topic.aspx?id=JSWebService


The code from his post is this:


var xml = "" + "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +


" <soap:Body>" +

" <query xmlns:q1=\"http://schemas.microsoft.com/crm/2006/Query\" xsi:type=\"q1:QueryExpression\" xmlns=\"http://schemas.microsoft.com/crm/2006/WebServices\"&gt;" +

" <q1:EntityName>systemuser</q1:EntityName>" +

" <q1:ColumnSet xsi:type=\"q1:ColumnSet\">" +

" <q1:Attributes>" +

" <q1:Attribute>systemuserid</q1:Attribute>" +

" <q1:Attribute>fullname</q1:Attribute>" +

" </q1:Attributes>" +

" </q1:ColumnSet>" +

" <q1:Distinct>false</q1:Distinct>" +

" <q1:Criteria>" +

" <q1:FilterOperator>And</q1:FilterOperator>" +

" <q1:Conditions>" +

" <q1:Condition>" +

" <q1:AttributeName>systemuserid</q1:AttributeName>" +

" <q1:Operator>EqualUserId</q1:Operator>" +

" </q1:Condition>" +

" </q1:Conditions>" +

" </q1:Criteria>" +

" </query>" +

" </soap:Body>" +

"</soap:Envelope>" + "";


var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2006/CrmService.asmx", false);

xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2006/WebServices/RetrieveMultiple");

xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");

xmlHttpRequest.setRequestHeader("Content-Length", xml.length); xmlHttpRequest.send(xml);
var doc = xmlHttpRequest.responseXML; var user = doc.selectSingleNode("//BusinessEntity");

var userId = user.selectSingleNode("systemuserid").text;

alert(userId);

var userName = user.selectSingleNode("fullname").text;

alert(userName);


You can quite literally copy and paste the code into any JavaScript function inside of CRM and this will work. There is nothing that ties it to one CRM implementation or another.


My hat goes off the Michael and the rest of the Stunware team for their great work and sharing this spectactular code. Thanks guys.


Happy coding,


David Fronk

Dynamic Methods Inc.

Monday, July 30, 2007

EmailTo via JScript

One of the shortcomings that I've found with some of the out-of-the-box features in MSCRM is the Email field. It's underlined, so it is supposed to be a link but when you click on it, instead of opening an email page like a URL does for a web page, it does nothing.

I finally decided to spend some time on figuring out some way around the "copy/paste" method that I have told so many users previously to do to work around this issue. And while I did not solve the onClick problem I did at least find a way to get an email page to come up with the email from the email field filled in. A huge win over the "copy/paste" method.

I found a way through JScript in the ISV.config to get everything I needed. I knew that I could use the "mailto:" call from the HREF HTML tags but I wasn't sure on how to reference it. So, after a little research I found a pretty cool way to get around this problem. So, I cannot by any means take full credit for figuring this out, I can only claim credit for finding the pieces necessary and putting them together to get what I needed done (as I'm sure most of us do through the wonderful knowledge share called the Internet). So, thanks to anyone any everyone who has posted about this, I probably saw your posts and they have contributed to this:


<button title="Email" tooltip="Send Email" icon="/_imgs/ico/16_send.gif" javascript="window.navigate('mailto:'+crmForm.all.new_email.DataValue)" passparams="0" winparams="" winmode="0">

The key is the JavaScript attribute and the window.navigate call. Once the window.navigate reference was made it was also very great to see I could call any field value on the form to my JavaScript stored in the ISV.config. That ability alone opens up a lot of doors to new possibilities. It makes sense that all of the supported hooks that we as developers are given are JavaScript that we could use the exact same calls from a different source, it just wasn't something I had tried until now. Once I had those points down it was a piece of cake.

So, now I have a button along the toolbar that will open up your default email client to whatever email address you specify. I'm sure there are some much more complex scripts that can come from this (like a primary email selection box that then pics the corresponding email address to send the email to).

Happy coding,

David Fronk
Dynamic Methods Inc.