Archive

Posts Tagged ‘SharePoint’

SharePoint 2013 Modal Dialog Tips & Tricks

March 22nd, 2013 Comments

After hibernating for the winter, I have a spring treat for you all.

I present to you: Tips & Tricks: SharePoint 2013 Modal Dialogs. It’s a follow-up to my original SharePoint 2010 dialog tips & tricks post!

SharePoint 2010 Modal Dialog Tips & Tricks

October 30th, 2012 Comments

Wow, another week to-the-day and it’ll have been two years since I posted anything here!

Have learnt much and doing very cool things at Collabware and our CLM product for the past year and I’ve finally gotten off my butt and wrote a post with some tips & tricks on SharePoint 2010 Modal Dialogs on our blog:
http://blog.collabware.com/2012/10/30/tips-tricks-sharepoint-2010-modal-dialogs/

Of note is the ability to resize a modal dialog. I hadn’t found a completely working example so I’ve posted a version of the code we use for Collabware CLM. It leverages the same code that’s in SP.UI.Dialog.js when it initially sizes the dialog on page load. No dependencies on jQuery or other external frameworks!

SharePoint 2010: var $ conflict between CMSSiteManager.js and jQuery

November 6th, 2010 1 comment

I ran into an issue recently on a SharePoint 2010 project where a page containing a Thumbnails list view was throwing a JavaScript error. I actually took the wrong path troubleshooting this and burned through a lot of time as a result. I had incorrectly assumed the error had something to do with our custom master page.

Turns out the CMSSiteManager.js library that is used by the Thumbnails list view is also using the $ variable! Argh!

Good thing the plug-in pattern we use only calls $ internally and not globally…

(function($) {
  // plug-in goodness here...
})(jQuery);

