SharePoint 2010 Ribbon Button Error – "Access is denied. sp.ui.rte.js…"

Heather WatermanHeather Waterman (@hwaterman) and I turn to each other fairly regularly when either of us is stuck on something that we know the other will understand better. It’s the tremendous value of the SharePoint community along with the crazy tools like Skype that we have these days. (When I started coding, it was hard enough to get the attention of the person sitting next to you, much less someone across the hall or on the other side of the world. Or South Carolina.) All that and the fact that Heather is an all around good egg, and it’s a win for me at least!

Today I was having a problem where the buttons on the SharePoint 2010 ribbon weren’t working correctly. When I popped open the Developer Tools in IE9 (by hitting F12), I could see this error every time I clicked on one of the ribbon’s Rich Text formatting buttons.

image

That’s “SCRIPT5: Access is denied.  sp.ui.rte.js?rev=uY%2BcHuH6ine5hasQwHX1cw%3D%3D, line 2 character 267202″. Sure, it made sense to me, too.

I found several blog posts, each of which had interesting suggestions (e.g., add the site to the Trusted Zones or check for empty CSS or JavaScript files), but none of them worked for me.

Off to Skype to ask Heather, the expert. She had seen this issue before, but the tips above had solved it in the cases she could remember. We started marching through my custom master page and CSS to see what we could find.

Long story short, I was loading jQuery, jQueryUI, and SPServices from CDNs, using the txt file I describe in my post called, aptly enough, Referencing jQuery, jQueryUI, and SPServices from CDNs. I would have thought that since the error was about one of SharePoint’s js files, the issue would have been with one of the js files I was loading from the CDNs. However, it turned out to be the jQueryUI CSS file, not any of the script files.

I’m not sure that it is part of the cause, but because I’m working on a new SharePoint Internet site in stealth mode, I have the IP address in my hosts file. My guess is that this causes an issue with loading CSS files from another domain.

Well ,thanks to Heather I have the rest of the afternoon to do other useful things rather than spending more time on this silly issue. Thanks, Heather!

Using Unescaped CAML in a Data View Web Part (DWVP) in SharePoint Designer 2010

I’ve created more customized Data View Web Parts (DVWPs) than I could possibly count, but I still learn new stuff all the time. Tonight I was trying to get a DVWP to switch into DataSourceMode=”CrossList” and I accidentally noticed a nice little trick.

If you right-click on the DVWP and select Properties, a Tag Properties Task Pane will open up, probably in the bottom left or bottom right of your SharePoint Designer screen. If you click on the DataSource section, it’ll look something like this:

image

Note that the SelectCommand which I’ve highlighted is shown unescaped It seems that you can make edits there and SharePoint Designer will pass them into the DataSource section escaped, just as it must be.

I’ve used Notepad or XML escape Web pages or XML escaping apps to do this for years, and it turns out that SharePoint Designer would have done it for me all along. If that’s in some documentation somewhere, I challenge you to find it!

SPXSLT (SharePoint XSL Templates) Release 0.0.9

SPXSLTI’ve just released a new version of the SPXSLT Codeplex Project, version 0.0.9.

In this release, I added one new template called FixAmpersands. FixAmpersands is useful when you want to “join’ two lists in an AggregateDataSource in a Data View Web Part (DVWP) and the column you are uisng as the key may contain ampersands. This isn’t all that unusual if the keys are text values that don’t represent some sort of coding scheme, like a Product Code. Sometimes you may need to “join” two column values that contain ampersands, like “Beef & Kidney Pie” or “Tool & Die”. Because of the way that ampersands must be encoded on the Web, the primary value will contain the ampersand & but the secondary value will contain an encoded ampersand &. By calling FixAmpersands on the primary value, the “join” will work because the & will be replaced with &. (In fact, I had to monkey with the representations of the ampersands in that last sentence to get them to display correctly.)

The template is recursive, so it will replace *all* occurrences of & with &.

FixAmpersands looks like this:

