Thursday, December 30, 2010

CRM Gotcha: Using Javascript URIs in SiteMap

Donna Edwards, CRM forums co-owner and established MVP, will often bounce threads from the “main” CRM forum into the CRM Development forum, which I comfortably call home, whenever the question is a particularly obscure one and hasn’t received an answer from the cabal of experts usually found in the “main” CRM forum.  I delight in any opportunity to take her “escalations” as a personal challenge.  Today, I found it in this thread.

The author explains that his usage of a “javascript:” URI produces interesting behavior when placed into the Url attribute of a SubArea element within the CRM SiteMap.  At first, with some simple JavaScript, he was receiving the text “[object]” in the dynamic CRM content frame.  Then, when he voided the return of the URI’s script, the “Loading…” message and graphic would remain (until some other area was loaded).

I encountered a similar behavior when working on the Embedded Advanced Find View project, and guessed that the same situational elements must be present here.  Not wanting to be wrong, I pulled out the IE Developer Tools (side-note: Microsoft, this is seriously the coolest feature of IE 8), and confirmed it.

So, what explains the behavior?  The answer is simple:  AJAX.  See, CRM’s UI scripts don’t simply pass the Url value into the src attribute of a frame (or Iframe); how would it achieve the “Loading…” message, if it did?  The trick, is that CRM scripts overwrite the contents of the dynamic content frame with the HTML necessary to display that message, and then instantiates a new, ActiveX [FreeThreaded]DOMDocument object behind-the-scenes to load the target URI.  When the status of the DOM document object becomes complete, the dynamic content frame’s DOM is overridden with the results.

This means that the original contents are lost.  Because the previous contents were also loaded in this dynamic fashion, and don’t exist in the browsing history, the frame can’t be historically reverted (e.g. javascript:history.go(-1)).  Additionally, a “javascript:” URI isn’t loaded into the DOM document object until after the contents have already been replaced by the “Loading…” message.  So, it makes any reference to the information that had originally been in the frame nearly impossible to obtain.

I’m sure somebody will figure out how best to produce content or redirection within the dynamic content frame, while simultaneously using a “javascript:” URI, but I’m unaware of any such process available today.  I think it’s simply safer to say that, though not expressly declared as such in the SDK, “javascript:” URIs aren’t supported.

Monday, December 20, 2010

Global MVP Summit, Here I Come!

Registration for the Microsoft 2011 MVP Global Summit opened on Monday, last week.  The moment registration was possible, I completed it.  My excitement could be barely contained when Matt Wittemann, a fellow CRM MVP from C5Insight, agreed to room with me during the event.  This will be my first Summit, and it will be awesome to have an experienced guide.

(Matt blogged about my Javascript Grid Editor project earlier this year, several months before I found out I had been nominated for the MVP Award.  Since then, I’ve become a follower of his ICU MSCRM blog.  He’s really got some neat stuff there, so check it out if you haven’t had a chance.)

I’m also blessed to have my employer, BC Technical, offer to send me to the event.  Obviously it’s easier to attend the Summit for us state-side MVPs, but even without compensated hotel accommodations, attending the event would have exhausted my available funds.  I don’t write about my employer much in this blog, mostly because this blog is a personal space, but this exception I’m making is to say, “thank you,” in a public format.  BC Technical has always encouraged personal growth in my career, but this contribution makes them invested in a way I didn’t expect.  May we all be so fortunate!

As for the Summit, I’m ardently anxious to meet my personal CRM heroes—many of whom have indicated that they will be attending.  I’ve had a wonderful chance, through various MVP-related channels, to establish personal relationships with people I only knew by name only a year ago.  Though the Global MVP Summit is not product-specific, I’m sure most of my time will be spent within the CRM-sphere.

So, it’s full-steam ahead to the Summit!  If you’re attending, and would like to meet, send me a message.  If you’re a part of the CRM MVP team, I probably owe you a beer, so don’t forget to collect!

Wednesday, December 8, 2010

Updated CRM Javascript Library: 1.2

It’s been a little while since I published all the additions I’ve made to my personal CRM Javascript Library up to GitHub, but today I found a few moments to do so.  Most of the scripts I’ve published on this blog are in the library, and are up-to-date with the most recent bug-fixes and features.  This library of functions is what I use in my CRM deployment, and helps by drastically reducing the amount of effort spent in deploying functionality to customizations.

One of these days, I’m going to have to get around to writing up descriptions of all the functions on the project page.  Oh well.  Hopefully, the names of the functions are pretty clear regarding their intended application.  Also, since most of them come from posts, a cursory search through the blog should reveal helpful explanations and even some sample code.

Saturday, December 4, 2010

Refresh the Notes Section

A recent CRM Development forum inquiry lead me to probe the DOM of an entity page to discover a simple way to refresh only the Notes area of that form.  The following two line script simply reloads the Iframe containing the notes, which can be helpful in situations where the notes have been changed through some ancillary mechanism, but you don’t want to reload the entire form to view the changes.

var notesFrame = document.getElementById("notescontrol");
notesFrame.src = notesFrame.src;

Thursday, December 2, 2010

Update to “Hiding Buttons and MenuItems”

I’ve just made some dramatic improvements to the code in the “Improved Code for Hiding Buttons and MenuItems” post.  It eliminates the usage of the on-the-fly style changes, which in certain situations does not hold properly, causing the element to become visible again.

Instead of style changes, I’ve opted to use the removeChild() DOM method.  Since, however, functions to restore the button/menu item are obsoleted by this change, I’ve also included instructions and mechanisms for using insertBefore() to restore the button/menu item to its original location.

If you’ve been frustrated by reappearing elements, or wanted truly dynamic control over concealing and revealing them, visit that post immediately.