Accessing the web property bag with JavaScript

A useful, but largely unknown, feature in SharePoint is the Property Bag. The Property bag is place where site-wide settings can be kept. It is implemented as a collection of name/value pairs. The reason it is largely unknown is that it is not visible from the user interface, nor can it be seen using SharePoint Designer. It can only be accessed by developers, or by administrators using a tool like SharePoint Manager.

In SharePoint 2007, using the Property Bag in an application meant writing C# code, deployed to the server. SharePoint 2010 gives us a couple of options to access the property bag without managed code on the server. These are sandbox solutions and the Client Object Model.

Accessing the Property Bag using the JavaScript Client Object Model is a straightforward process, as the API has this ability built in:

 //wait until client object model dependencies are loaded before executing our code
ExecuteOrDelayUntilScriptLoaded(getWebProperties, "sp.js");

var webProperties;

function getWebProperties() {
    var clientContext = new SP.ClientContext.get_current();
    webProperties = clientContext.get_web().get_allProperties();
    clientContext.load(webProperties);
    clientContext.executeQueryAsync(Function.createDelegate(this, this.getWebPropertiesSucceeded), Function.createDelegate(this, this.onQueryFailed));
}

function getWebPropertiesSucceeded() {

          //debugger; //use this to force a break here
	//returns an object with all properties.  
          //Use the quick watch to expand this out to see all of them.
	var allProps = webProperties.get_fieldValues();

	var customProp = "";

         //make sure the property is there before using it.
	if(webProperties.get_fieldValues().CustomSite_Version != undefined)
	{
		var customProp = webProperties.get_fieldValues().CustomSite_Version;
	}
	alert(customProp);
}

function onQueryFailed(args, sender)
{
     //handle errors here
}

I have not discovered a way to iterate through the web properties like you can with a .Net object, but you can view all of the web properties using the debugger by opening a watch on the webProperties.get_fieldValues() expression:

Here we can see all the site’s properties, including a custom web property I have added: CustomSite_Version.

To fetch a particular property in code, first ensure it is not undefined, then call it much like a .Net-style property:

var customProp = webProperties.get_fieldValues().CustomSite_Version;
Advertisements

Adding Rounded Corners to Top Navigation

Update: This post contains advice I don’t recommend anymore. Changing the meta tag value to “IE=9” is known to cause some problems with SharePoint 2010. For starters, I’ve noticed that trying to save a list item with a multi-line text field will result in an error (something about an xsd namespace not defined). I have also heard it causes some issues with People Pickers. /Update

Recently I had a requirement to create a custom look and feel on a SharePoint master page. Among the requirements was to implement rounded corners in the Top Navigation bar. Not being a branding guy I really didn’t know how I was going to implement this. I figured the solution would involve images and lots of meticulous tweaking of the DOM to find a combination that worked.

When I asked about the minumum browser version and was told it would be IE9 I felt there had to be a better way to do this using HTML5 and CSS3.

Turns out rounded corners are an out-of-the-box feature in IE9 and all the latest browsers. Implementing them in SharePoint was actually a simple proposition, once a couple of hurdles are cleared.

Implementing this solution involved making some changes to the site’s master page – a couple of CSS classes and a meta tag in the page’s head. The first step was to find the DOM representation of the top navigation bar. In my environment it looked something like this:

The top nav elements are composed of an unordered list, and each list item has a class of “static”. Inside each list item is an anchor, also with a class of “static”. In addition, the currently selected nav item has the extra class “selected”. These are the DOM elements we have to work with.

In all I want to define three CSS classes: one for the default look, one for the selected item, and a third to capture the “hover” event.

To implement the rounded corners we’ll use the new CSS property “border-radius”. There are quite a few options to specify with this property, but I’m going to use the simplest syntax, which just specifies a number to use with all four corners. I also needed to add a bit of a margin on the right to keep some separation between the nav elements. I also had an annoying light blue border around the anchor, so I modified that property as well. I also discovered a CSS3 class for adding drop shadows to the nav elements(why? Because I can!). When all was said and done the default style looks like this:

.s4-tn ul li.static a.static
{
	border-color: transparent;
	background-color: #ccccee;
	border-radius: 10px;
	margin-right:10px;	
	box-shadow: 6px 1px 5px rgba(150, 150, 150, 0.5);
}

To add the selected and hover versions of the style, we’ll use all the properties in the default style except for “background-color”. So our new styles will simply replace this one property, like this:

.s4-tn ul li.static a.static.selected
{
	background-color: #8888cc;		
}

.s4-tn ul li.static a.static:hover
{
	background-color: #dddd99;
}	

When we save and open the site, we’ll notice the rounded corners if we use Chrome or Firefox, but not in IE9. To make this work in IE9, we have to modify this meta tag in the master page:

<meta http-equiv="X-UA-Compatible" content="IE=8"/>

…and change the value to “IE=9”.

Now we have round-cornered navigation elements, as well as custom styles for selected and hover scenarios.

Note…The Publishing Infrastructure feature alters the way the DOM is constructed for the Top Navigation. I tested this against both versions, but if you find any anomalies, let me know.