<xsl:template name="FixAmpersands">
  <xsl:param name="StringValue"/>
  <xsl:variable name="Ampersand" select="'&amp;'" />
  <xsl:choose>
    <xsl:when test="contains($StringValue, $Ampersand)">
      <xsl:value-of select="concat(substring-before($StringValue, $Ampersand), '&amp;amp;', substring-after($StringValue, $Ampersand))"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$StringValue"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

And you call it like this:

<xsl:varaible name="FixedTitle">
  <xsl:call-template name="FixAmpersands">
    <xsl:with-param name="StringValue" select="@Title"/>
  </xsl:call-template>
</xsl:variable>

In the examples above, here’s what would happen:

Title FixedTitle
Beef & Kidney Pie Beef &amp; Kidney Pie
Tool & Die Tool &amp; Die
Sugar & Spice & Everything Nice Sugar &amp; Spice &amp; Everything Nice

I also fixed a small issue I noticed with the MultiSelectValueCheck.xsl file, which was missing the stylesheet wrapper.

Coming Soon: Caching in SPServices

For a long time, I’ve been reluctant to try to add caching to SPServices. The main reason is that I couldn’t think of a reliable way to do it that wasn’t going to cause potential issues and it also had to be backward compatible. Well, I think I’ve cracked that nut. In the current alpha of SPServices (v0.7.2ALPHA3), I’ve implemented a caching capability.

In my SPServices development environment, I have a ridiculous page which has far more calls to SPServices than you are likely to ever implement on one page yourself. It’s the page I use to test all of the potential combinations of calls that you might ever want to make to ensure that they work consistently. My testing is certainly not always foolproof, but this page has served me well to get most of the obvious kinks out for every version since the beginning of the library. (It runs in WSS 3.0, so I start there and move up the chain to test things with cross-version capabilities.)

Just to show how ridiculous it is, here are some counts:

Function Number of Calls
SPFilterDropdown 3
SPArrangeChoices 2
SPSetMultiSelectSizes 2
SPCascadeDropdowns 3
SPLookupAddNew 5
SPDisplayRelatedInfo 4
SPAutocomplete 1

At first glance, that may not seem so bad, but it takes 47 calls to various Web Service operations, and therefore 47 AJAX calls, just to load the page. It can take anywhere from 5-8 seconds on average, though sometimes it’s far worse.

After implementing the caching capability, I’ve cut that down from 47 to 27 calls, which is a 43% reduction, if I’m doing my math right. Even better, the load time is now consistently around 3.5 seconds. (I’m timing things in Firefox because Firebug makes it easy.)

Better yet is the performance improvement I see when I start changing values in the dropdowns, which causes more calls. The way I’ve implemented this, I’m caching the results for every single unique SOAP message SPServices sends to the server. This means that I’m not trying to cache all the items in any list, but only the XML which is returned for each request. Since each request has a unique “fingerprint” in the form of the SOAP message itself, I have a key to use to store the cached XML object and a way to retrieve it. The jQuery .data() function is what powers this simple little idea.

The way this works is somewhat clumsy: you only get a benefit if you make a call that is exactly the same as a prior call. However, that’s not as uncommon as you think, especially under the covers in the value added functions like SPCascadeDropdowns and most of the others above.  Many of the value added functions must call GetList for one reason or another, and just caching those calls cuts out something like 15% of the calls in my bloated page.

Now that I’ve posted this new alpha, I *really* need some help regression testing. Right now, the caching is all or nothing. There’s a default option called cacheXML, and it’s set to true in the alpha, so everything that can be cached will be cached. (When I release this functionality for real, the option will be set to false so that nothing works differently in existing applications.)

So here’s how you can help. Download the alpha and drop it into a test environment where you are already making SPServices calls. Try some tests with the alpha as it is, and then with the cacheXML option set to false. With Fiddler or Firebug, you should be able to see the SOAP traffic and get a gauge on what sort of improvement you might be able to gain. Let me know what you see and whether you have any problems. You can pass cacheXML: false into any call to SPServices if you need to turn off the caching for that call. Try some debugging, too, because I don’t want to make anything work differently than it has in the past.

