Aidan Garnish

Collaboration Not Competition

CSS3 - rounded corners and drop shadow fun!

As IE9 is going to provide support for CSS3 I thought that it was about time I took a quick look at some of what is going to be available.

The following html and css demonstrates just how easy it is to produce rounded corners, drop shadows and gradient borders without an image file in sight -brilliant!

HTML File

<html>
<head>
<link rel="stylesheet" href="css3.css" media="screen" />   
</head>
<body>
<div class="box"></div>
<br/><br/><br/>
<div class="box2"></div>
<br/><br/><br/>
<div class="box3"></div>
<br/><br/><br/>
<div class="box4"></div>
<br/><br/><br/>
<div class="box5"></div>
</body>
</html>

CSS File

body
{
padding:20px 20px 20px 20px;
}

.box
{
-moz-border-radius-bottomleft:50px;
-moz-border-radius-bottomright:200px;
border:orange 20px double;
-moz-border-radius-topleft:100px;
-moz-border-radius-topright:66.66px;
padding:24px 24px 24px 24px;
width:320px;
height:50px;
}

.box2
{
-moz-border-radius: 1.6em;
border-radius: 1.6em;
border:black solid 1px;
height:100px;
-moz-box-shadow:-10px 10px 20px gray;
width:400px;
}

.box3
{
-moz-box-shadow:10px 10px 20px red;
-moz-border-radius: 1.6em;
border-radius: 1.6em;
border:red solid 1px;
height:100px;
width:400px;
}

.box4
{

background-color: #DAE8EC;
-moz-border-radius-topleft: 10px;
-moz-border-radius-bottomright: 10px;
border: 2px solid #B8CB99;
padding: 10px;
width:380px;
height:70px;
}

.box5
{
border: 8px solid #000;
-moz-border-bottom-colors: #555 #666 #777 #888 #999 #aaa #bbb #ccc;
-moz-border-top-colors: #555 #666 #777 #888 #999 #aaa #bbb #ccc;
-moz-border-left-colors: #555 #666 #777 #888 #999 #aaa #bbb #ccc;
-moz-border-right-colors: #555 #666 #777 #888 #999 #aaa #bbb #ccc;
padding: 5px 5px 5px 15px;
height:100px;
width:370px;
}

If you save these files and open them with Firefox 3.5 or above you should see something similar to:

 

Twitter SharePoint web part

** Update June 2010 - new Twitter web part using OAuth rather than Basic Auth **

I thought I would have a go at creating a web part to display a Twitter public timeline within SharePoint. The reason for creating this web part is so that it can be used by project teams that are spread over several offices/countries to stay in touch and feel more connected without having to invest a lot of time emailing each other or talking on the phone. Twitter is ideal for this kind of light weight communication as it restricts the user to sending short, to the point messages.

Before starting I had a quick look on the web to see if I was reinventing the wheel. Michael Gannotti suggests this solution using javascript and the CEWP but I wanted something that we would have a little more control over in terms of html markup and branding and that wasn't limited to the CEWP being available. I also wanted to have the possibility of extending the web part to include other functionality in the future such as not just being able to display tweets but to also send them.

The web part is configurable using two custom attributes - username and password. This allows you to display any users public timeline assuming you have the password. To set it up for use with a project team public timeline you should create a Twitter account for the project and then follow the members of the team to see a timeline that displays tweets from each of the members. 

At the bottom of this post there are links to the .wsp file which can be deployed to SharePoint using stsadm.exe and a .css file so that you can see how I chose to style the web part but obviously you could brand it any way you want.

**Update by request - more detail on deploying solutions

My solution uses Twitterlib.dll which is an open source .Net wrapper for the Twitter API and was created by the developers at Witty. This is a link to the Witty project on Google code. 

Download the wsp for the Twitter web part: TwitterPublicTimeline.wsp (24 kb)

For a styling suggestion try this css: twitter.css (302.00 bytes)

Change class on an HTML element using javascript

A basic javascript function to toggle an elements class property.

<script language="javascript">
 function ToggleClass(id, class1, class2)
 {
  try
  {
   if(document.getElementById(id).className == class1)
   {
    document.getElementById(id).className = class2;
   }
   else
   {
    document.getElementById(id).className = class1;
   }
  }

  catch(e)
  {
     window.alert(e.description);
   }
 }

</script>

An example of how this can be used to hide and show sections in a page:

<html>
<style>
.Row
{
   float:left;
   clear:left;
}

.AddressRow
{
   float:left;
   clear:left;
   padding:0px 0px 5px 0px;
}

