Home | Blog | Screencasts | Projects
# Monday, September 29, 2008

I’ve been doing some thinking around how MOSS can be integrated into a large and complex organisation, an organisation that has many disparate applications which act as an information silo. Most developers who are not intimately familar with MOSS will suggestion just using the page viewer web part if the external system is web based. The page viewer web part is basically an IFrame, so MOSS is in effect a window to the external application.

The benefits to this approach are:

  • Low Cost – The external system has already been developed, so it’s not going to cost you anything significant in terms of developer hours. This is assuming that no technical hurdles exist in simply referencing the application via a page viewer. I’ll discuss the authentication issues in the disadvantages section.
  • Quick – Its quick and easy to do, if you plan to redevelop your system to be MOSS aware, this is a good interim measure.

 

The disadvantages are:

  • Systems remain isolated – You still have to maintain that existing system, this might be OK but, it’s likely to be mature and stable.
  • The information is still in a silo – This continues from the last point,MOSS isn’t taking full advantage of the system, you can’t personalise the information from the system, you can’t drop a filter web part on the page and get the exact data your looking for. Sure you might be able to crawl the external site and provide it via the Search Centre, but can your users build a custom list and use this information in a way that makes sense to them?
  • Authentication – How is your authentication handled, MOSS is just providing a window to the external application, your external system has to do all the heavy lifting in terms of authentication and authentication.
  • Inconsistent User Experience – Your external system probably has its own navigation, style and theme that probably isn’t the same as the MOSS implementation that your trying to sell to your users. It has gives off this feeling that its all held together by sticky tape.

I think this approach is fine if you fully understand what your doing, I plan on discussing some of the other approaches in some upcoming posts.

Monday, September 29, 2008 9:22:00 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
Sharepoint | Work
# Saturday, September 27, 2008

I’ve just uploaded the code that I’ve been blogging about recently to CodePlex:

http://www.codeplex.com/JQueryWebParts/

This contains:

This is now the best place to continue development of these tools.

Saturday, September 27, 2008 2:04:00 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
JQuery | Sharepoint
# Thursday, September 25, 2008

I’ve previously posted a demo that made use of a tag suggestion web part, as you type the web part will make an ajax call which will return the tags that match the current input. The user can click on the suggestion tag and it will populate the textbox, multiple tags can be entered into the textbox.

image

 

The most interesting part of this web part is the server side call, which I’ve implemented as a HttpHandler in the Tags.ashx file:

 

public class Handler : IHttpHandler {

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text";

 

I’ve made use of the System.Web.Extensions JavaScriptSerializer to render the string array of tags to JSON:

   1: List<string> tagList = new List<string>();
   2:  
   3: //add all the tags to a collection, JSON serialize the list
   4:  
   5: System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
   6:  
   7: context.Response.Write(serializer.Serialize(tagList.ToArray()));
   8:  

I’ve put this handler in the /_vti_bin/ directory of SharePoint which maps to the ISAPI folder under the 12 hive.

 

I’ve used the same code to generate the tags as I did with the tag cloud web part, so once again the generation of these tags won’t scale to large lists, this is just an example of how to implement a JQuery based Tag Suggestion web part.

 

The source code for this web part can be found here.

Thursday, September 25, 2008 7:39:59 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
code | Sharepoint | Work
# Wednesday, September 24, 2008

Just a quick tip, if your crawling external sources with the MOSS (or Enterprise Search), you might find that your crawl doesn’t finish or hangs, it might be worthwhile checking to see if the site you are crawling has a calendar with links:

 

image

 

You will need to determine the URL and then add a crawl rule to exclude that path, the crawler will see an infinite number of pages (it thinks each date and next link is a separate page).

Wednesday, September 24, 2008 1:17:00 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
MOSS | Search | Sharepoint
# Tuesday, September 23, 2008

I recently had a project where I needed to bind some business objects to a SPGridView in a web part, which on its own is trivial, but I also needed to create the columns for the SPGridView on the fly, since a number of business objects could be rendered in this control.

The main problem was the naming of these columns, if I just bound them directly to the Grid, I would get the ugly naming of my properties (I say it’s ugly, it’s actually pretty awesome if your a developer, but those pesky end users like pretty names).

The sample grid looks like this by default:

 

grid-without

 

So what I came up with isn’t exactly new or innovative, I created a custom attribute called Alias:

 

    public class AliasAttribute : System.Attribute
    {
        protected string[] aliasName;

        public AliasAttribute(params string[] alias)
        {
            this.aliasName = alias;
        }