The idea is simple, but it may well cause problems I haven’t thought about. Let me know how things go as a comment to this post, or better, in the SPServices Discussions, where it’s easier to post and format code. I think you’re going to like this!

Moving Lists from Hosted WSS 3.0 to Office365 – The ShareGate Way

The other day I did a post in which I was grousing about what a pain it is to move individual lists from a 2007 environment to a 2010 environment. Even worse, I wanted to move the lists from a hosted WSS 3.0 environment at FPWeb to Office365. Because of this, there was no access to the back end, and it was a one-time move, anyway. I did figure out a really messy way to do it, and my prior post outlines that if you’re interested.

[notice]I’m going to stick with my premise that portability is one of SharePoint’s Achilles’ heels. We absolutely have to get to a point where there are better answers to these questions than “hire a developer” or “buy a third party tool”.[/notice]

GSoft GroupBen Niaulin (@bniaulin) at GSoft Group saw my complaining on Twitter and reminded me that as an MVP I could get a copy of their Sharegate product for free. BTW, GSoft fielded an awesome Iron SharePoint team called the SHAREPOINT G-NIUSES at the recent SharePoint Summit in Toronto. I was there to see what they came up with, and I was impressed. Check them out if you need SharePoint Services in Canada (or anywhere, I suppose).

SharegateI was certainly willing to try Sharegate out, of course. Setting it up and getting it running was a snap. The user interface is really nice – something that I think many end users would be totally comfortable with. Ben wanted to give me a tutorial up front, but I figured that wouldn’t be a fair test. I wanted to see if I could figure it out myself, just with the existing help.

My first challenge was that I couldn’t figure out how to copy the structure of the lists from WSS to Office365. It was clear how to move the content, but not the structure. I caved and pinged Ben. Apparently, this was by design.

In Ben’s words:

Sharegate is currently a Content Migration tool, you need to have the destination library there.

The idea is that when migrating from SharePoint 2007 to 2010 many new features and structures exist. What  may have been a lookup column could become a Managed Metadata column in 2010 instead. That’s what we focus on, migrating the content, for now.

This wasn’t a big deal, though, because I was interested in moving only about a dozen lists, and the structures weren’t that complex. I had hoped to be able to move the structures *and* content, but I just bit the bullet and built the structures (that I hadn’t built already based on my prior, manual method) by hand.

Here are some screenshots that show how straightforward it was to move the content. The first step, which I don’t capture here, was simply to connect to the source and destination locations.

Next you select the source “container”, in my case, an individual list.

image

Then you specify the destination “container”.

image

Once you’ve made those choices, you can see all of the items in the source which you can migrate.

image

I wanted to move everything, so I just clicked the “Select All” link.

image

The next prompt let me choose between an easy and a more powerful route. I just wanted to go the Full copy route, as I was moving the content wholesale. The option on the right, which I poked around in but didn’t use this time, gave me a *lot* of control over how the content moved. I could remap fields, change values based on conditions, all sorts of stuff. The other migration tools I’ve looked at also do this, but I really liked the interface in Sharegate.

image

Next came a warning about mapping the permissions. Since I didn’t have access to the back ends, I couldn’t install the Sharegate Extension. This meant that the permissions wouldn’t go across. This was something else I didn’t care about, so I simply clicked Continue.

image

image

And voila, the content moved across, with a nice progress indicator telling me how things were going. It wasn’t a lot of content, so it was pretty quick.

Lather, rinse, and repeat for each of my other lists and I was all set.

All in all, it was a pretty painless experience. I think that Sharegate’s UI is one of the big selling points for it. Also, since it doesn’t try to be too many things (like some of the products out there), the process was streamlined for basically the exact path I wanted to take. If you’ve got some content to migrate from one place in SharePoint to another, give it a look.

And thanks, Ben!