Unfortunately our scripts for invoking the plug-ins was referencing $:-(

$(document).ready(function(){
  $('.foo').samplePlugin();
});

A quick replacement of $ to jQuery did the trick:

jQuery(document).ready(function(){
  jQuery('.foo').samplePlugin();
});

If you have large blocks of inline jQuery code on your page, you’ll probably want to use jQuery.noConflict():

jQuery.noConflict()(function() { 
    // code using $ as alias to jQuery
});

Issue with custom styles in the SharePoint 2010 Rich Text Editor and @media

October 12th, 2010 Comments

I recenty ran into some issues with exposing custom styles in the SharePoint 2010 Rich Text Editor (RTE) in browsers other than IE, or specifically with Firefox and Safari.

In order to have a custom style show up in either the Markup Styles and Styles drop downs in the Ribbon, you need to prefix your HTML class with either ms-rteElement- (shows up in Markup Styles) or ms-rteStyle- (shows up in Styles). You also need to use the -ms-name property within your rule.

For example:

H2.ms-rteElement-H2Lg {
  -ms-name: "Large Heading 2";
  font-size: 26px;
}

The problem I ran into was that the custom styles showed up the dropdowns for IE but not in any other browser. At first I though it was because the -ms-name property is a custom CSS extension in the MS name space. I tried adding properties like -moz-name and -webkit-name and even name but they had no effect.

Turns out the RTE custom styles don’t show up if they appear inside an @media block in your CSS file!

I ended up creating a bunch of stubs with just name -ms-name property BEFORE the @media block. If you try to place the stubs after the @media block, the RTE does not pick-up the label for the custom styles, they show up as empty options without labels in the RTE drop downs.

/* create stubs with -ms-name property here */
h2.ms-rteElement-H2Lg {
  -ms-name: "Large Heading 2";
}

ul.ms-rteStyle-LinksList {
  -ms-name:"Links List";
}

/* place actual properties inside @media block */
@media screen {

  h2.ms-rteElement-H2Lg {
    font-size: 26px;
  }

  ul.ms-rteStyle-LinksList {
    list-style: none;
    margin: 0;
    padding: 0;
  }

}

You can read more about how to create custom styles for the SharePoint 2010 RTE here:

SharePoint 2010: Fixing the MSDN Contextual Tab Web Part Walkthrough

July 31st, 2010 4 comments

UPDATE!!!

The latest versions of the CKSDev for SharePoint 2010 include an SPI for stubbing out a contextual web part! I highly recommend that anyone coding for SP2010 to install the CKS Dev Tools!

http://cksdev.codeplex.com/

I haven’t had much opportunity to work with SharePoint 2010 in the past few months. However, I did get to try out the MSDN walkthrough for creating a custom web part with contextual ribbon tab recently. You can find the article here: http://msdn.microsoft.com/en-us/library/ff407578.aspx

In a nutshell, what’s supposed to happen is when you click on the web part, there will be a custom tab that appears in the Ribbon. It all works great for the first instance of the custom web part you place onto a page, but if you try adding a second instance of the web part, your page blows up!

You’ll get the following error:
Item has already been added. Key in dictionary: ‘Ribbon.CustomContextualTabGroup’ Key being added: ‘Ribbon.CustomContextualTabGroup’

:-/ … looks like there wasn’t much QA done for the walkthrough. Anyways, to make a short story shorter… I posted a question on the TechNet forums and Dallas Tester from MS did get back to me with a bunch of suggestions.

Here are the changes you can make to allow for multiple instances of the custom web part to appear on the page without everything blowing up.

Make the following modifications to the ContextualTabWebPart class.

Add the global ‘_added’ bool and OnInit event handler:

static bool _added = false;

protected override void OnInit(EventArgs e)
{
 base.OnInit(e);
 _added = false;
}

Since we no longer have to get the unique component ID in the delay script, I changed DelayScript into a private string:

private string delayScript = @"
 function _addCustomPageComponent()
 {
  for (var i = 0; i < g_customWebPartIds.length; i++)
  {
    SP.Ribbon.PageManager.get_instance().addPageComponent(new ContextualTabWebPart.CustomPageComponent(g_customWebPartIds[i]));
  }
 }

 function _registerCustomPageComponent()
 {
  SP.SOD.registerSod(""CustomContextualTabPageComponent.js"", ""/_layouts/CustomContextualTabPageComponent.js"");
  var isDefined = ""undefined"";
  try
  {
   isDefined = typeof(ContextualTabWebPart.CustomPageComponent);
  }
  catch(e)
  {
  }
  EnsureScript(""CustomContextualTabPageComponent.js"",isDefined, _addCustomPageComponent);
 }
 SP.SOD.executeOrDelayUntilScriptLoaded(_registerCustomPageComponent, ""sp.ribbon.js"");";

Modify the OnPreRender event handler:

protected override void OnPreRender(EventArgs e)
{
 base.OnPreRender(e);

 ClientScriptManager csm = this.Page.ClientScript;
 string componentId = SPRibbon.GetWebPartPageComponentId(this); // the unique component id 

 // if this is the first instance of the custom web part,
 //we need to add the contextual tab to the ribbon
 if (!_added)
 {
  this.AddContextualTab();
  _added = true;
 }

 // we need to create an array which will store the IDs of all instances of our custom web part
 csm.RegisterClientScriptBlock(
  this.GetType(), "DeclareCustomWebPartArray", "var g_customWebPartIds = new Array();", true);

 // add this webpart's ID to our array
 csm.RegisterClientScriptBlock(
  this.GetType(), "AddCustomWebPartId" + componentId, "g_customWebPartIds.push('" + componentId + "');", true);
   
 csm.RegisterClientScriptBlock(this.GetType(), "ContextualTabWebPart", this.delayScript, true);
}

If you want to verify that the correct web part is trigger the Ribbon commands, you can modify the ‘handleCommand‘ method in ‘CustomContextualTabPageComponent.js

handleCommand: function ContextualTabWebPart_CustomPageComponent$handleCommand(commandId, properties, sequence) {
 if (commandId === 'CustomContextualTab.HelloWorldCommand') {
  alert(this._webPartPageComponentId + ' says: Hello, world!');
 }
 if (commandId === 'CustomContextualTab.GoodbyeWorldCommand') {
  alert(this._webPartPageComponentId + ' says: Good-bye, world!');
 }
}

Here’s a ZIP file of the entire solution in case you’re too lazy to make the modifications yourself. :-)

SharePoint 2010: CssRegistration ConditionalExpression Property

March 1st, 2010 Comments

In a previous post detailing the new SharePoint 2010 CssRegistration control, I mentioned that I did not know what the ConditionalExpression property did. Well, now I do!

This property takes an Internet Explorer Conditional Comment. For example, if we wanted to link to a style sheet specific to IE 7 or greater, we can do this:

<SharePoint:CSSRegistration Name="foo.css" ConditionalExpression="gte IE 7" runat="server" />

The following markup would be emitted:

<!--[if gte IE 7]>
<link rel="stylesheet" type="text/css" href="foo.css"/>
<![endif]-->

SharePoint 2010: Show Dialog on Page Load

February 11th, 2010 Comments

A quick tip…

Because the sp.ui.dialog.js library is lazy-loaded, it may not be available when the page is ready/loaded. I’ve seen some early examples where if you wanted to do something on page load, you use:

_spBodyOnLoadFunctionNames.push("YourInitFunction()");

This will not work if you want to open a SharePoint dialog on page load. Instead use:

ExecuteOrDelayUntilScriptLoaded(YourInitFunction, "sp.ui.dialog.js");

SharePoint 2010: Upgrading your Public Beta solutions to RC

February 11th, 2010 Comments

A word to the wise, if you’re planning on upgrading your solutions developed on the public beta to the new SharePoint 2010 Release Candidate, double check your code!