        public string[] Alias
        {
            get { return aliasName; }
            set { aliasName = value; }
        }
    }

 

This attribute gets applied to each property on your business object with a pretty name:

 

        [Alias("Internet URL")]
        public string InternetAddress
        {
            get { return internetAddress; }
            set { internetAddress = value; }
        }

 

Now the code that performs the binding looks for properties with a custom attribute and pulls out the alias as the HeaderText:

BoundField newBoundField = new BoundField();
newBoundField.HeaderText = Helpers.GetPropertyAlias(field.Trim());
newBoundField.DataField = field.Trim();
grid.Columns.Add(newBoundField);
public static string GetPropertyAlias(string propertyName)
{
    //Change the next line for your business object ..
    PropertyInfo[] propInfos = typeof(BusinessObject).GetProperties();

    foreach (PropertyInfo propInfo in propInfos)
    {
        if (propInfo.Name.ToUpper().Equals(propertyName.ToUpper()))
        {
            object[] attribs = propInfo.GetCustomAttributes(typeof(AliasAttribute), true);
            foreach (object attrib in attribs)
            {
                if (attrib is AliasAttribute)
                {
                    AliasAttribute alias = (AliasAttribute)attrib;
                    //return the alias
                    return alias.Alias[0];
                }
            }
        }
    }

    //if we don't find the custom attribute, just return the same value we passed in
    return propertyName;
}

 

The end result is a nice pretty grid:

 

Grid-With

 

A sample project can be found here.

Tuesday, September 23, 2008 10:20:00 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
code | MOSS | Sharepoint
# Monday, September 22, 2008

If you work in an organisation that has an organisation hierarchy it might be worth setting this up within MOSS, so that when you view a user’s profile you will get the following view:

OrgHeir

 

This is driven off the Manager profile field, it can be setup so that it is driven off either active directory or a custom source such as a SQL database in which case the BDC will need to be used. The Colleague suggestions and notifications make use of the organisation hierarchy as well, so it is worthwhile to set it up.

One thing but, regardless of your localisation settings, the heading ‘Organization Hierarchy’ will be spelt with a ‘z’, so for us Aussie’s we just have to cop the American spelling.

Monday, September 22, 2008 9:33:00 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
Sharepoint | Work
# Thursday, September 18, 2008

The SharePoint Capacity Planning tool can be found here. The executive overview can be found here.

 

The process of creating a model is very simple:

image

 

The UI is wizard based and it asks a number of questions, it's all high level stuff that shouldn't present any issues:

 

image

 

The notes from the overview point out that the tool gives a first approximation, we’ve found that it does a good job recommending hardware, but that the topology of the recommended farms could use some extra thought.

 

For example, if you created a single intranet site with 25000 users with a heavy collaboration usage profile, the tool will recommend 6 servers, 2 of which are SQL Servers. The tool recommends 3 web front ends and an index server.

Now I’m sure this would work fine, but some questions you could ask are:

Could adding a dedicated web front end that isn’t in the load balanced cluster but that is used to service the indexer add to the performance of the site, since the crawler isn’t competing with end users for resources?

The tool doesn't go into the logical architecture of the SharePoint farm, it's purely hardware related.

 

 

image

 

Overall I think the tool is very worthwhile, your planning should definitely include running this tool, but don’t let this tool do all the work, do a little bit of thinking for yourself.

Thursday, September 18, 2008 9:06:12 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
Sharepoint | Planning
# Tuesday, September 16, 2008

If you run your SQL Server on a non standard port you may have experienced issues when installing SharePoint on this server. The standard psconfig utility has a field for the server name, if you give it a comma and then the port your SQL box is running on it will fail. The psconfig wizard doesn't understand the port number format. This isn't just related to SharePoint, I had to use this same trick when I was doing a Great Plains install.

The trick is to create an Alias, first run 'cliconfg', you should be presented with the following UI:

 

image

 

Select the Alias tab, then Add - you should then see the above dialog. Now you just need to enter the server alias, I normally just make this the server name, but your circumstances may be different, then unselect the 'Dynamically determine port' checkbox so you can enter the port number that your SQL Server runs on.

Once the Alias is setup you can refer to the SQL Server by the server alias that you have setup here.

Tuesday, September 16, 2008 9:02:54 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
configuration | Sharepoint | SQL Server
# Monday, September 15, 2008

I found this fantastic post today that I just had to comment on:

 

In a SharePoint entry form the user can select multiple values from a list. This should include an “All” option so in a long list the user can select or de-select all values with one click.

 

The idea is to use JQuery to perform a select 'All' on all the checkboxes in a list.

DannyE posted this JavaScript:

 

$(”.ms-RadioText[title=’All’] :checkbox”).click(function(){
   var otherids = (this.id).substring(0, (this.id).length-2 );
   $(”input[id^=’”+otherids+”‘]”).attr( “checked” , (this.checked)?”checked”:”" );
});

 

It looks for all the items with the ms-RadioText class that also have a Title attribute that equals 'All', it adds a click handler that will then toggle the checked status of the checkbox, its extremely cool, way better than the latest block buster movie ...

 

Anyway, that's all well and good, I'm not adding much value reposting his stuff, so I'd just like to improve on his deployment recommendation.

Instead of adding a script reference to the master page and then inserting a content editor region to paste the JavaScript in, I would suggest using the JQuery Script Manager:

 

So the idea is to use SharePoint Designer to register the control with the JavaScript. Note here to use the ScriptTemplate you'll have to grab my latest script manager control from here.

<cc1:jQueryManager ID="JQueryManager1" runat="server">        
<ScriptTemplate>
$(".ms-RadioText[title='All'] :checkbox").click(function(){
 var otherids = (this.id).substring(0, (this.id).length-2 );
 $("input[id^='"+otherids+"']").attr( "checked" , (this.checked)?"checked":"" );});
</ScriptTemplate>
</cc1:jQueryManager>

This will insert the JQuery Script Manager and declaratively add the JavaScript code to the page. This way you don't need to worry about the script resources or having multiple client side load functions.

How can you not love JQuery after seeing the power of the above code? it's just that awesome!

Monday, September 15, 2008 10:47:30 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
code | JQuery | Sharepoint | Work

I've previously posted a demo that illustrated a tag cloud web part, I've now posted the code.

First let me warn you that the method I've used to get the tag list will not scale, so please disregard the TagBuilder method, you'll need to implement that yourself.

tagcloud

 

I've based this tag cloud control loosely on the tag cloud control from codeproject, I've refactored most of it, but have kept the maths behind generating a weighting.

 

Using the control is pretty simple, you just need to measure the tags and then pass in a collection of CloudItems:

 

//tagList is a dictionary with the tag and count
Dictionary<string, int> tagList = new Dictionary<string, int>();

foreach (string tag in tagList.Keys)
{
    CloudItem cloudItem = new CloudItem();
    cloudItem.Text = tag;
    cloudItem.Weight = tagList[tag];
    cloudItem.Href = "/SearchCenter/Pages/Results.aspx?k=tags:" + tag;
    Items.Add(cloudItem);
}

There are a number of ways to perform the measurement, if you were to count the number of times a tagged resource was accessed, you would end up with a heat map of popular items. Alternatively you could simply count up the number of times a tag has been used (I think this is the most common use, I've done it this way in my demo). In any case the exact implementation details have been left up to you.

Monday, September 15, 2008 9:32:34 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
code | Sharepoint | Work
# Sunday, September 14, 2008

The web part that I'm presenting today is more of a building block, it doesn't do much on its own. It makes use of the JQuery Corners Plugin.

 

image

 

To set the corner types you can modify the Corner Type setting:

 

image

 

The above example will cause the following JavaScript to be output:

 

jQuery('cornerDiv').corner('tr 25px');
 

This web part makes use of the JQuery Script Manager that I've posted about previously.

 

As usual the source can be found here.

 

A screencast of the control in action can also be found here.

 

Sunday, September 14, 2008 9:02:49 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
code | JQuery | Screencast | Sharepoint | Work
# Friday, September 12, 2008

I've just rolled off a project that made use of the Business Data Catalog (BDC), I thought I'd share my experiences.

Firstly I'll give a quick heads up on the BDC, you've probably seen a diagram similar to the following one, basically it shows all the features in MOSS that hang off the BDC:

bdc

 Business Data Web Parts - These are the out of the box list web parts, they provide enough functionality out of the box to at the very least expose the user to the data.

SharePoint Lists - A user can create a column of type 'Business Data' this is very handy for end users, for example they may want to create an Asset register for locations, the locations that are relevant to them maybe exposed via the BDC, this would then save the user the task of maintaining the location list.

 Search - Provide a consistent search experience across all the enterprise data.

 User Profile Importer - Use business data to enhance the profile information you have about your user base, from the example above, you could import the base location into your profile property, then web parts could be built to personalise the information that is displayed to you.

 Custom Solutions - Use the BDC as a data access layer.

 

 

 

 

 

 

 

 

So anyway the application that I did some work on fits into the custom solution box mostly, but with a little bit of thought you can generally make it cross over a number of areas (search, profile import etc) and by doing so create a greater experience for your end users.

For example, our BDC profile import process imported a whole range of properties, one in particular was a business unit code. So by creating a custom metadata property, the people search was able to become a business unit people searcher. We then build some custom web parts that visualised the data on some maps and in some other ways that were relevant to the business, we constructed links that pointed to the people search which made use of the location code, much in the same way that I created tag links in the search demo.

We added the BDC data to the search centre but changed the result links to point to pages with our custom web parts, so now the search centre feeds into the custom visualisations, so no matter where the user comes from, either search or navigation they are going to get sucked into our experience.

 

So my tips are simple:

  • Plan your navigation experience - does search play a part in your experience?, its such a powerful concept to ignore, more people especially the younger generation are very search centric.
  • The BDC is best for read only type data - do you need to push back information? might be other easier ways to go about it.
  • Try to use all the options like web parts, search and profile information to be part of your overall custom solution.
  • Can users use your data in lists? Would it make the end users job easier?
Friday, September 12, 2008 12:37:59 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
Sharepoint | Work
# Wednesday, September 10, 2008

I've posted a couple of articles on JQuery and it's use in SharePoint and also provided some sample web parts. Recently I was putting together these web parts into a single project and I ran into a problem. Each web part was adding the JQuery script resources to the page as if it was the only control on the page, for example the ImageCarousel and the Tag Suggestion web parts both had code that needed to be run on the JQuery load event, this problem would also crop up when multiple instances of the same web part were added to the page. What was outputted to the page was something like:

 

$(document).ready(function(){ 
//function call for webpart1
}
$(document).ready(function(){ 
//function call for webpart2
}
$(document).ready(function(){ 
//function call for webpart2 instance 2
}
 

So I started developing a Script Manager control that I could add to the page that would output the JQuery load event just once, but with all the calls for the page inside this event. As with anything programming related these days, I found what I was looking for at http://codeplex.com/JQueryScriptManager/ I've changed a bit of the implementation, but the basic intent has remained the same. Hopefully I'll be able to get these changes updated to codeplex.

 

Looking at the revised code for the ImageCarousel web part:

 

jQueryManager jqueryManager = null;

protected override void OnInit(EventArgs e)
{
    
    jqueryManager = jQueryManager.GetCurrent(Page);
    if (jqueryManager == null)
    {
        jqueryManager = new jQueryManager();
        Page.Controls.Add(jqueryManager);
    }
    Page.ClientScript.RegisterClientScriptInclude("JCarousel", Page.ClientScript.GetWebResourceUrl(this.GetType(), 
        "JQueryWebParts.js.jquery.jcarousel.pack.js"));
    base.OnLoad(e);
}
 
 

Now inside the PageInit we check for the presence of a JQueryManager script control, if we don't find one, we add it to the controls collection. Just like the ASP.NET Ajax ScriptManager control, there can only be one per page.

 

Now to add code that is globally scoped which also resides in the same script block where our OnLoad event lives:

 

jqueryManager.RegisterScript("-- javascript code without <script> blocks");
//example:
jqueryManager.RegisterScript("var someItems = [5,4,3]");
            
 

To get javascript to run when the page is loaded (this will bundle calls into a single load event):

 

jqueryManager.ReadyFunctions.Add(new RegisterStartFunction("jQuery('#carousel').jcarousel();"));

Use the ReadyFunctions collection which takes a RegisterStartFunction object as a parameter.

 

Internally the JQuery script manager control is performing the following:

 

StringBuilder Start = new StringBuilder();

if (Scripts != null)
{
    foreach (RegisterScriptBlock r in Scripts)
        Start.Append(r.ScriptBlock + Environment.NewLine);
}

if (ReadyFunctions != null)
{
    Start.Append("$(document).ready(function(){");

    foreach (RegisterStartFunction r in ReadyFunctions)
        Start.Append(r.FunctionName + Environment.NewLine);

    Start.Append("});\n\n");
}

Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "JQuery", Start.ToString(), true);

 

The source code can be downloaded here. This includes the updated JQuery Script Manager and the ImageCarousel web part that I've previously posted about.

 

I think this approach will provide a nice platform to continue building web parts based on JQuery Plugins, have fun.

Wednesday, September 10, 2008 10:44:47 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
code | JQuery | Sharepoint | Work
# Tuesday, September 09, 2008

I've blogged previously about the SharePoint solution that I created that modifies the web.config file of a web application to enable the ASP.NET Ajax toolkit.

While I was at Tech-Ed I saw a presentation where the presenter needed to add this exact functionality to his web.config file, so he preceded to create a blank ASP.NET Ajax web project just so he could copy the relevant lines from the web.config that was created.

So that has prompted me to package up my solution and put it up on codeplex.

You can find the solution and source code at: http://www.codeplex.com/SPAjaxEnabler/

 

image

 

I've put together a screen cast of how to use the tool here as well.

Tuesday, September 09, 2008 9:56:06 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [2] - Trackback

Continuing on my theme to bring more JQuery plugins into SharePoint, I present a sample application that makes use of the search features of MOSS and some custom web parts that provide Ajax tag suggestion and a tag cloud web part that works over all SharePoint document libraries with a little configuration of the search engine.

 

Here is a screen cast that demonstrates the concept:

 

Alternatively you can download a higher quality video here (7mb).

 

I will blog more about how I built this application in the coming days and I'll also release the source code to it along with a more detailed description.

If I can convey any message about this application it would be that the search experience is an integral part of the overall application and it can really add some value. For example in the tagging demo I've created a metadata property mapping called Tags, this property is used to crawl the Tag column of the document library. The search cloud web part renders a link to the search centre with the selected tag embedded in the search query, so for no code I've managed to display all the documents that are tagged with the selected tag.

 

The Ajax tag suggestion web part is based on the great Tag Suggestion plugin, it uses a IHttpHandler to iterate over all of the lists to create a collection of matching tags which are returned as JSON, now this approach won't scale, but we can work on that in the future, hopefully we can also leverage the search engine for that as well.

 

For now, hopefully this demo will give you some ideas to employ the search engine inside your MOSS development.

Tuesday, September 09, 2008 8:43:26 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
Screencast | Sharepoint
# Monday, September 08, 2008

One of my favourite features of SQL Server 2008 is the Merge or 'upsert' Statement. Lets say we have an ETL process that prepares a data stage table, without the merge statement you might first delete all the records from the staging table and then insert them all again. If you have large data sets this can become quite time consuming and well frankly it doesn't seem very elegant. Another alternative is to use a cursor to iterate over each record and look for changes, you might also have data that has a timestamp which might help you write a set based operation, both of these approaches are less than ideal.

Well as of SQL 2008 you can use the Merge Statement:

 

Lets say you have a simple table like:

 

CREATE TABLE People
(
  ID       INT PRIMARY KEY,
  Name     Varchar(50) NOT NULL,
  Position Varchar(50) NOT NULL,
  Age      INT NOT NULL
);

 

Assuming our StagedPeople table is the same structure the merge statement would look like:

 

MERGE INTO People
USING StagedPeople
 ON People.ID = StagedPeople.ID
WHEN MATCHED THEN
-- if we find a match, then perform an update  
UPDATE SET
  Age = StagedPeople.Age,
  Name = StagedPeople.Name,
  Position = StagedPeople.Position
WHEN NOT MATCHED THEN
 -- if we don't find a match, then insert a new record
 INSERT (ID, Name, Position, Age)
 VALUES (StagedPeople.keycol, StagedPeople.Name, StagedPeople.Position, StagedPeople.Age)
WHEN SOURCE NOT MATCHED THEN
 -- we could delete the record, since it's not found in the Staged table
DELETE;
OUTPUT $Action

 

 

The $action variable returns a varchar(20) of the operation that has taken place,  i.e. 'INSERT', 'UPDATE', 'DELETE'

The operations and full reference can be found here.

It seems like a pretty fundamental operation, glad it only took till 2008 for us to have it :)

Monday, September 08, 2008 11:01:17 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
code | SQL Server | Work
# Saturday, September 06, 2008

This week I picked up this simple tip for spatial enabled applications. Just say you have an existing database that has the latitude and longitude stored as separate columns such as a Latitude and Longitude as you would like to SQLSpatialmake these columns available so that spatial operations can be performed on them.

Create a view on the table with the Lat, Long as parameters to the Geography::Point function which creates a spatial point.

 

 

Your table might look like:

 

image

 

The following SQL will do the trick to convert the points to spatial column:

 

CREATE VIEW SpatialView
AS

-- Create a view over a table without a spatial column
SELECT Name, geography::Point(Latitude, Longitude, 4326) as Location FROM UnSpatialTable

So now you have a spatial column that you can include in your spatial queries such as, finding the distance between points:

 

DECLARE @location GEOGRAPHY

SELECT @Location = Location from SpatialView where name = 'test'


SELECT @Location.STDistance(Location) as DistanceToOther from SpatialView

 

Creating a buffer around a point:

 

SELECT Location.STBuffer(20) as BufferedLocation from SpatialView where Name = 'test'

 

This approach might be useful if you collecting data on a mobile device running the compact edition of SQL which doesn't have any spatial features. You can collect your data as lat,long values and then do the spatial manipulation via the view. Don't forget to think about spatial indexes!

Saturday, September 06, 2008 6:34:46 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
code | SQL Server
# Thursday, September 04, 2008

Recently I posted about using JQuery in SharePoint web parts in this post I wrapped up the JCarousel plugin. Instead of requiring the JCarousel.js file to be included into the master page, I instead made the web part inject the HTML to cause the JavaScript file to be loaded.

The first step was to include the packed version of jquery.jcarousel.pack.js into my project:

 

image

 

Notice the Embedded Resource setting for the build action.

 

Now if we add the following code to our assembly.cs file:

 

[assembly: System.Web.UI.WebResource("SPImageCarousel.jquery.jcarousel.pack.js", "text/javascript")]

 

The above line now makes our embedded resource available for use in our web part which is done by the following code:

 

protected override void OnInit(EventArgs e)
{
    Page.ClientScript.RegisterClientScriptInclude("JCarousel", Page.ClientScript.GetWebResourceUrl(this.GetType(), "SPImageCarousel.jquery.jcarousel.pack.js"));
    base.OnLoad(e);
}

 

This code will ensure that the script is only added to the page once since the key "JCarousel" is the first parameter, remember that more than one web part can be added to a page at the same time, so we need to consider this as we develop our web parts. OnInit is the perfect event to call RegisterClientScriptInclude it's nice and early in the page lifecycle.

 

So hopefully you'll find this a nice and easy way to include your JavaScript resources, it does have the disadvantage of requiring a recompile to include a later version of the JavaScript file, so your mileage may vary if this is a concern.

 

Better still if your using .NET 3.5 Service Pack 1, you could make use of the CompsiteScript element of the script manager to combine the javascript files so the browser makes fewer calls to the server.

Thursday, September 04, 2008 11:52:17 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
code | JQuery | Sharepoint | Work
# Tuesday, September 02, 2008

I've mentioned before that I'm partial to JQuery, I consider it to be the Jessica Alba of JavaScript.

With all the work that has been done creating awesome JQuery based UI components, it seems like such a shame that us SharePoint developers aren't making more use of them.

So I present to you my first JQuery based web part, the Image Carousel:

image

Based on JCarousel, this web part presents the contents of a picture library in a carousel that can be scrolled by the navigation buttons.

 

The web part simply imports the jcarousel.js file, the web part then injects a JavaScript array of the images that reside in the selected picture library along with some javascript that initialises the carousel. The code to find the SharePoint picture library list is trivial:

 

SPSite site = SPContext.GetContext(HttpContext.Current).Site;
SPWeb web = site.OpenWeb();

foreach (SPList list in web.Lists)
{
    if (list.BaseTemplate == SPListTemplateType.PictureLibrary)
    {
        //grab the images from this list
        jsArray.Append(ProcessList(list));
    }
}

 

The web part makes use of custom toolpart for the selection of the picture list:

 

image

 

I think this provides a good template and starting point to start putting more of those JQuery plugins to use inside SharePoint

 

A small screencast of the control in action can be found here.

 

The end effect is some exceptional functionality for little development effort, which is really what JQuery is all about.

Some of the things that you need to think about when integrating:

  • Make sure that the injected div tag that will be used at the host has a unique id, remember that more than one webpart can be added to a page, if you hard code the html to have specific ID's, you will run into problems.
  • Make sure the JavaScript gets injected into the right part of the page, also just like the above point, ensure that each injected bits of code have a unique name, so that multiple webparts on the same page don't cause problems.
  • Use the packed version of the component, SharePoint is bloated enough already, use the smallest possible footprint you can.

 

The source code can be found here.

Tuesday, September 02, 2008 1:23:35 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
code | JQuery | Sharepoint | Work
Statistics
Total Posts: 134
This Year: 0
This Month: 0
This Week: 0
Comments: 20