Lars Nielsen's Discoveries

May 26, 2011

Equal height columns using div and CSS

Filed under: Branding,Good Practice,SharePoint — Lars Nielsen @ 7:59 pm
Tags: ,

Finally now SharePoint is using DIV elements in the v4.master page, rather than using tables for layout as SharePoint 2007 did (and which is not xhtml compatible and has a load of other problems as well).

Using DIV’s rather than tables for layout is a great idea, but some things become more difficult to do with CSS and DIV’s. One of the more common issue is now to get a screen layout with two columns of equal height.  With tables in HTML it was easy – just create two cells in a row and they will be sized to be the same height by the browser.  DIV’s however are given a height dynamically to contain their content so it becomes quite difficult to create even a simple layout with 2 columns (DIV’s) of the same height.

There are plenty of possible  solutions to this, and this post lists some of them.  In my work recently I was working on some CSS that seemed to be following this technique.  I guess it works, but it’s not exactly straightforward, and I was having trouble getting it stripped down to just two columns and working in a fixed width design rather than flexible width.  So in the end I found this simpler alternative and used that as the basis for my CSS.  It works fine in all the main browsers (although there is a problem with IE 6 and 7 – see below) and doesn’t involve the complexity of defining widths and relative positions in several places.  It uses a similar trick, in making the background of the whole wrapper to be whatever you want for the background of the left hand column, and the other columns sit to the right and cover the background with another background.  In this, I managed to create a layout with 2 columns of equal height with quite simple and basic CSS.

Here’s the code for a page to show the technique:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>div test</title>
<style type="text/css">
div.Main {
  width:980px;
  background:red;
  color:white;
  border:none;
  margin:0 auto;
}

div.Left {
   width:165px;
   float:left;
}

div.Middle_Right {
   margin-left:165px;
   border-left:none;
}

div.Right {
   margin-left:0px;
   background:blue;
   border:none;
}

div.Clear {
   clear:both;
}
</style>
</head>
<body>
<div class="Main">
    <!-- Left -->
    <div class="Left">
    	<div id="New div">
    	Left<br />Left<br />Left<br />Left<br />Left<br />Left<br />Left<br />Left<br />
    	Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left
 		</div>
    </div> <!-- /Left -->
    <!-- Middle + Right -->
    <div class="Middle_Right">
        <!-- Right -->
        <div class="Right">
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
		Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
	        <div class="Clear">
	        </div>
        </div> <!-- /Right -->
    </div> <!-- /Middle + Right -->
</div> <!-- /Main -->
</body>
</html>

Update

This technique seems to cause problems with IE6 and IE7 in that the colour of the left hand DIV bleeds over into the right hand div at the bottom if the left hand div is higher than the right hand one, and you resize the browser to be less high than the DIV’s themselves. Other browsers seem to be OK. In the case of SharePoint 2010, it doesn’t officially support IE 6 anyway, and nearly everyone who uses IE 7 has upgraded to IE 8 at least, so in practice this may not be too much of a limitation.

March 6, 2011

SharePoint Built In Fields

Filed under: Development,Good Practice,SharePoint — Lars Nielsen @ 6:19 pm
Tags: ,

Instead of using hard-coded strings for the names of the built in fields in SharePoint, you can use the object model to get the GUID of the field.  So instead of doing this:


SPListItem i;

// Get a list item into i

string moderationStatus = i["_ModerationStatus"] ;

You can do this:


SPListItem i;

// Get a list item into i

string moderationStatus = i[SPBuiltInFieldId._ModerationStatus] ;

This will get you a reference to the correct field using its GUID rather than its name.  The full list of built in fields is in the SPBuiltInFieldId documentation.  The SharePoint Kings blog also has an explanation of this class and also SPBuiltInContentTypeId.  There are a couple of problems with the fields to watch out for:

  • If you want to get the account who created an item, use the field SPBuiltInFieldId.Author not SPBuiltInFields.Created_x0020_By
  • If you want to get the account that last modified an item, use SPBuiltInFieldId.Editor not SPBuiltInFieldId.Modified_x0020_By

I’m not sure when SPBuiltInFields.Created_x0020_By would work but in my experience on a regular list, it’s always empty so I used SPBuiltInFieldId.Author instead.  So for example to get the account that created a list item as an SPUser object (so you can get the name or their email address) use code like this:


SPListItem item;

// Set the value of item somehow

