Microsoft MVP Logo

In a few recent posts I blogged about how you handle events using the commanding framework when someone clicks a button or another control in the SharePoint 2010 ribbon as well as how you can implement this using a custom page component. As I mentioned, one of the aspects of the commanding framework is that you can have your command specify when it is and is not available. The SharePoint ribbon command manager checks the commands to see if they are or aren't available at given times. When a command is not available, the button is disabled (grayed out) in the ribbon and cannot be clicked. This facilitates a good user experience.

You implement this in one of two ways depending on how you implemented your event handling. If you do it declaratively you use the <CommandUIHandler EnabledScript="" /> attribute. If you do it with a page component you do it with the canHandleCommand() method in the client-side object. For the sake of this post let's just refer to these as the "can execute handlers" of the command (that's what WPF & Silverlight 4 call it in their commanding implementations). Sounds easy, but what if...

The Challenge...

What if you need to make a call back to some resource to see if the command should or shouldn't be enabled? Well, because it's JavaScript (err... ECMAScript... excuuuusssseeeemeeee), the call has to be async. OK, so what's the big deal? Well, if it's async, then you just left the command. When your check finishes, how are you supposed to tell the ribbon "hey, come back here and check the status of the command to see if it is or isn't available."

The Solution!

Ah, there's a solution for this (no, not some *.wsp with a bunch of junk in it). Here's what you'll need to do. After you issue your async call in the can execute handler, you need to return FALSE back to the ribbon to essentially tell the ribbon "I'm not sure if this command is available right now, but for now, let's just say it isn't while I check."

Then, when your async call completes, if the command is available, change the value of some private JavaScript variable from FALSE to TRUE. You then need to tell the ribbon "hey, come back and check this command's can execute handler". To do this you need to raise the JavaScript event ApplicationStateChanged in the ribbon which can be done by calling the RefreshCommandUI() method. This will tell the ribbon to go back and check if the command is available or not. So you need to go back into your can execute handler and add some logic to check this variable instead of blindly returning FALSE. Just be careful because you may need to add a bit more logic in your handler to make sure the value is refreshed every time state changes (like if an item is selected in a list in the ribbon).

One Parting Thought...

Because you're likely going to want to use some private JavaScript variables for your page component, you're likely going to want to make sure these are localized and available to your command and only your command. In that case you're pretty much pushed into the direction of implementing your command as a page component as that's the only option that lets you have a true client-side object whereas the <CommandUIHandler /> way is a bit more ad-hoc and loose.

Comments powered by Disqus