.AddressRowNoDisplay
{
   float:left;
   clear:left;
   padding:0px 0px 5px 0px;
   Display:None;
}

.Field
{
   float:left;
   padding-right:10px;
}

</style>

<head>

<script language="javascript">


 function ToggleClass(id, class1, class2)
 {
  try
  {
   if(document.getElementById(id).className == class1)
   {
    document.getElementById(id).className = class2;
   }
   else
   {
    document.getElementById(id).className = class1;
   }
  }

  catch(e)
  {
     window.alert(e.description);
   }
 }

</script></head>
<body>

<div class="Row">
<div class="Field">Aidan Garnish </div>
<div class="Field">0191 4562736</div>
<div class="Field"><a href="javascript:ToggleClass('Address1', 'AddressRow', 'AddressRowNoDisplay')">Show/Hide detail</a>
</div>
<div id="Address1" class="AddressRowNoDisplay">
55 Jumble Avenue, Googenheim, GH1 5SD
</div>

<div class="Row">
<div class="Field">Brian Cosby </div>
<div class="Field">0192 3568736</div>
<div class="Field"><a href="javascript:ToggleClass('Address2', 'AddressRow', 'AddressRowNoDisplay')">Show/Hide detail</a>
</div>
<div id="Address2" class="AddressRowNoDisplay">
37 Ungerton Road, Googenheim, GH1 7WS
</div>

<body>
</html>

Creating XHTML compliant ASP.Net server controls

ASP.Net is great but many of the controls use table tags when they render. I am currently in the process of developing some Internet sites using MOSS 2007 which need to meet accessibility guidelines so these controls, in their out of the box state, are no use to me. We have tried applying the CSS adapters that get rid of the tables but this also had the effect of removing tables from the site settings screens making them difficult to use.

The solution we are going for is to create new controls that inherit from the base control. The new control then overrides the render event to remove the non-compliant tags and replaces them with compliant ones.

We are also using this method to add script to the master pages which removes table tags from web part zones etc.

DISCLAIMER - I have created a non-tabular control for the SPGridView. You could argue that the SPGridView presents tabular data so does not need any changes to the rendered HTML, you would probably be right but this example shows what can be done. :-)

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web.UI;
using System.Text.RegularExpressions;
using System.IO;

namespace XHTMLCompliantMOSSControls
{
    public class CompliantSPGridView : SPGridView
    {
        protected override void RenderContents(HtmlTextWriter output)
        {
            //get the rendered HTML
            StringBuilder sb = new StringBuilder();
            StringWriter sw = new StringWriter(sb);
            HtmlTextWriter hw = new HtmlTextWriter(sw);

            base.RenderContents(hw);
 
            //remove tables
            string str = sb.ToString();
          
            str = Regex.Replace(str, "<table[^>]*>", "<div class=\"mainSPGridView\">");
            str = Regex.Replace(str, "<tr>", "<div class=\"normalSPGridView\">");
            str = Regex.Replace(str, "<tr class=\"ms-alternating\">", "<div class=\"alternatingSPGridView\">");
            str = Regex.Replace(str, "</tr>", "</div>");
            str = Regex.Replace(str, "<td[^>]*>", "<div class=\"itemSPGridView\">");
            str = Regex.Replace(str, "</td>", "</div>");
            str = Regex.Replace(str, "<tr class=\"ms-viewheadertr\">", "<div class=\"headerSPGridView\">");
            str = Regex.Replace(str, "<th class=\"ms-vh2-nofilter ms-vh2-gridview\" scope=\"col\">", "<div class=\"itemSPGridView\">");
            str = Regex.Replace(str, "</th>", "</div>");
          
            output.Write(str);
        }
    }
}

If you then apply a bit of CSS using the classes that have been added it is possible to get it looking just like the tabular SPGridView.

This approach could be used with any server control to make it compliant with XHTML.

MOSS 2007 - CSS Crackers!

There is a  nasty gotcha in MOSS SharePoint CSS registration. It doesn't matter what order you register your css files, they will be rendered in the html in alphabetical order! Not very helpful...

Overriding core.css in MOSS 2007

So you are trying to use a custom css in your master page but the nice shiny font you are trying to display isn't showing up! The reason for this is that core.css will be called after your custom css file leaving your text displaying as verdana or arial.

The fix for this is to declare your custom css file in the master page settings of your site - (Site Actions/Site Settings/Master Page). The result is that your custom css will be applied after core.css and the font you specified is used.

For more interesting scenarios in which a bit of tweaking is required to get the right css file to be applied see http://www.heathersolomon.com/blog/archive/2006/10/27/sp07cssoptions.aspx