Wednesday, October 6, 2010

SharePoint 2010 - Dynamic JavaScript problems with Inline Editing

SharePoint 2010 allows inline editing of your HTML on Publishing pages, which is a nice boost to productivity. However, there are some quirks with this feature that can really trip you up if you aren't ready for them.

Here's a scenario I ran into this week. I have a simple Publishing Page with a Content Editor Web Part on it. Inside this web part, there is an HTML element that I target with some jQuery to display tooltips. The JavaScript here is really quite simple and just dynamically adds a relative positioned div to the page above the target element.

The code for this is tested and works fine outside of SharePoint. But when you edit a page, you'll find an interesting side-effect. Specially, when editing the page, the JavaScript that adds the dynamic elements to the DOM still runs. When the page is saved, even if you didn't even edit that particular Content Editor Web Part, the updated DOM elements get saved - including the tooltip changes!

I have tested this with a lot of scenarios, but it's pretty consistent across any SharePoint components that provide inline editing.

So, how do you allow JavaScript to dynamically update content on publishing pages? This is really going to depend on the nature of your content. Here are a few different scenarios I've employed in my site:
  • Extract the dynamic content and make it a web part.

    This works well if your content doesn't change that often and has few properties. A great example here would be having a web part that uses swfobject.js to load a flash file rather than placing the script call inside a Content Editor
  • Skip the JavaScript calls that update your page when in edit or design mode.

    This works really well for scenarios like my tooltip. You can do this either in JavaScript or C#, depending on how your page works.
Here is an example of checking your page mode with JavaScript, using jQuery:
if ($('#MSOSPWebPartManager_DisplayModeName').val() == 'Design' || $('#MSOSPWebPartManager_DisplayModeName').val() == 'Edit') {
        alert('Don't do anything');
    } else {
        alert('Safe to run JavaScript');