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.

11 comments:

Unknown said...

Hi David

Wow its excellent code hats of david.

Happy coding

Dynamic Methods said...

Thanks Prabhu. I wish I could take the credit, Michael Hohne from Stunware is really the brains behind this code. But you are correct, it is really sweet.

Thanks again,

David Fronk
Dynamic Methods Inc.

Anonymous said...

Hi David,

I try to use this code on the Microsoft Outlook CRM Client. I call the local webservice http://localhost:2525. I receive the folowing error. What do I wrong?

Server was unable to process request
0x80040216
An unexpected error occurred

Dynamic Methods said...

Whatever code you write has to be written with the assumption that the client is online. There is no support for offline code in MSCRM 3.0. The call that is being made in this bit of code needs to go out to the server to get the webservice information. The Outlook client does not pull that information down so there is no way to call the webservice directly out of the box.

This all changes in MSCRM 4.0 however. Callouts (or plug-ins as they are now called) will be pulled down to the local client and be utilized while the client is offline.

David Fronk
Dynamic Methods Inc.

Anonymous said...

Hi David,

How can I retrieve the username on the Microsoft Outlook CRM Client when I'm offline.

I created a custom aspx page and I want to display the username on it.

Dynamic Methods said...

In MSCRM 3.0 there is no supported way to code for the offline client. All code you write in MSCRM 3.0 is stored at the server and does not get pulled down to the Outlook client when it goes offline. So, I have not tried writing anything for the offline client.

In MSCRM 4.0 however, this all changes. You will be able to write offline code and the code will go with the end-user. I have not written any code for this myself but I'm sure there will be code in the 4.0 SDK for something similar to this.

David Fronk
Dynamic Methods Inc.

Anonymous said...

Hello David

Absolute beauty.

Jaber

Anonymous said...

David,

How could this be done in CRM 4.0? Your help is appreciated!!

Thanks,

Dynamic Methods said...

Jeremiah,

Jim Wang actually has a great post on this. Check it out here:

http://jianwang.blogspot.com/2008/01/crm-40-get-userid-businessunitid.html

He's got the XML posted and everything. That should get you what you need.

David Fronk
Dynamic Methods Inc.

Simon Spencer said...

Hi David

Great post. Just wondering if you could tell me how you changed the output of the name so that it went into a field instead of an alert window? I am new to javascript and am struggling with this bit.
I am wanting to have it so that when a box is checked, the logged in users name is put into a text box.

Thanks
Simon

Dynamic Methods said...

Simon,

You will want to try:

crmForm.all.new_fieldname.DataValue = userid;

That will work for a textbox. If you want to push to a Lookup field then that's more involved. But there are examples in the SDK.

Hopefully that helps,

David Fronk
Dynamic Methods Inc.

Post a Comment