In day to day working with Dynamics CRM 2011, an issue you may come across when customizing an entity is controlling the navigation pane items programmatically. With Dynamics CRM Version 2011, It’s much more straightforward to add and remove the navigation pane objects, by using the form customisation screen, a feature not available in version 4.0 where a sitemap edit was required to remove these elements.
This works great and fits most requirements, but I want my navigation pane to be "dynamic", to show only relevant links, which are based on the form context. In this example, I will assume I have loaded a Contact record, and my navigation bar will need to hide or reveal the related entities depending on the contact type (optionset).
For the purposes of this post, I wont be giving a walkthrough on how to register form events, I'll be focusing on functionality only. If you want an end to end demo, feel free to leave a comment :).
For the purposes of this post, I wont be giving a walkthrough on how to register form events, I'll be focusing on functionality only. If you want an end to end demo, feel free to leave a comment :).
A standard approach to this is to use the following syntax
Xrm.Page.ui.navigation.items.get()
Xrm.Page.ui.navigation.items.get()
passing the Nav bar element ID, and controlling it’s display style like so...
//Ensure navitem is "quoted" to represent string // bool: true = Visible, false = removed function showNavItem(navitem, bool) { var objNavItem = Xrm.Page.ui.navigation.items.get(navitem); objNavItem.setVisible(bool); }
Using this approach, you can build up your business logic to hide or reveal the elements based on the contact type as follows.
function controlNavElements() { //this returns the numeric value of the optionset var contactType = Xrm.Page.getControl("customertypecode").getAttribute().getValue(); if (contactType == 100000000) // Contact type A { //Display nav element 1 and Hide Nav element 2 showNavElement(navelement1, true); showNavElement(navelement2, false); } else if (contactType == 100000001) // Contact type B { //Hide nav element 1 and display Nav element 2 showNavElement(navelement1, false); showNavElement(navelement2, true); } else // Neither type A or B { //Hide both Nav elements showNavElement(navelement1, false); showNavElement(navelement2, false); } }
Controlling Navigation Items, where the entity is related by (N:N) many-to-many.
The example above will work jsut fine when hiding Navigation pane elements, where the entity has a parental relationship. (eg, A contact’s relationship to it’s activites). In instances such as these, The Element ID of the Navigation pane object does not change, and your script will work with any contact you have open.
N:N relationships are different!
If you use the IE developer tools (F12), and use the “select element by click” tool, when selecting a Navigation element to an N:N related entity, you’ll see something like this as the ID value.
navnew_contact_otherentity{5e62a1bb-c3cd-497e-aea1-d23dc85dd623}
The ID, is suffixed with a guid, which is the ID of the open record. This is how Dynamics displays the related entities when you click the Navigation Item.
With that in mind, my previous display functions are useless for N:N, as the ID itself will be different for every contact record that is open. What you’ll need, is a function that ignores the GUID part of the N:N element, but unfortunately there no “out of box” function I’m aware of that does this.
So here it is…
My work-around is to loop through all Navigation pane elements, each time checking for the prefix of the element ID (which remains constant) if a match is found, it will update its display properties. This allows you to use the following function, irrespective of the relationship type.
/*********************************************************************************** navElementDisplay ## Param 1: navElementID ## For standard N:1 relationships, pass the ID in it's entirety, for N:N relationships pass the ID up to the opening brace containing the guid. ## Param 2: displayRule ## "inline" = Displayed "none" = Hidden ***********************************************************************************/ function navElementDisplay(navElementID, displayRule) { var navElement; var navElementArray = Xrm.Page.ui.navigation.elements.get(); var i = 0; for (i = 0; i < navElementArray.length; i++) { elementId = navElementArray[i].$K_0; //element ID Tag if (elementId.indexOf(navElementID) != -1) //indexOf fuction returns -1 if not found { //If found, step in and get element, using current ID navElement = document.getElementById(elementId); } } //exit loop, Update display rule navElement.style.display = displayRule; }
And invoke it like so...
if(contactType == 100000000) { navElementDisplay(navelement1, "inline"); navElementDisplay(navelement2, "none"); }
Hope this helps
Craig
No comments:
Post a Comment
Thanks for your comment
Craig Hamer