CRM Javascript
February 06, 2012
XRM 2011 JavaScript: Another 101 Lesson in Microsoft Dynamics CRM 2011
When you’re learning JavaScript, you’ll often come across the need to do something to every field on the form. When you do, it’s important to have efficient code to make such widespread changes so the user doesn’t have to wait for the JavaScript to finish. This lesson consists of several parts, some of which you’ll probably already know but hopefully there are some things in here for everyone.
Setting up our Environment
First thing first, open your CRM 2011 development environment and browse to an account form. Once the account form is open, hit F12 on your keyboard. A window should popup that looks like this:
If instead, you see the window in the bottom of your browser page. Click the little “Unpin” button shown here:
This is IE Developer Tools and if you haven’t used this in the past, then I hope you enjoy not having to save/publish/refresh/test nearly as often. To start, we’re going to see how many fields we have on the form. When inside of the CRM form, we’d use something like:
Xrm.Page.data.entity.attributes.getLength()
But when we’re inside Developer Tools, we actually have a different context. So we need to click on the “Console” tab and execute:
frames[0].Xrm.Page.data.entity.attributes.getLength()
Anything we want to execute on the form, we can do by simply prepending “frames[0].” in Developer Tools to get the proper context. This allows us to write and test code instantaneously, which is a huge timesaver.
Iterating Fields
Now that we are playing in our Developer Tools sandbox, let’s iterate through some fields to see which fields are required. To use multiple lines, click the double up arrow in the bottom right corner.
Here’s some slightly modified code from the SDK that we can just copy and paste into our Console:
var message = "The following fields are required:\n";
frames[0].Xrm.Page.data.entity.attributes.forEach(function (attribute, index) {
if (attribute.getRequiredLevel() == "required") {
message += " \u2219 " + attribute.getName() + "\n";
}
});
alert(message);
Note: I can’t stress enough how awesome the SDK is. Everyone I’ve met who partakes in the SDK creation, maintenance, etc. have been top notch people. If you aren’t using the SDK, you are missing out in tons of awesome tips, features and customizations.
You’ll notice that the above code quickly goes through each field and checks to see if the field is required. We could also check if the field is dirty (meaning the user changed the value), if the field is enabled, or whatever. It’s just a simple way to make mass changes quickly.
About “forEach”
For the experienced developers, you may be thinking did IE get ForEach? No, but the CRM developers were gracious enough to add this into the Xrm variable. For those of you unfamiliar, this was an old Mozilla thing that made life a lot easier when dealing with arrays. Expanding further, the Xrm forEach approach is faster than most arrays people would generate using for loops. You can write some JScript that is faster and I’ll get into that one day, but at this point you are better off using the forEach approach.
I’ve said it several times, but I really like the Xrm object due to its attention to performance. In fact the method here is about a hundred times faster than iterating the crmForm.all object. I’ll back that up with some pretty graphs and such in a later post.
Checking for Changed (Dirty) Fields
var message = "The following fields are dirty:\n";
frames[0].Xrm.Page.data.entity.attributes.forEach(function (attribute, index) {
if (attribute.getIsDirty()) {
message += " \u2219 " + attribute.getName() + "\n";
}
});
alert(message);
Notice how easy it is to change what we are checking for. Whether we are looking for a specific value, dirty fields, required fields, or whatever, doing so inside the forEach function makes it fast and easy.
Back to the Web Resource
To go from the Developer Tools back to the Web Resources, we need to replace all of the “frames[0].” references with blanks. IE Developer Tools is a great way to create and test our code without affecting anyone else and there is a lot more to developer tools than the console. I hope you enjoy!
Posted by Paul Way on February 06, 2012 at 08:25 AM in CRM Best Practices, CRM Development, CRM Javascript, Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM Tricks and Tips, XRM | Permalink | Comments (1) | TrackBack (0)
January 12, 2012
CRM 2011 - iFrames & Saving
After spending time on several of the CRM forums, I noticed a few people having trouble with iFrames and saving data inside of the iFrame. While a forum post is a little difficult to write a full response, I wanted to share some insight on capturing the form save event to then trigger a save event inside of your iFrame.
From a business case, this is a fantastic way to tie multiple systems together. If all you are doing is syncing data, then look first at a plugin or scribe. However, if you are looking for the user to interact with multiple systems simultaneously, then an iFrame is a wonderful way to integrated with an existing system. A good example might be where CRM is only storing the summary information and the iFrame contains the details. The user may update the details which should save both the CRM record and the details of the web site.
Prerequisites
First, let’s assume you have an iFrame inside an entity.
Secondly, we need to uncheck the “Restrict cross-frame scripting” check box on the iFrame properties.
Lastly, it’s a good idea to make sure our iFrame is using HTTPS to prevent mixed mode security warnings.
Talking Directly
If you try to talk directly to the iFrame via something like:
Xrm.Page.ui.controls.get('IFRAME_opp').getObject().contentWindow.document
Unless you are On-Premise, you may encounter the “Access is Denied” warning. This will show itself when dealing with URLs on a different domain (or subdomain). Cross domain scripting is a security feature within the browser. Now an easy fix is to disable the browser settings, but this isn’t a good solution.
Messaging
Instead of talking directly, we need send a messages to our iFrame. To send a message, we’d do something like:
Xrm.Page.ui.controls.get('IFRAME_opp').getObject().contentWindow.postMessage('test', "*")
To receive the message on the iFrame, you need to listen for the message event. Let’s take a look at the JavaScript on our example iFrame page:
1: function receiveMessage(e) {2:3: if (e.origin == 'https://way.crm.dynamics.com'){4:5: if (e.data == 'test'){6: document.getElementById('msgBox').innerHTML = 'testing...<br />' + e.origin + '<br />' + e.data;7: }8:9: if (e.data == 'save'){10: saveForm();11: }12: }13:14: }15:16: saveForm = function() {17: document.getElementById('msgBox').innerHTML = 'saving...';18: }19:20: window.attachEvent("onmessage", receiveMessage);
It is very important to check the origin and the message if you are dealing with publicly facing sites.
If the idea of messaging is new to you, here are some additional resources:
- http://msdn.microsoft.com/en-us/library/cc197015(VS.85).aspx
- http://msdn.microsoft.com/en-us/library/cc511311(v=vs.85).aspx
The OnSave
To initiate the message from the CRM 2011 form, you need to register an OnSave event from within the “Form Properties”.
How about .NET Pages?
If your iFrame is an ASPX page, all of this still applies. The only difference is that you want to have an ASP.Net button on your page to call the server side code. Instead of the saveForm event, simply call the click event of the button.
When dealing with server side saves though, you can either post a message back to say “I’m done” which will then complete the CRM save or you can put a set timeout in the onSave on the CRM side.
Conclusion
Hopefully you have seen how easy it is to integrate with another web site while inside of CRM 2011. If you have had problems with iFrames in the past, I really encourage you to use iFrames for your integration needs as they can really enhance your users experience and can allow for improved data across systems. I hope you enjoy!
Posted by Paul Way on January 12, 2012 at 01:22 PM in CRM Javascript, Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM Online, Microsoft CRM Tricks and Tips, XRM | Permalink | Comments (2) | TrackBack (0)
December 28, 2011
XRM 2011 - JavaScript 101 in Microsoft Dynamics CRM 2011
When it comes to CRM 2011, knowing JavaScript opens up a whole new world for what you are able to do. Whether it’s a functional piece like address verification or a cosmetic change like shading the form, it’s all possible through JavaScript. I’ve been to several CRM events and when it comes to JavaScript, it’s always light on the details. So I’ve decided to put together a small series of learning JavaScript for CRM 2011. If right now JavaScript sounds a little frightening, realize that pretty soon it will be just another tool in your arsenal.
Where oh where do we begin? 
First of all, there is more to JavaScript then just JavaScript. With CRM 4, we used crmForm.all.?. With CRM 2011, we use Xrm.Page.?. Those are JavaScript objects or libraries built to make your life easier. When it comes to JavaScript as a whole though, there is jQuery, Dojo, Sencha, Prototype and countless other libraries out there. We are only going to focus on CRM 2011 and basic JavaScript.
In today’s lesson, we’re going to look at the value of an Option Set and toggle a section based on the value. When the Relationship Type is set to Customer, we’re going to show the “Policy Info” section. When the Relationship Type is set to Prospect, we’re going to hide the “Policy Info” section. The purpose for this is to only show to the user what is important for the contact. In the case of a Prospect, they don’t have a policy with us, so it doesn’t provide any value to our users.
Getting Prepared
To start, we need to three different schema names: the field, the tab and the section. One way to get the schema names is to click the “Customize” tab and select “Form”.
Once the Form Editor opens up, select the field you want to use (in our case we’re using a custom field). Once you’ve clicked the field, click on the “Change Properties” button on the ribbon at the top of the screen.
A new window should pop-up. Click on the Details tab, to see the “Name”. This is the schema name.
To find the schema name for the tab, click just to the right of the text. A light blue border should now be on the tab. At this point, it’s selected so let’s click the “Change Properties” button again.
Tip: To move around a section, use your arrows
For tabs and sections, the Display tab contains the schema name we need.
Note: If you have a GUID for the name, feel free to rename it to something recognizable. Typically, I prefix tabs with “tab” and sections with “section”.
Next, get the name of the section we are hiding.
Now we should have our schema names
- Relationship Type – customertypecode
- General Tab – general
- Section – sectionPolicy
Ode to the Code
Getting a Field
To do this, you’ll want to call:
Xrm.Page.getAttribute(“CRM_Field_SchemaName”)
So for our example, I’m going to use the “Relationship Type” attribute called customertypecode. To get this attribute, we’re going to call:
Xrm.Page.getAttribute(“customertypecode”)
Getting the Fields Value
Now that we have the field, let’s get the value:
Xrm.Page.getAttribute(“customertypecode”).getValue()
Our Logic (Pseudo code)
When writing code, I like to talk my way through it and pseudo code and comments are two easy ways to do this. A comment in JavaScript can be done with the double slash “//”.
// function togglePolicyInfo(){
// if policy info equals Customer
// show section
// else
// hide section
// }
Showing the Real Code
Our psuedo code is just the plan of what we want to do. Here’s the code, you’ll actually need.
function togglePolicyInfo(){
if (Xrm.Page.getAttribute('customertypecode').getValue() == 100000000){
// Customer - show policy information
Xrm.Page.ui.tabs.get("general").sections.get("sectionPolicy").setVisible(true);
} else {
// hide policy information
Xrm.Page.ui.tabs.get("general").sections.get("sectionPolicy").setVisible(false);
}
}
Adding the Code
We need to add the code to a Web Resource and then to two events: OnLoad of the Form and OnChange of the Field.
Summary
Now whenever I choose the relationship type Customer, I can see the applicable sections. Although this was a bit on the light side, hopefully this can get you started.
Here are some additional resources:
- http://msdn.microsoft.com/en-us/library/gg328255.aspx
- http://www.w3schools.com/js/
- http://crmbusiness.wordpress.com/2011/02/17/crm-2011-javascript-xrm-page-basics/
Hope you enjoy!
Posted by Paul Way on December 28, 2011 at 02:15 PM in CRM Javascript, Jquery | Permalink | Comments (0) | TrackBack (0)




Recent Comments