SPFieldUser createdByField = (SPFieldUser)item.Fields[SPBuiltInFieldId.Author];

SPFieldUserValue createdByUserValue = (SPFieldUserValue) createdByField.GetFieldValue(item[SPBuiltInFieldId.Author].ToString());

SPUser user = createdByUserValue.User;

September 19, 2010

Is SharePoint 2010 really accessible?

Filed under: Good Practice,SharePoint — Lars Nielsen @ 12:07 pm
Tags: ,

Having read all the articles about how much effort has been put into SharePoint 2010 accessibility, I decided to have a better look myself.

I created a publishing site in SharePoint 2010 and then created a single article page and added a few words of content into the content placeholder.  I tried using the v4.master page.  Using Total Validator I validated the source code of the page (just pasted it into their cut-and-paste validator).   Here’s the result:

Starting page: Uploaded Page

Total errors found: 203 (Parsing: 6, HTML: 183, WCAG v2 A: 14)

(X)HTML used for this page: XHTML 1.0 Strict

Most of the errors were for XHTML compliance but right at the start of the page HTML, there’s the line:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

There are all kinds of XHTML failures in the source code.  I did notice for example quite a few ie:menuitem tags.  I guess they’d not be rendered in another browser, so it might be worth testing XHTML compliance from a browser other than IE.  Having said that, my attempt to use SharePoint 2010 with Opera (which has a great tools for checking accessibility) proved short-lived.  In Opera, the Site Actions menu wouldn’t drop down properly, presumably because of some Javascript incompatibility, so that pretty much rules it out as a viable browser for SharePoint.

Anyway, as for accessibility which is what I was really interested in, there were also a number of WCAG level ‘A’ errors.  There were a few cases of the fgimg.png image without an ALT tag, the search textbox has a ALT attribute but it shouldn’t do (at least according to the validator), and some anchor tags like this:

<a href="#" style="display:none"></a>

An invisible tag with no link text: yuck!

I also briefly had a look at the HTML that what renders from a web part pages: it’s still using tables for layout, against WCAG 1.0 guidelines.  I also tried varying the master page and I did get different results with nightandday.master rather than v4.master, but there were still plenty of problems.    So whilst things are certainly better than SharePoint 2007, it seems like you can’t get fully real-world accessible pages straight out of the box.  Unless, of course, anyone knows any different – I’d like to be proved wrong!

June 15, 2010

Performance code tips for SharePoint

Filed under: Development,Good Practice,SharePoint — Lars Nielsen @ 7:02 pm
Tags: ,

I thought I’d collect together some tips on how to improve the performance of code in SharePoint and how to avoid some traps which might cause code to run slowly or break in production systems.

1) Accessing Lists

You need to be careful when working with SharePoint lists – often code that might work fine on a dev machine with small lists won’t work so well when you deploy it to a production environment where the lists are much bigger.  In particular, watch out for the right way and wrong way to loop through the items in a list.  Never loop through the SPList.Items object, because SharePoint will query the database each time within the loop.  Instead set a new SPListItemCollection variable to point to SPList.Items and then loop through the new variable.   This will cut it down to just one query to get all the items in one go, rather than one at a time.

Even better is to the GetList() method of the SPWeb to get a reference to the list.  This is less demanding in terms of database access and also you can test if the list is there by trapping a FileNotFoundException which is thrown by the method if the list does not exist.  Use code like this to get a reference to the list:


string listName = "My List"

try
{
string s = _currentSPContext.Site.ServerRelativeUrl; // Site collection root Url
if (!string.IsNullOrEmpty(s))
{
          string siteCollectionRelativeUrl = s.TrimEnd('/');
SPList MyList = _currentSPContext.Site.RootWeb.GetList(siteCollectionRelativeUrl + "/Lists/" + listName);
.....
}
}

catch (FileNotFoundException)
{
    .....
}

2) Counting items in a list

In the same way, it’s better to use SPList.ItemCount rather than SPList.Items.Count, again to prevent multiple queries on the database.  Although the results do differ if you have folders in the list – SPList.ItemCount counts a folder as one item, whereas SPList.Items.Count ignores the folders.

Here are a load more great best practice advice

[Update: 28/3/2012]

I just found this great post with lots of detail and advice on good and bad ways to work with lists in the object model.  It’s quite old now but I think it’s still valid for SharePoint 2010

Blog at WordPress.com.