Associated views in Microsoft Dynamics CRM can be enhanced to provide relevant historical information about related entities. By showing inactive records, and giving them a unique visual style, the data takes on new meaning.

Below, I have detailed the process followed to display inactive records, and then format the rows of the associated view (from within the parent entity’s OnLoad event). Please look through what I have done, use it freely, and change it to your liking.
The solution that I have implemented involves attaching to a succession of functions on elements related to the associated view. WARNING! The suggestions that follow do not come with any warranty or guarantee of service, and are most likely not supported by Microsoft. Use at your own risk!
There are a number of ways to go about doing this, but here are two:
- Displaying inactive records in associated view (Ronald Lemmen)
- Displaying inactive records in associated view (Georged CRM Blog)
Enabling both active and inactive records, however, proves to be only the first step. An issue arose while doing a little usability testing that showed that simply having the status listed as one of the columns did not create enough differentiation between the records. Additionally, there were cases where the associated view’s toolbar needed to be stripped down to only one or two functions (to reduce visual clutter). Below is the end result of the manipulation of the associated view using only client-side Javascript:
There are two ways in which we display associated views. The first way is through the system-generated navigation on the left-side of any entity. These links add an iframe to the page whose source is the associated view. The second way is to put the associated view in an iframe directly on the tab(s) of the current entity:
- CRM 4.0 IFrame: Show Entity’s Associated View (Jim Wang)
- CRM 4.0 Show Associated-View in IFRAME (AssocViewer) (Adi Katz)
This change allows the associated view to be visible in a more relevant context within an entity.
For the use of this article I will be using the system-generated navigation, and attaching Javascript events that help to give the associated view therein a more user-friendly appearance.
Step 1: Adjust the Associated View
Follow one of the methods above that allows inactive records to be visible. Adjust the Associated View to include the Status column (I put ours toward the end, since it will not be necessary to see it once the styling is done).
Step 2: Add the Javascript to Onload of the Parent Entity
Some of the values in the code below require you to find titles, or IDs of HTML elements. To accomplish this I recommend using Fiddler and your choice of text editor.
function setAssociatedOnClick() { // Get the left-hand navigation links navbar = document.getElementById("crmNavBar"); navlinks = navbar.getElementsByTagName("a"); for (var i = 0; i < navlinks.length; i++) { // Use the tooltip text to find the correct navigation link // Could obviously use your choice of options here if (navlinks[i].getAttribute("title") == "TITLE OF ASSOCIATED ENTITY") { // Store the current onclick behavior var currOnClick = navlinks[i].onclick; // Override the current OnClick event, but start with the current one // This prevents losing any CRM-customized JScript navlinks[i].onclick = function() { currOnClick(); iframes = document.getElementsByTagName("iframe"); for (var j = 0; j < iframes.length; j++) { // Check that this frame is for our related entity if (iframes[j].id.indexOf('ASSOCIATED ENTITY STRING') >= 0) { // Change what happens when the associated view iframe loads iframes[j].onreadystatechange = function() { if (this.readyState == "complete") { var grid = this.contentWindow.document.getElementById("divDataArea"); // Process the data grid when it loads/reloads/sorts/refreshes grid.onpropertychange = function() { // Get all the NOBR elements (where text is stored) var btnlist = this.getElementsByTagName("nobr"); for (var i = 0; i < btnlist.length; i++) { // Check if the text is 'Inactive' (needs some refinement) if (btnlist[i].innerHTML.indexOf("Inactive") >= 0) { // 'Inactive' row-level style formatting btnRow = btnlist[i].parentNode.parentNode; btnRow.style.color = "#909090"; // Deal with style changes for row sorting/clicking btnRow.onpropertychange = function() { var collist = this.parentNode.parentNode.getElementsByTagName("col"); var sortCol = 0; for (var m = 0; m < collist.length; m++) { sortCol = (collist[m].className != null && collist[m].className.indexOf("SortedColumn") >= 0) ? m : sortCol; } if (this.className.indexOf("SelectedRow") >= 0) { this.style.backgroundColor = "#F0F0F0"; this.style.color = "#333333"; this.childNodes[sortCol].style.backgroundColor = "#F0F0F0"; this.childNodes[sortCol].style.color = "#333333"; } else { this.style.backgroundColor = "#FFFFFF"; this.style.color = "#909090"; this.childNodes[sortCol].style.backgroundColor = "#EAF3FF"; this.childNodes[sortCol].style.color = "#909090"; } }}}}}}}}}}}}
Here are the basic ideas in the code:
- When the content is loaded, find the link to the associated entity
- Manipulate that link to do what it normally does on a click, and add some extra behavior after that
- Attach a listener for when the associated view loads as well as when the grid changes
- When the grid loads, step through the records and adjust them
Once you have access to the grid, the possibilities for manipulation are pretty much endless. We have even added functions in the grid’s controls to allow a return to the original sorting (by just refreshing the page), and options on the bar for external links. I hope this helps stir your imagination for the possibilities that are available. Please ask any questions you might have, and I will try to answer them to the best of my ability.
I think the function setAssociatedOnClick() would work for me, just not sure how to implement on some thing like
if (document.getElementById(‘nav_mdv_campaign_campaignresponse_accepted’) != null) {
document.getElementById(‘nav_mdv_campaign_campaignresponse_accepted’).onclick = function() {
loadArea(‘areaCampaignResponses’);
}
}
I see how I could modify function to hind records with a field set to ‘registered’ just need to get that recordset
Luke,
Your solution interests me, as I need to accomplish a similar task. I’m a newb developer and I’m hoping you’d be willing to hold my hand a bit.
I’ve already successfully moved the related records to an IFRAME. Would you perhaps add some detail to how i can adapt your code to work in conjunction with the associated records being in this IFRAME. Such as which ELEMENTS need to fit into which parts of your script.
Thanks in Advance,
Dave
thanks very nice idea and code