This is especially true if you have custom master pages, page layouts, or site templates which are derived from the OOTB ones.

Here’s a simple screen grab of a diff between the Public Beta v4.master and the version in the RC:

Screenshot of differences between the public beta and RC v4.master pages.

v4.master differences

Notice one of the Site Actions menu items has been removed in the RC and permissions are slightly different in another. There are other small differences in the v4.master like some of the sprite co-ordinates have changed for the help and recycle bin icons which might leave you scratching your head as to why the wrong image is showing up.

The v4.master is just a short example. I found quite a few differences in the Blog site template and spent quite a bit of time doing diffs and merging my customizations back into the updated RC versions.

If you’re using TFS for your source control, I found it helpful to just copy and paste the contents of original version of whatever file you customized into your versioned control file and then doing a difference/merge between that and the last version checked-in.

Categories: Development, SharePoint

Yaroslav on Customizing the SharePoint 2010 Ribbon

December 29th, 2009 Comments

My buddy Yaroslav’s been blogging away about customizing the SharePoint 2010 ribbon, like the mad scientist that he is, over the past few weeks…

Here’s what he’s got so far:

Go check it out!

Categories: Development, SharePoint

Branding SharePoint 2010 Collaboration Sites – Part 2 in a Series

December 29th, 2009 8 comments

In part one of this series on branding SharePoint 2010 collaboration sites I posted a bit about how the new Theming engine works in SharePoint 2010. In this post, we’ll be going over the new and improved CSSRegistration control in SharePoint 2010.

A history lesson; the CSSRegistration control in SharePoint 2007

The CSSRegistration control in SharePoint 2007 basically has one property you can set, the Name is the Url to the CSS file that you want to register. When you register a style sheet through the control, it adds the CSS file to an alphabetically sorted list. The style sheets in this list are then emitted as HTML <link> elements by the CSSLink control.

If you required one CSS file to be emitted before another, you would need to name them accordingly. For example:

<SharePoint:CSSRegistration Name="foo.css" runat="server" />
<SharePoint:CSSRegistration Name="bar.css" runat="server" />

Even though I registered foo.css before bar.css, the HTML on the rendered page would look like so:

<link rel="stylesheet" type="text/css" href="bar.css"/>
<link rel="stylesheet" type="text/css" href="foo.css"/>
<link rel="stylesheet" type="text/css" href="/_layouts/1033/styles/core.css?rev=..."/>

bar.css would come before foo.css and what’s this core.css doing here? Somehow, someone at MS decided that the core.css containing ALL of the base CSS rules for WSS should override any custom CSS!

As a workaround, you could set the DefaultUrl property for the CSSLink control to point to a single CSS file that would come after core.css, and then use @import to link to any additional custom CSS files.

The fact that core.css was emitted after any style sheets registered using CSSRegistration made the CSSRegistration control all but useless in 2007.

The shiny new CSSRegistration control in SharePoint 2010

So things are much better in the SharePoint 2010 world. If you examine the documentation for the SharePoint 2010 version of the CSSRegistration control, you’ll find the addition of the following properties, which currently have no descriptions to their usage in the SDK:

RevealToNonIE (boolean)

I assume this property would allow you to register IE-only style sheets.  This doesn’t seem to be working in Beta 2 though as it doesn’t matter whether I set this to true or false, the CSS files would get emitted regardless of the browser I was using.

ConditionalExpression (string)

Another assumption that this would allow us to set certain conditions in order for the style sheet to appear in HTML. Nothing at all in the way of documentation nor could I find any examples in the 14 Hive as of Beta 2.

This property is an Internet Explorer Conditional Comment. For example, if we wanted to link to a style sheet specific to IE 7 or greater, we can do this:

<SharePoint:CSSRegistration Name="foo.css" ConditionalExpression="gte IE 7" runat="server" />

The following markup would be emitted:

<!--[if gte IE 7]>
<link rel="stylesheet" type="text/css" href="foo.css"/>
<![endif]-->

After (string)

This property is what was sorely missing in 2007. We can now tell the CSSLink control to emit the registered style sheet after another CSS file. You can either define just the leaf filename, ie bar.css or the path to the CSS file, ie /foo/bar.css. If you don’t use the After property, style sheets will still be emitted by alphabetical order. For example:

<SharePoint:CSSRegistration Name="bar.css" After="foo.css" runat="server" />
<SharePoint:CSSRegistration Name="foo.css" runat="server" />

bar.css is emitted after foo.css because we specified the After property when we registered bar.css:

<link rel="stylesheet" type="text/css" href="foo.css"/>
<link rel="stylesheet" type="text/css" href="bar.css"/>
<link rel="stylesheet" type="text/css" href="/_layouts/1033/styles/Themable/corev4.css?rev=..."/>

corev4.css IS STILL emitted after everything else for whatever reason, unless you use the After=”corev4.css” property when registering AND there are a few gotchas that you need to be aware of.

