Wednesday, November 12, 2008

jQuery in SharePoint Example - Rounded Corners

A recent project involved the branding of MOSS to incorporate custom design elements as supplied in a PhotoShop page mockup. One of these design requirements was rounding the external corners of the quick launch menu.

Hmmm, what to do. There are plenty of techniques discussed on the web for achieving this outcome, but often the basis for these techniques is to start with clean, web-standards compliant HTML. That's certainly not what SharePoint provides - I needed to work with the HTML that is created by the mixture of master pages and user controls, and did not want to override standard elements for this styling exercise. One aim was to minimize the changes, if any, to the master page.

Many of the rounded corner approaches use JavaScript. And I was, at the time of this project, starting to see the potential of jQuery combined with SharePoint. So a little more research located a neat way forward - the jQuery.Round plug-in.

After a few minutes (hours?) experimentation I derived the jQuery statements to apply rounded corners to the menu. This of course also required adding references to the jQuery and jQuery.round libraries in the master page - so it was necessary after all to change that page!

The statements were:

function AddQuickLaunchCorners()
{
    $(".ms-quicklaunchouter").corner("10px");
    $("div.ms-quickLaunch h3.ms-standardheader span div.ms-quicklaunchheader").css("background-color", "#c1ecff").corner("top 7px");
    $("table.ms-recyclebin:last td").corner("bottom 7px");
}

Note the assumption in the last JavaScript statement that the recycle bin will be the bottom row in the quick launch menu.

These statements, together with modifications to some of the other CSS styles, resulted in the following look for the quick launch menu:




But then I came across a very annoying behaviour. Imagine the following scenario:

  • I view a page containing this menu in one tab in IE7
  • Then I open another tab in IE7 and navigate around any page in that second tab

Not an unusual behaviour really. But on returning to the first tab displaying the SharePoint page with menu, this is what the menu then looked like:


Yeuch! More "minutes" of investigation lead to the inclusion of the following code in the JavaScript file applying the dynamic styling to the page:

window.onfocus = ReapplyQuickLaunchCorners;

function ReapplyQuickLaunchCorners()
{
    RemoveQuickLaunchCorners();
    AddQuickLaunchCorners();
}

function RemoveQuickLaunchCorners()
{
    $("div.ms-quicklaunchouter>div:not(.ms-quickLaunch)").remove();
    $("div.ms-quickLaunch h3.ms-standardheader span div.ms-quicklaunchheader>div").remove();
    $("table.ms-recyclebin:last td>div").remove();
}

Not a nice solution (OK, it's a hack!) but it works and I ran out of time.

So where am I leading with this post - well, just to illustrate the great things you can do with jQuery to mould SharePoint. Sometime I'll blog about using jQuery for AJAX calls to the MOSS profile search web services, but that's for another time.....

5 comments:

rwhitworth said...

Great article, I was trying to work with your rounded corners for the quick launch navigation. Where are you storing your jquery scripts in sharepoint. Also, I just want to test this on one page by putting it in a content editor web part, what would be the syntax for calling this script (adding a reference, etc)

whats.to.learn.today said...

The cleanest way to incorporate JQuery is to use a delegate control, as explained by Jan Tielens in his post 'Integrating SharePoint 2007 and jQuery'. The third option in that post explains the concept very clearly.

I tend to write the bulk of the JavaScript that is using jQuery in a JS file, deploying that JS file with a SharePoint solution that also includes the delegate control insertion.

In the case of these rounded corners which need to be applied on every page in the site, including a $(document).ready() call inside a JS file, and then referencing the JS in a SCRIPT tag in the ASCX in the delegate control achieves the aim. It results in the JavaScript function being called in every page based on the masterpage.

Praveen said...

Good article. I will try to implement this. I written a small article on integrating JQuery in SharePoint, which may helps people who are learning SharePoint and integrate JQuery.
http://praveenbattula.blogspot.com/2009/05/jquery-integration-in-sharepoint.html

-Praveen.

d3vlabs said...

Does anyone have this working with WSS 3.0? I've tried by adding Content Editor Web Part with the following code:


http://pastebin.com/f58689592

Hank said...

Hi guys,

I have problem to implement the solution in SP 2010.

I have the following



$(document).ready(function() {
AddQuickLaunchCorners();
});

function AddQuickLaunchCorners()

{

$(".ms-quicklaunchouter").corner("10px");

$("div.ms-quickLaunch h3.ms-standardheader span div.ms-quicklaunchheader").css("background-color", "#c1ecff").corner("top 7px");

$("table.ms-recyclebin:last td").corner("bottom 7px");

}

is there a way to know if the code in jquery.corner.js is executed?

Thanks!!