Thursday, January 29, 2009

More SharePoint Rounded Corners

Late last year I posted an item on rounding the corners of the SharePoint quick launch menu using jQuery. Recently I have completed a project where rounded corners were required on outlined blocks of information rendered in a custom web part, so I thought I'd share with you another way of using the jCorner library.

The requirement was for the web part to render a series of information blocks. The design I adopted was to drive the displayed information blocks from two lists:
  • Heading list - a custom list to define the heading and icon for each block
  • Links list - a custom list with a lookup field (pointing back to the heading list) and a URL field

Each item in the heading list is rendered as a block in the custom web part, and each block contains a heading, an icon and a series of links (coming from the links list). An example of the styling of one of the blocks is shown below:



The HTML markup that produces this box is as follows (not very semantic, unfortunately, and a few too many tags, but I needed it to get it to work within a deadline!) :

<div class='infoblocks'>
  <div class='infoblocksinglecontainer'>
    <div class='infoblockouterforcorner'>
      <div class='infoblock'>
        <div class='infoblockicon'>
          <img alt='Insurance' src='http://.../Umbrella_Icon.jpg' /><div>
          <div class='infoblocktitle'>Insurance</div>
          <div class='infoblocklinks'>
            <a class='infoblocklink' href='http://...' title='Get quotes'>Get quotes< /a>
          </div>
      </div>
    </div>
  </div>
<div>
 
The custom web part retrieves the list items from the headings list, and outputs a "infoblocksinglecontainer" DIV element for each list item, populating the various contained DIVs with the data from the list item.

The round corners are then formed with a combination of CSS and JavaScript calling methods in the jQuery.corner library.

The JavaScript is contained in a JS file deployed to the LAYOUTS folder in the 12 hive and then referenced by a SCRIPT tag output by the web part used on the page. One point to notice about the jQuery selector is the use of a locally-scoped context to improve performance. I picked up this tip from the great article entitled "Improve your jQuery - 25 Excellent Tips" by Jon Hobbs-Smith - if you use jQuery then I thoroughly recommend you have a read of that one!


$(document).ready(function() {
  AddRoundCorners();
});
function AddRoundCorners() {
  var blocksContext = $('.ms-WPBody');
  $('.infoblockouterforcorner', blocksContext).corner('9px');
  $('.infoblock', blocksContext).corner('7px');
}

The CSS is as follows:

.infoblocks {
    width:250px;
}
.infoblocks-twocolumns {
    width:520px;
}
.infoblocksinglecontainer {
    float:left;
    display:inline;
    height:1px; /* Switches on layout for this element, thereby forcing the element to contain the image */
    margin:5px;
    width:1px;
}
.infoblockouterforcorner {
    background-color:#b9d5f1;
    display:inline;
    height:1px; /* Switches on layout for this element, thereby forcing the element to contain the image */
    padding:1px 2px 1px 2px;
}
.infoblock {
    background-color:white;
    border:solid 1px #000;
    display:inline;
    height:1px; /* Switches on layout for this element, thereby forcing the element to contain the image */
    margin:2px -2px 2px 2px;
    padding:2px 2px 2px 2px;
    width:245px;
}
.infoblocktitle {
    height:1px; /* Switches on layout for this element, thereby forcing the element to contain the image */
    color:#06c;
    font-size:10pt;
    font-weight:bold;
    padding-top:3px;
    margin:0 0 0 70px;
}
.infoblockicon {
    display:inline;
    float:left;
    width:65px;
    height:100%;
}
.infoblockicon img{
    vertical-align:middle;
}
.infoblocklinks {
    margin:3px 5px 3px 70px;
    display:block;
}
.infoblocklinks a:link,.infoblocklinks a:visited{
  font-size:8pt;
  font-weight:normal;
}

Note that this CSS assumes that the icon in a block will be 60x60 in size. The CSS handles any number of infoblocklink elements correctly by allowing the block to grow in depth (not width). And to finish, here's another useful behaviour of these blocks; by setting the width of the "infoblocks" class to 520px you can have two columns of blocks rather than one.

Wednesday, January 14, 2009

Missing Buttons and Link on the Add Web Part Page

Beware when tweaking page widths in SharePoint! I was attempting to set the page width to a set size by applying a width style to the ms-main CSS class in a SharePoint site. Easy-peasy, job done.

But wait! When I went to add a web part to a page in this site by clicking on the "Add a Web Part" link at the top of a web part zone, the resulting popup page had no buttons!

First task - look at the source of that page. But which page creates that popup? By running Fiddler and clicking on a link to open that popup, the capture in Fiddler showed the page name to be "webpartgallerypickerpage.aspx" in the LAYOUTS folder in the 12 hive.

Even better it meant I could open that page in Firefox by pasting in the complete URL as recorded by Fiddler. Which in turn meant I could use Firebug to spot from where the classes in the page are sourced.

It turns out that this popup page uses the site master page and stylesheet, causing the main table in the popup window to be set to my fixed width - a width greater that the set width of the popup window. The popup is configured to show no scroll bars - hence the disappearing content!

Luckily the content table in the "webpartgallerypickerpage.aspx" has an ID of "mainTable" which is not applied to the table in other SharePoint pages. Therfore I could apply a special width in CSS to the table appearing in this popup.

Problem solved for that page, now I'd better check whether that table ID is used elsewhere...