Gotcha 1: You’re never sure of the sort order

As of Beta 2, there’s some weirdness when you register multiple style sheets that all require to be after the same CSS file. They are no longer sorted alphabetically but in most cases they end up being last in first out:

<SharePoint:CSSRegistration Name="1.css" After="corev4.css" runat="server" />
<SharePoint:CSSRegistration Name="2.css" After="corev4.css" runat="server" />
<SharePoint:CSSRegistration Name="3.css" After="corev4.css" runat="server" />

I was expecting 1, 2, 3… but instead I get 3, 2, 1…

<link rel="stylesheet" type="text/css" href="/_layouts/1033/styles/Themable/corev4.css?rev=..."/>
<link rel="stylesheet" type="text/css" href="3.css"/>
<link rel="stylesheet" type="text/css" href="2.css"/>
<link rel="stylesheet" type="text/css" href="1.css"/>
Gotcha 2: I need something AFTER another thing…

The other thing to take note on is when you need to define nested After. For example, I need to make sure that the style sheets are emitted in the order 1, 2, 3, 4:

<SharePoint:CSSRegistration Name="1.css" runat="server" />
<SharePoint:CSSRegistration Name="2.css" After="1.css" runat=”server" />
<SharePoint:CSSRegistration Name="3.css" After="2.css" runat="server" />
<SharePoint:CSSRegistration Name="4.css" After="3.css" runat="server" />

We don’t get what we would expect the result to be, instead it comes out as 1, 4, 3, 2:

<link rel="stylesheet" type="text/css" href="1.css"/>
<link rel="stylesheet" type="text/css" href="4.css"/>
<link rel="stylesheet" type="text/css" href="3.css"/>
<link rel="stylesheet" type="text/css" href="2.css"/>

It looks like as a general rule of thumb, you should register the style sheet which comes after another one FIRST. So in order to get 1, 2, 3, 4 we need to define our registration like so:

<SharePoint:CSSRegistration Name="4.css" After="3.css" runat="server" />
<SharePoint:CSSRegistration Name="3.css" After="2.css" runat="server" />
<SharePoint:CSSRegistration Name="2.css" After="1.css" runat="server" />
<SharePoint:CSSRegistration Name="1.css" runat="server" />

EnableCssTheming (boolean)

Remember those “Themable folders” and compile time directives in the CSS files I mentioned about in Part 1? The EnableCssTheming property tells the SharePoint 2010 theming engine to recompile the style sheet using any directives found within the registered CSS file if the file’s location is in one of those “Themable” folders. EnableCssTheming is “true” by default, you have to explicitly set it to “false” if you do not want the registered style sheet to be parsed and re-compiled.

For example:

<SharePoint:CSSRegistration Name="<% $SPUrl:~sitecollection/_layouts/1033/Styles/Themable/foo.css %>" runat="server" />

If we don’t have a theme selected, the HTML emitted will be:

<link rel="stylesheet" type="text/css" href="/_layouts/1033/Styles/Themable/foo.css"/>

But if there’s a theme applied to a site, it will be in one of two locations, where [1234567] and [12345678] are hex values that represent the theme name and CSS file paths. The ctag QueryString parameter is a simple integer counter used for cache invalidation. It increments up every time a web’s theme gets changed.

If the theme was applied through the web UI:

<link rel="stylesheet" type="text/css" href="/[WEB PATH]/_themes/[COUNTER]/foo-[12345678].css?ctag=[COUNTER]"/>

Or, if the theme was set programmatically using the ThmxTheme class and shareGenerate was defined as “true” it will be located here:

<link rel="stylesheet" type="text/css" href="/_catalogs/theme/Themed/[1234567]/foo-[12345678].css?ctag=[COUNTER]"/>

Just to re-iterate, the two three locations where the “Themable” folder can be located are:

  1. In the “14 hive” at %ProgramFiles%\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\[LCID]\STYLES\Themable;

    Where [LCID] is the Locale ID. In North America, the default is “1033” for English (US).

  2. In each web’s Style Library/Themable. These CSS files only affect the specific web and all languages.
  3. In each web’s Style Library/[LANG]/Themable.

    These CSS files only affect the specific web and a specific language. In North America, the default is “en-US

You can place your CSS files inside sub-folders of Themable for neatness but not the other way around… /Style Library/Themable/foo/bar.css will be recompiled by SharePoint 2010′s theming engine while /Style Library/foo/Themable/bar.css will not.

In the next episode…

Whew! We’ve now gone through how to register a style sheet so that it’s compatible with the new SharePoint 2010 theming engine.

My next post will be how to get our custom style sheets onto the out-of-the-box collaboration sites without having to create custom site templates or master pages. We’ll revisit an old friend (or new acquaintance to some), the Delegate Control!

UPDATE: