Saturday, January 15, 2011

SharePoint 2010 Dialog Auto-Sizing and Master Page Customization

SharePoint web dialogs bring an exciting new UI feature: they can auto-size to the content of a hosted page. Auto-sizing works by examining the contents of your page during page load, and setting the size of the dialog accordingly. Unfortunately, this feature can be speed bump on the road to master page customization. This post will describe the master page customization process necessary to keep dialog auto-sizing working with your master pages.

The most important thing to note is that the auto-sizing feature is aware of whether the ribbon is fixed at the top of the screen. It is important to know whether your master page has the ribbon fixed at the top of the screen or not in order to customize it to work well with auto-sizing. A ribbon fixed on top of the screen looks like this, with the page content below the ribbon scrollable separately from the ribbon itself:

ribbon_fixed_at_top

If the ribbon is fixed at the top of the screen, be sure the following statements about your master page are true:
  • The ribbon is inside an element with ID "s4-ribbonrow".
  • The remaining page content is inside an element with ID "s4-workspace".
  • The element with ID "s4-workspace" is scrollable.
  • The <body> element is not scrollable.
If the ribbon is not fixed at the top of the screen, be sure the following statements about your master page are true:
  • There is no element on the page with ID "s4-ribbonrow".
  • The <body> element is scrollable.

The auto-sizing process happens when the hosted page loads. If your master page or any individual pages use dynamic HTML to change the size, position, or amount of content on the page after page load, you may need to re-invoke the auto-sizing process after the dynamic content update in order to obtain a correctly-sized dialog. From within a hosted page, call
window.frameElement.autoSize();
to invoke the auto-sizing process. During initial page load, the dialog is hidden and a loading dialog is shown (see below). However, after the page has loaded, re-invoking the auto-sizing process will continue to show the existing dialog while changing its size.

dialog_loading


If your master page uses a table-based layout, or a variable-width layout, the auto-sizing process may be unable to determine the correct size. In that case, you can try to set a minimum or fixed width on an element in the page in order to help the auto-sizing process.

Sunday, January 9, 2011

SharePoint 2010 - Enabling a Button on the Ribbon Based on Selection

How to create a button which enables if and only if a single item is selected. This isn’t something we have out of the box, but the code to get this functionality is pretty simple. I’m going to assume that you’re generally familiar with SharePoint, CustomActions, and customizing the Ribbon – if that’s not the case, you’d probably be better off researching those things before delving into this.

Basically, the enabling behavior all boils down to the following few lines of code:

EnabledScript="javascript:function singleEnable() {   var items =
   
SP.ListOperation.Selection.getSelectedItems();   var ci = CountDictionary(items);   return (ci == 1); } singleEnable();"

What this does is query to get the dictionary of selected items, and if the size of the dictionary is 1 it returns true (enable), otherwise it will return false (disable). Technically, I should have used Script on Demand to call into the SP.* namespace, but since I’m calling this from the Ribbon I have a high confidence that SP.js has been loaded already.

With nothing selected:

image


With one item selected:

image


Clicking the button:


image


And with more than one item selected:


image


You could also change this to enable only if no items were selected, or if any number of items were selected. The way to make those kinds of changes should be relatively self-explanatory.

The full CustomAction code for a sample Ribbon button which enables when one item is selected is at the end of this post. The code assumes the following:
  1. You want to add this button to the New group on the Documents tab. If you want to add the button to another location, you should change the Location attribute of the CommandUIDefinition element (as well as change any appropriate attributes in the Button element, such as Id and Sequence, to match the new location).
  2. You have an icon image at LAYOUTS/SharePointProject1/DemoButton.jpg. If that’s not the case, you should either put an icon at that location or change the Image32x32 attribute to a valid icon path.

CustomAction code:

<CustomAction   Id="EnableSingleSelectButton"   Location="CommandUI.Ribbon" >   <CommandUIExtension>     <CommandUIDefinitions>
     
<CommandUIDefinition   Location="Ribbon.Documents.New.Controls._children">   <Button Id="Ribbon.Documents.New.EnableSingleSelectButton"           Alt="Button enabled on single selection"           Sequence="35"           LabelText="Single Select"
 
Image32by32="/_layouts/SharePointProject1/DemoButton.png"           Command="SingleSelectButton"           TemplateAlias="o1" />       </CommandUIDefinition>     </CommandUIDefinitions>     <CommandUIHandlers>       <CommandUIHandler           Command="SingleSelectButton"           CommandAction="javascript:alert('There is only one thing selected!');"           EnabledScript="javascript:function singleEnable()
          {
            var items = SP.ListOperation.Selection.getSelectedItems();             var ci = CountDictionary(items);             return (ci == 1);           }           singleEnable();" />     </CommandUIHandlers>   </CommandUIExtension> </CustomAction>