Fear and Loathing

Gonzo blogging from the Annie Leibovitz of the software development world.

  • Hiding the New Toolbar Button in SharePoint with jQuery

    Another quick little fun thing today. Many times you might want (need) to hide the “New” button on a list toolbar. You know the one I mean?

    image

    Why would you want to do such a thing? For example on a project I’m building I actually call the NewForm.aspx page with a querystring because I want to pre-populate my form with some vales. As such, I don’t want users to create new items in a list without these references and since they have to come from another list I’m left with the problem of trying to restrict them from creating new items but still offer them the ability to use the features of the list like alerts, exporting to spreadsheets, etc. Yes, the “New” button isn’t available for readers of a list but for contributors it is and for admins you can’t just turn some of this stuff off easily.

    If you do some Googling you’ll find some ways to do it. Some want you to modify the list schema, others have C# code to hide it, an others even want you to crack open SharePoint designer and butcher your AllItems.aspx page. Bazooka to kill a mosquito solution IMHO.

    Here’s another simple way to do it with your Swiss Army knife, jQuery.

    Ingredients

    • jQuery (either installed on your server or remotely and referenced in a master page or via a Content Editor Web Part)
    • 1 Content Editor Web Part
    • 1 lines of jQuery/JavaScript

    First you’ll need to have a list to modify. In this case I’ll use a Task list, but any list or library will do. Next go to the view page for the list that you want to do this on.

    Click on Edit Page in the Actions menu and you’ll be allowed to add and edit web parts on the view page. This was a feature Microsoft smartly added and is fully supported. Now we can start adding our jQuery love.

    Click on Add Web Part, browse for the CEWP and drop it on the page. Make sure you place it below the list form and also mark it as “Hidden” in the Layout options. This keeps the page looking as clean as it was originally.

    If you inspect the HTML of any toolbar, it’s basically composed of something like this:

    <table class=”ms-menutoolbar”>
    <tr>
    <td class=”ms-toolbar”>[toolbar item]</td>
    <td class=”ms-separator”>[separator image]</td>
    <td class=”ms-toolbar”>[toolbar item]</td>
    <td class=”ms-separator”>[separator image]</td>
    <td class=”ms-toolbar”>[toolbar item]</td>
    <td class=”ms-separator”>[separator image]</td>
    [etc.]
    </tr>
    </table>

    We want to hide the first couple of <TD> elements which contain the “New” button as well as the separator. We can do this easily with this little nugget of jQuery:

    <script src="/Javascript/jquery/jquery.js"></script>
    <script>
        $(document).ready(function(){
            $('.ms-menutoolbar td:lt(4)').hide();
        });
    </script>

    Add that to your CEWP you added to the NewForm.aspx page and you get this:

    image

    fooP! The “New” button disappears.

    Sidenotes

    The jQuery is super simple here (I try to write as little code as possible). When the document loads, find the toolbar class (‘.ms-menutoolbar’) then find the first 3 <TD> tags and hide them. One thing to note, when I wrote this today at work I was on IE7 and there were only 2 <TD> tags to hide (thus my jQuery selector was “td:lt(3)”). When I wrote this post I did so hitting my site using FireFox and lo and behold there seems to be an additional <TD> tag. In any case, you might have to experiment with the selectors to get the right number depending on your setup.

    There are *always* many ways to do things in SharePoint. This is just one of them. I suppose you could also find the “id” of the buttons and remove/hide them but SharePoint IDs are always cryptic and not guaranteed to be the same from list to list, page to page, and site to site. I just find this method easy and low impact. YMMV.

  • SharePoint Site Roundup #SPC09

    For those of you who watched the intro video at SharePoint Conference 2009 on Monday (you can view the video again here) I’ve put together a roundup of all the sites in the video (in the order they appear).

    These are all sites built on Microsoft SharePoint Server 2007 (well, sort of, see below).

    Some of the sites are pretty obvious (for example some like AMD still popup up the Name ActiveX control) and others still show their /Pages/ document library. Some sites have pure HTML sites which doesn’t necessarily mean they’re not SharePoint. They could be SharePoint internally and simply publish static content out to the web. The other explanation might be that some of the sites in the video are intranet sites so you won’t be seeing them externally running SharePoint (these are indicated as Intranet only and there’s nothing to see).

    Others are a little more clever in hiding the SharePoint aspect. For example Chesapeake does a great job of hiding the actual pages as the links all look very RESTful (and check out the QuickLinks on the last menu item, it looks like part of the navigation structure but is actually a styled Links list).

    You can pick up some very interesting and unique approaches to using SharePoint by studying some of these sites and seeing how they’ve used the technology (many of them use jQuery and some popular plugins like Mega Menu)

    A few I’ve marked with an asterisk. Some are empty shells, using SharePoint for navigation but the real site is behind it. Others have no SharePoint to be found. I could be wrong but my SharePoint kung-fu skills cannot detect the languishing beast. Maybe you can?

    • Continental seems to be using SharePoint as a front shell but once you click through you’re whisked away to a cold fusion site or some other technology behind the scenes.
    • MTV doesn’t look like a SharePoint site *at all* and I can’t see where any of it could be SharePoint (maybe this is Intranet only?)
    • The link for easyJet actually takes you to holidays.easyjet.com which is *a* SharePoint site. easyjet.com is a classic ASP site (perhaps they’re upgrading?). I was unable to find an easyJet.com site that looked like the one in the video.
    • Citgroup.com and other citi sites all seem to be .htm sites. Not sure where the SharePoint is here although the site in the video looks public facing to me.
    • The Tyson site in the video matches the public facing site and they are .aspx pages, they just don’t look like SharePoint under the covers. Perhaps they did a *really* good job scrubbing the pages (for example there’s no core.js files)
    • tvland.com seems to be all .jhtml pages. The video *looks* like it’s the public facing site but again I can’t tell. I even tried the Press site featured in the video (http://www.tvland.com/press) but it’s not SharePoint and doesn’t match up.
    • Vodaphone, can’t find the site (which looks public) from the video, just a static HTML site present.
  • SharePoint 2010 What’s New – Ratings #SPC09

    SharePoint 2010 offers a new feature around rating content. Note that this feature is only available in SharePoint Server 2010 and not available in Windows SharePoint Services 4.0 SharePoint Foundation 2010 (yeah, I can’t keep up with the name changes either).

    Ratings are very generic things that have a lot of flexibility. They allow users to rate content (of any type, Lists, Documents, Pages on a site, and even Content Types) and store that ratings data in the database just like the new social tags that are part of 2010. A rating represents the average score from all users submitting a rating for that item.

    SharePoint Server provides the rating store, a control to rate items, and a web service to collect and consume the ratings. This service can be used from anywhere inside or outside of the system, including Office 2010 clients.

    To enable a site for ratings you activate the Ratings Service for the site collection via Central Admin (once the service is activated it can be used on any list in the site collection). The service creates a timer job that takes care of collecting the rating data and storing it. Ratings are saved asynchronously but then the store is queued up so not everything is written directly to the database immediately. The service also creates two site columns, one for Ratings and one for the number of ratings. These are available to add to your own Content Types and are added to Lists when the Ratings setting is enabled.

    To start with ratings, we need something to rate. So here’s a simple list with some movie titles in it that we’ll enable ratings on.

    image

    To enable ratings, we go into the settings for this list. Under General Settings for the list you’ll see a new option called Ratings settings.

    image

    Select this and you’ll see the option to turn ratings on or off for this list. It works the same for a Document Library.

    image

    Once you select Yes and click OK, magic happens! Now we take a look at the library and two new columns have been added (from the site columns the service created above). A Rating column (this is a new Content Type) and a Number column to hold the number or ratings. Each time a user clicks on a rating for each item, the number goes up. This is used to average out the rating score to produce the overall rating value for the item.

    image

    Now when we look at our list we see the new Rating and Counter columns added (they’re added by default to your list but you can change this in the view just like any other column).

    image 

    To add a rating, just hover over the Rating field. An AJAX progress window displays then a tooltip provides instructions to the user. The ratings service uses a ratings control seen here that uses two star displays. The first display shows the average rating. As you hover your mouse over the stars the colour changes to yellow to reflect the rating you’re about to assign via a mouse click.

    image

    Once you click on a rating a confirmation tooltip is shown. This is the second star in the ratings control and displays the current user’s personalized rating. This is all done asynchronously so there are no icky postbacks.

    image

    You also get the same user experience when editing a single record in the edit form.

    image

    Pages are rated the same way as items in a list but because you can change the page layout, you’ll need to open the Page Layout in SharePoint Designer 2010 and add the rating control wherever you want (and optionally set some options and properties for the rating). Information is stored in the same place for the ratings.

    Once the list is rating-enabled, you can use the Rating column or Number of Ratings column to group or sort the information in a Content Query Web Part.

    The rating service not only provides features inside of SharePoint but also exposes a Ratings Web Service that any application or Office client can consume. This allows you to submit a rating for an item, get the average rating and rating count for an item, and get the personal rating for an item. The Web Service is the same service that provides the functionality to the Ratings control so the results are the same. This allows you to provide say a ratings experience to your users inside of your own external ASP.NET application but still submit and keep track of the rating data in SharePoint.

    Enjoy learning the new features of SharePoint 2010!

  • SharePoint 2010 What’s New – Lookup Columns #SPC09

    An enhancement that’s been long waiting for SharePoint is around lookup columns. In 2007 you can create a lookup column which essentially “looks up” values from another list. Here’s creating a lookup column in 2007:

    Basic stuff. You select the list you want to get information from and the column you want to use as a display value. You can allow multiple values which makes for an interesting setup. Imagine you want to keep an inventory of servers in SharePoint. You might create a list of servers then you want to know what operating systems are installed. So you could create a list called “Operating Systems” and then in your Server list create a lookup column called “OS” that gets information from “Operating Systems” using the column “Title”.

    A few problems with lookup columns you want to be aware of. If you delete say “Windows XP” from your “Operating Systems” list, any reference in the Servers list are going to be blank. Also there’s no restriction on deleting your lookup values if they’re in use. There’s no referential integrity between the two.

    Another simplistic thing in 2007 is that you only get one column to pick from. This might be fine but what if you want to display more information in the lookup (for example Operating System + Version). You can create a calculated field in the original list which can be something the user picks but a) it requires the creation of that calculated field b) If you have a lot of fields to display the dropdown can get quite wide and c) what if you just want to display additional information for the lookup but not include it in the picklist?

    In 2010 Lookup columns have been greatly enhanced and provide these features out of the box. Here’s what creating a lookup column looks like now:

    You’ll notice two major enhancements here (and a third I’ll get to later). First is the additional column to show. This is a list of all the columns in the original list. These are not added to the dropdown that the user will select, they’re added to the view when you display the list item. This is the same behavior as you would see in a BDC column in 2007. These additional columns can also be filtered and sorted on giving you some additional capabilities in your views.

    The second major enhancement is the Relationships section at the bottom. This is huge and provides you the ability to specify the relationship between items in your list and the lookups they use. It’s an optional choice on the lookup and you can choose between cascaded deletes or restricted deletes.

    Cascaded delete will delete delete any related items in the list you’re defining the lookup on when an item in the target list is deleted. So delete “Windows XP” in your lookup table, any records that reference it are deleted in your Servers list.

    Restricted delete means if you try to delete the “Windows XP” lookup value you’ll be prevented from doing so if your Servers list contains items that use it as a reference.

    Very cool indeed!

    Finally one last thing. You might have noticed there was an option to allow duplicate values or not.

    This is actually a property of the base ListItem and included on *all* column types. So anything (text, number, lookups, etc.) can be set to unique or not.

    Enjoy learning the new features of SharePoint 2010!

  • The Kimono Is Open, The Veil Is Lifted, The Gags Are Removed... #SPC09

    If you find the title of this blog familiar, it should be. Mike Fitz used it when he posted his first remarks about SharePoint 2007 back on September 14, 2005. Here we are in 2009 with a product releasing in about 6 months. Amazing what a journey it’s been, and things are just starting to heat up. Right now Steve Balmer is probably on-stage in Vegas and 7000 SharePoint nerds are listening to him. Developers, Developers, Developers. I’ll never forget Steve and find him a powerful presence whenever he’s around.

    So welcome to the New SharePoint Order, namely SharePoint 2010. I have a whack of blog entries sitting in the queue but I thought I would start with a summary of what you can expect with SharePoint 2010. This is a 50,000 foot view of what’s to come. Over the next few days, more details will be revealed about all of these goodies and people will finally get to see what some of us have been messing around with the past few months.

    The changes in 2010 are huge. Just like the switch from 2001 to 2003 and the higher orders of magnitude in change from 2003 to 2007 so is the shift to 2010. The changes, improvements, and features you’ll see in 2010 are again going to cause a shift in thinking about solutions you build in and out of SharePoint and what is possible.

    So let’s take a look at an overview of the changes in some of the areas in SharePoint.

    Platform

    I actually stumbled across a MSDN blog that mentioned this a few days ago, but it was buried and I guess nobody really got it out there (at least I haven’t see anyone talk about it). In any case, SharePoint 2010 will run on Vista (SP1 and higher) and Windows 7. Yes! This includes both Windows SharePoint Services (4.0) and SharePoint Server 2010. No longer does the lone developer need a VM to develop solutions in. Just install WSS or SP2010 onto your Vista or Win7 OS and you’re off to the races.

    The Service Model has been re-architected so you no longer need a Shared Services Provider (SSP). The services are just there and you decide what to turn and off. Services can still be deployed centrally to an Enterprise Resource Center model where farms can consume services as needed.

    There’s also a big investment in hosting scenarios. The introduction of multitenancy allows you to partition data of shared services to accommodate multiple tenants. Tenants can manage the configuration of administrator-delegated functions (for example what services are available) from one place.

    User Solutions allow you to enable authorized users to upload solutions that have limited access but still provide rich business solutions for SharePoint. They allow the execution of “relatively untrusted code” but do not allow access to things like central admin or things that can take down a server. These solutions can be uploaded to a solution store (without the need to access the sever directly) and live in a sandboxed environment. Any critical exceptions that happen will immediately terminate the user solution code. Think of this like the Private Assembly model from DotNetNuke. Yeah, that’s one thing I was wishing for with SharePoint so now hosting scenarios can get a little more interesting.

    With SharePoint 2010, the entire system has shifted to a claims-based authentication system. Claims-based authentication is based on standard protocols and the Security Assertion Markup Language (SAML) that was introduced in .NET 3.5. Out of the box Active Directory/Windows Authentication is there, just implemented differently using claims but now authorization through other forms (CardSpace, Windows Live ID, ADFS, etc.) are more easily implemented.

    User Interface

    I think by now everyone has seen the new Web Ribbon UI. This is a user interface that mimics the capability of Office 2007. It’s also contextual so depending on what you have selected on the screen, the ribbon emotes this. Select a list item and choices for action on items appear (edit, alert, delete, etc.), select the library it lives in and you can do typical operations on lists (permissions, exporting, etc.).

    To aid with the upgrade capabilities, there’s a few feature in the Configuration Wizard called “Visual Upgrade”. This allows you to preserve the look and feel of existing SharePoint sites and allows end users to update their sites user experience when they want. New sites created after the upgrade will use the new SharePoint user experience by default.

    PowerShell

    If you haven’t got yourself ready for PowerShell and planning on adoption SharePoint 2010, now is the time as it’s used literally *everywhere*. There are specialized cmdlet used in almost every aspect of SharePoint as well most of the basic administration functions can be performed using scripts. The SharePoint cmdlet are not just scripts, they’re objects inherited from the PSCmdlet class (called SPCmdlet) and let you do a ton of things with PowerShell.

    The Social Aspect

    One of the big changes on the Internet in the past few years has been the advent of Twitter, Facebook and other social bookmarking, tagging, and communication tools. With SP2010 people can tag literally anything, and bookmark and comment content on sites. This is supplemented by web parts using tag clouds and other tools to find that content. The evolution of "My Site” is the “People Portal” and pulls together all of the social networking features into a user-friendly interface that enables people to express themselves better in the corporate setting.

    In addition to social tagging, there’s the addition of expertise tagging. SharePoint supports building and sharing their skill sets to everyone else. Imagine wanting to find all the .NET developers in your organization with C# and SQL experience. Now you can! With SharePoint 2010, you can truly look at and think of SharePoint as Facebook for the Enterprise.

    Wiki, Wiki, Everywhere

    Team sites and Publishing Sites have always been a problem. Team sites have that default.aspx look and feel (you know, the two-column deal that has little to no flexibility) but publishing sites have page layouts and all kinds of cool stuff. Now the two meet and have babies and it’s called SharePoint 2010. Every site (team or otherwise) is essentially a wiki with the publishing capabilities from 2007. Page layouts can be changed around, new pages can be created, and the content can be edited in a more intuitive way (you don’t have to drop a content editor web part onto a page to edit it’s text for example).

    The content areas are rich and practically *anything* can be dropped onto them, including lists and web parts. Yes! You can start editing a page and say “Hey, it would be cool to have a video embedded here” and drop one in.

    Finding What You Need

    Search has been greatly improved in SharePoint 2010. You can now search for a person using a fuzzy search algorithm. Nobody can ever find me because my first name is “Bil” not “Bill”. However trying to find me via “William” or something similar works in 2010. Search queries can now match a wildcard at the end of a text string so “Young*” will match “Youngblood” and “Younglings”.

    Search results has also been improved and lets you filter down from wide range searches to things like dates, tags, authors, and content types. You can also rank search results based on click-through history and for people, by social distance. If you prefer to deploy the FAST search product, SharePoint supports FAST and provides better search results like item counts, visual search (thumbnails) and “Find Items Similar to this” links.

    InfoPath, Everywhere

    The huge difference with InfoPath is that it’s used everywhere. When you change a normal SharePoint list item, it’s really an InfoPath form behind the scenes. This is transparent and more than likely, you won’t be able to tell. In fact the default look and feel makes it look just like the 2007 NewForm.aspx page. There are some overall performance improvements (for example there’s a new type of list control that only populates the control when its clicked) and better accessibility.

    There’s also a new feature that lets users expose an InfoPath form as a web part. This should help people build more interactive sites more easily and contributes to that “composite” part of the new SharePoint circle. As with most of the rest of SharePoint 2010, PowerShell is used everywhere and there are InfoPath cmdlets to help you deploy and upgrade forms, manage data connections, and administer the InfoPath Forms settings.

    It’s All About The Content

    For those that use the content management features that were folded into 2007, 2010 offers much more interesting and flexible options for authoring, organizing, and finding information.

    Document Sets provide a capability of collecting documents together as a single unit (you still edit the documents individually). Workflows, versioning (point in time snapshots) and other actions can be performed on the entire set at once.

    I’m a huge proponent of trying to organize information other than using folders. 2010 has several improved ways to do this through managed metadata (centrally administered) and local metadata at the site/site collection level. Users can edit this information in their documents (including offline editing) and use the metadata for navigation and searching. For page authoring, there’s a new feature called “auto-foldering” (sounds rather odd and not sure if this what they’re going to call it). If “auto-foldering” is enabled then when a page is checked in for the first time, the routing object model is called to route the page into an appropriate location (using metadata to decide where it should go).

    There’s also the notion of a Document ID now. Every document uploaded to SharePoint has a unique document id generated for it. Think of it as a GUID for documents. This is a value that can be used to always find that document on the site using a static URL. This ID can be used to find the document (through an out-of-the-box Document ID Lookup Box Web Part), navigate to it via a static URL (e.g. “/SiteName/DocumentFinder.aspx?Id=FX803S2”), and manipulate the document via the API. No matter where the document has been moved on the server, users will be able to find or navigate to it. You’re not limited to how Microsoft creates these IDs. Custom document id providers can also be created so you could fetch information from another system or use some other technique to generate them.

    The XHTML and CSS files SharePoint uses have been simplified (there’s still a ton-o-classes though) and is now WCAG 2.0 AA-compliant. The Content Query Web Part, a workhorse of a web part in SharePoint Server installs, can now do cross-list views of content based on managed metadata. And for those that have a ton of pages in the “Pages” document library (in publishing sites) you can now organize the information by folders (or use metadata).

    A new ratings feature provides the ability to rate content by users. These ratings are exposed as metadata so you can sort, filter, and query it. Ratings can be enabled on list items, document library items, and publishing pages.

    YourTube

    SharePoint 2010 fully supports SilverLight and includes some digital aspect features so you can create centrally managed asset libraries where audio and video assets can be served up for publishing and streaming video assets. Supported file formats in a SharePoint asset library include .asf, .avi, .flv, .mov, .mp3, .mp4, .rm, .wma, and .wmv.

    There are new content types for audio, images, and video. These come with new columns like data rate, frame rate, and length (duration of an audio or video file in seconds). You can also associate thumbnail images for videos (not automatically generated but simple to hook up). Images will generate thumbnails automatically like they do in 2007.

    When adding an asset to a web page you have complete control over things like how it’s played and what state the run-time display is in. This allows you to create looped videos on pages, automatic play-when-loaded pages, and inline, pop-up, or full screen players for video content.

    Looking to build an internal YouTube for your organization? Pretty simple with 2010 now.

    Feature Attractions

    There have been some nice improvements to the feature framework in 2010. For example you can now capture and program the upgrading of a feature. The SPFeature class now has a method called Upgrade that will allow you to perform an upgrade at all scopes and the Feature.xml definition file has a new <UpgradeActions> section that lets you specify a custom assembly to handle the upgrades.

    It’s Only a Model

    The programming model overall has been greatly enhanced, with a lot of things we’ve wanted in the 2007 version. If you’ve poked around in the previously released SDKs, some of this might be old news.

    Lists now have Adding/Added and Deleting/Deleted events added (the same as how list items work, but now on the entire list). The web object also has additional events to help with provisioning (for example to programmatically add web parts as the final step to creating a new site).

    One of my favorite features in 2010 is the addition of LINQ support. LINQ allows you to query all types of data (regardless of the source) using the same query syntax. You’ll still need to know (and continue to learn) CAML for site and list definition, but finding things are just a LINQ query away. Behind the scenes, the LINQ to SharePoint provider really just converts LINQ queries into CAML (much like how the LINQ to SQL Provider does) but it means you can write queries to find items like this now:

    // Query for customers from London
    var londonCustomers = from customer in Customers
     where customer.City == "London"
     select customer;

    There’s also a tool called SPMetal that will generate your entity classes for you. Once the classes are generated, you can add items to list with just a few calls rather than having to populate each field individually. The entity classes are POCOs so unit testing gets far easier with 2010.

    This is really just scratching the surface of what’s new and while it seems lengthy, there’s so much more. Like I said, I’ll be posting more detailed entries on many of these (and other) features of SharePoint 2010.

    Okay kids, let the disclosure begin!

    Note: First off, I am *not* attending SharePoint Conference 2009 where all of this information is coming out of. Second, most of this information is based on my working with the product for the past few months. Some details in my entries may be out of date or incorrect and I apologize for that. I’ll correct things as I can and stumble over items. If you find something amiss, feel free to leave any corrections or remarks in the comments of the posts yourself or flip me a quick email.

  • ShareTalk – Soup to Nuts

    My co-worker and BizTalk MVP Kent Weare has been blogging up a storm with his BizTalk and SharePoint integration series of posts on his BizTalk blog. In it, he walks through the entire process of getting BizTalk 2009 talking to Windows SharePoint Services 3.0, publishing forms, retrieving information, creating InfoPath forms from BizTalk schemas and more!

    This is an awesome (and the first that I know of) resource that’s complete on the BizTalk and SharePoint side of things (with some InfoPath form processing thrown in for good measure). I highly recommend the entire series for anyone who’s interested in this sort of exchange.

    I’ve also put together a single PDF file of the entire series (100 pages, 7mb). You can download it here.

    Enjoy!

  • Changing the Home tab in Mutipage Meeting Workspaces with jQuery

    Another simple trick today. Very often people ask about how to change the tab name on sites created with the Multipage Workspace Template. A simple enough request but not something you can do out of the box. Or can you?

    Okay, let’s take a step back. Let’s say you want a site with tabs. There’s a built-in template under the Meetings group called Mutiplage Meeting Workspace. It creates a site with tabs and allows you to add new tabs (Web Part Pages) and place whatever Web Parts you want on each tab.

    Just a note that this is actually a Meeting Workspace template and isn’t quite like a normal site template. You’ll find oddities like the inability to create subsites and weird hidden “1” folders. This is because meeting workspaces are designed to have the ability to repeat and use the hidden folders for supporting this. However for the purpose of creating a site with tabs, it works and easy to get going with. See some links at the end of the article on tips and tricks creating Multipage sites.

    Using this template it’s easy (but not intuitive) to change the name of the tab for each page. To change the name of an existing tab:

    1. Navigate to the tab page
    2. Click on Site Actions then select Manage Pages


    3. Click on Order to show the dropdown menu and select Settings


    4. Change the Page Name and click OK

    However if you try this on the Home Page you’ll see this message:

    That’s not very comforting (and I can’t recall why you can’t change the name as it’s rather silly) however it’s jQuery to the rescue to correct this quip.

    To change the Home Page tab name we’ll need two Content Editor Web Parts (CEWP). One when the Home tab is active and one when it’s not. Using jQuery we simply find the tab and change the text. Seriously it’s this easy:

    <script type="text/javascript">
        $(document).ready(function(){
            $('.ms-tabselected:contains("Home")').text("Zombieland");
        });
    </script>

    And here’s the code when the tab is inactive (it has a different classname):

    <script type="text/javascript">
        $(document).ready(function(){
            $('.ms-tabinactive:contains("Home") a').text("Zombieland");
        });
    </script>

    I know it’s simple and boring. You can also use the ‘begins’ wildcard feature of finding a class in jQuery so rather than the simplistic code above, you can impress your friends and pick up hot chicks with something a little more sophisticated looking like this:

    <script type="text/javascript">
        $(document).ready(function(){
            $('*[className^="ms-tab"]:contains("Home")').text("Zombieland");
        });
    </script>

    However this only works when the Home tab is active. When it’s inactive you need to include the hyperlink so the selector looks like this (note the addition of the ‘a’):

    <script type="text/javascript">
        $(document).ready(function(){
            $('*[className^="ms-tab"]:contains("Home") a').text("Zombieland");
        });
    </script>

    I thought I would be smart and use the className^=”ms-tab” wildcard so it would work on any page but the content changes if the page is active. Even with the class selector when the page is active, there’s no hyperlink to the page (which makes sense) so no ‘a’ selector to find. When the tab isn’t active it’s there. My JavaScript kung-fu prevents me from figuring out something that works for both situations but feel free to post a snippet in the comments and I’ll update the post.

    In any case, with a single line of JavaScript and jQuery we transformed this:

    into this:

    Enjoy!

  • Calculated Time Left columns in SharePoint with jQuery

    A current project I’m working on in SharePoint is an online auction. I’ll post more info about this and maybe some code and web parts later but for now I wanted to share a simple enhancement we did with a little jQuery to display the time left for each item.

    Just like eBay, I wanted to display the time remaining on auction items. I figured this would be a calculated field (based on a date the user chose for when the auction for that item ended) but having to calculate date differences based on the current date doesn’t work in SharePoint (the elusive [Today] problem). I thought jQuery would help and it did. Here’s how.

    First you need a couple of fields in your list. Auction items are stored in a list with some details (title, description, bid information, etc.).

    image

    Along with the regular fields there are a few other ones at the end that are used for housekeeping on the item (and not displayed to users). In particular there’s an [End Date] field which is a simple Date/Time field for when this item should end and another one called [Time Left].

    image

    [Time Left] is a calculate field shown as a Date/Time value. The actual calculated value is irrelevant as we’ll be replacing it with our JavaScript, so we just make it equal to the [End Date] field.

    image

    The calculated column serves as a dual purpose because we’re actually going to read this in our List View then replace it with the number of days/hours/minutes/seconds remaining on the auction item. Since it’s a calculated field, the user doesn’t edit it either.

    Over at End User SharePoint in the jQuery for Everyone series Paul Grenier, the undisputed King of jQuery in SharePoint, had a great article about dealing with the [Today] problem. His sample finds a column in a list view and displays when an item was last updated. It’s exactly what I needed, except I needed to look forward in time to determine the time remaining rather than backwards. Simple enough to take his example and reverse the dates. Here’s the modified jQuery code:

    <script type="text/javascript">
        $(document).ready(function(){
            var str = "Time Left"; //change this based on col header 
            var a=0;
            var headers = $("table.ms-listviewtable:first> tbody> tr:first th").get();
            $.each(headers, function(i,e){
                x = $(e).contents().find("a[title*='"+str+"']").length;
                a = x > 0 && i > a ? i : a;
            });
            var today = new Date();
            today = Date.parse(today)/1000;
            var dArray = $("table.ms-listviewtable:first> tbody> tr:gt(0)").find(">td:eq("+a+")").get()
            $.each(dArray, function(i,e){
                var d1 = Date.parse($(e).text())/1000;
                var time = '<span style="color:#ff0000">Ended</span>';
                if(d1-today > 0) { 
                    // calculate days, hours, minutes and seconds
                    var dd = (d1-today)/86400; 
                    var dh = (dd-Math.floor(dd))*24;
                    var dm = (dh-Math.floor(dh))*60;
                    var ds = (dm-Math.floor(dm))*60;
                    // build display string
                    time = ((Math.floor(dd) > 0 ? Math.floor(dd) +"d " : "")+
                            (Math.floor(dh) > 0 ? Math.floor(dh)+"h " : "")+
                            (Math.floor(dm) > 0 ? Math.floor(dm)+"m " : "")+
                            (Math.floor(ds) > 0 ? Math.floor(ds)+"s" : ""));
                    // highlight active auctions
                    var isEndingSoon = (((Math.floor(dd) + Math.floor(dh)) <= 0) && (Math.floor(dm) < 15)) ;
                    if(isEndingSoon) { time = '<span style="color:#ffcc00">' + time + '</span>'; }
                    else { time = '<span style="color:#005a04">' + time + '</span>'; }
                }
                // write out text value as html
                $(e).text('<span style="font-weight:bold">'+time+'</span>');
                $(e).html($(e).text());
            });
        });
    </script>

    Remember, the [Time Left] column is a calculated value that’s simply displaying the value from the [End Date] column the user enters. Why not just use the [End Date] field? Simple. It makes more sense when editing an item to set the End Date but then display the time remaining. Imagine if you were editing this and saw a field called “Time Left” as a Date/Time value. This way, the user sets the End Date for the auction but never sets the calculated field. We also needed the target date to be displayed in the list view so we could do our calculation so here it is.

    Finally I did a little formatting on the time remaining. All items are set in a bold font and coloured green. Items that are ending in less than 15 minutes are coloured orange (yellow doesn’t show up very well against a white background) and items that have ended already are displayed in red.

    Once this little jQuery script was written it was a simple matter of going to the list view page, editing it, and adding a Content Editor Web Part with our script in it. You could also use this on a Web Part Page as long as you have the [Time Left] field visible in the view. Here’s the list of items with the Time Left field and coloured highlighting:

    clip_image002

    Pretty cool and again, thanks to the power of jQuery (and Paul) no assemblies or server deployments needed!

  • SharePoint FUD... Spreading Far, Wide and Fast

    The last month or so I've been a casual observer to a bit of a train wreck. It's the train wreck that we collectively know as the SharePoint bashing exercise. I'll admit fully and upfront. I'm a SharePoint MVP and there are times SharePoint (at a micro level) frustrates me enough to go postal on my co-workers. However from a macro level and as a corporate tool, it's a pretty darn good piece of software.

    For the past month I've been watching people on Twitter endlessly blather on about how bad SharePoint is and how great <insert cool tool of the day> is so much better. The latest of the "SharePoint Killers" is Google Sites. I look at all of these complaints and competitors and scratch my head. What is all the bruhaha about? If you look at things seriously, you're comparing apples to gasoline and never the twain shall meet. The latest moronic dribble is from Computer World UK where they call SharePoint a "Fortress" and elude to Google Sites being able to get your "locked content" away from the prying arms of SharePoint. I have no idea what Glyn Moody is talking about. If I put my data/documents/etc. in Google or Drupal or some other more "free" system, how is it not locked away there? If by locking away your data in SharePoint you've made a decision to use SharePoint then sure, call it that. However it's no different than choosing any technology and storage platforrm. SharePoint doesn't nothing to trap or lock your data up anymore than any other system out there. But yes, SharePoint is a fortress which eats your data, pollutes the environment, and kicks puppy dogs.

    I started to go down this path with an adventure looking at various SharePoint-like alternatatives and I have a 10-page draft post comparing SharePoint to WordPress (which I think is a kick-ass blogging platform) along with ideas and notes for Drupal, Box.net and other comparisons. Maybe someday I'll publish them but I'm not seeing a value in doing that right now. However I wanted to take this opportunity to sit down, filter through the FUD that is spreading, and give my take on things.

    SharePoint sucks for content managment

    Suckage is always a relative term. What CM do you have today? Drupal? WordPress? Joomla? CMS? MOSS 2007 folded the old CMS capabilities into it so now users create "Pages" that can go through workflow, multiple edits, etc. all to be published at some point. I've setup many intranets that were primarily focused on just creating content and they've all been pretty successful. Where's the suckage here? Is it fabulous at copy 'n' paste from say Word or a web page? No, but then neither are those other products. There are some supplemental tools available to help this (Telerik has a nice RAD editor that plops into SharePoint with minimal effort as a replacement). Pages can be moved around at will (without breaking links) and assets can be centralized for everyone to use. SharePoint 2010 enhances this even more as we'll see in a few weeks. Perhaps SharePoint sucks compared to something but I'd like someone to come forward with some real world issues they're having. Perhaps SharePoint does have problems with specific issues, but overall MOSS is pretty good for content management.

    InfoPath Forms is Hell

    Again I'm waiting for someone to come forward here. We've built many forms all working well and were easy to build and deploy. Yes, if you get into complex forms with lookups into backend systems and complex decision tree logic it starts to get ugly. However why are you building something like this in InfoPath then? One of the main failures I see in SharePoint is misuse of technology. "Oh we have a forms engine with InfoPath so let's build all our business logic in forms". Uhh, no. No developer with half a brain would do that. Would you code SQL statements and database connections in the code-behind page of an ASP.NET form? Then why are you trying to do the same in InfoPath. Stop blaming tools for your own idiocy. I've used so called "form engines" from all kinds of products and short of building forms in ASP.NET and Visual Studio, InfoPath is pretty slick and simple. However it's a developers tool not something you hand over to a business user to create an IT mess out of.

    SharePoint is idiot easy to install without any planning

    Yes, yes it is. And leaving for the moon without a plan will probably get you killed on takeoff. Any fool that follow SharePoint for dummies to setup an intranet without any planning is exactly that. A fool. And a fool and his money are soon parted (along with your sanity and any sense of credibility you might have at your job). Even in Agile projects you plan. SharePoint installations are pretty simple when it comes down to it, but you still need to sit back and talk about what you're about to do. Are you over-architecting your solution (i.e. building a medium farm for 100 users) or are you under-architecting it so it doesn't scale (installing Basic mode on a stand-alone server for 10,000 users). It takes some expertise and understanding of a whole ream of technologies to pull off a good sized SharePoint deployment but as long as you don't jump in head-first without any idea of what you're doing, you'll probably do fine. Its when people think running setup.exe, sending out an email to everyone saying "Go use SharePoint", then wondering why they have storage/capacity/performance issues after the fact.

    SharePoint is big and expensive

    I hear this all the time and yes, it *can* be bloody expensive. In fact I was looking at external MOSS sites and the price tag was in the 10s of thousands of dollars. Compare that to the price of some open source software where you're basically paying for hosting or a machine sitting in the DMZ and you'll scratch your head. However a few things here. Comparing the price of WordPress ($0) to SharePoint is nonsense. It's the apples and gasoline issue. They are not the same product and thus you can't put them on a level playing field.

    I think this is one of the biggest issues with the whole compare and contrast argument with SharePoint. SharePoint does have wikis and blogs and content management and document repositories and all that jazz. However it has a whole bunch more. Need your OOTB SharePoint to have one little extra menu to direct users to a FAQ? That's a small bit of JavaScript or a feature deployed. Need it to consume web services and format the output, again something that can be built as a feature and deployed. The point is SharePoint is a platform, one that which Microsoft has come up with some basic templates to get you started but people haven't grasped the bull by the horn and gone nuts like they have with other platforms. It's true that building themes is for the birds in SharePoint and not as flexible as templates in say Joomla, but again themes and skins are not the same. In SharePoint themes, you don't have control over layout. With master pages you do but only for the overall site. Application pages provide additional layouts. One has to understand how these three come together to provide that user interface and experience and realize it's not just a simple text file like a DotNetNuke skin.

    The other major issue is integration. Sure MediaWiki is far superior to SharePoint when it comes to wikis but ask MW to handle versioning of Office Documents and exposing metadata (then searching on that metadata) and it falls flat. Alfresco for document storage? Sure, but then what about creating a custom list with business related fields, grouping that information, then creating views to display say sales from a division over a period of time. That's the thing about SharePoint. It does *all* of that, plus more. Does it do all of that exceptionally well? No. It does a lot of things pretty good, some things very well, others really crappy but that's like life. Nothing is the be-all tool for everything and you make compromises to get the best of most worlds. Trying to cobble together the best-of-the-best tools for content management, wikis, blogs, unstructured and structured data, document management and a wealth of other things is just going to create a big ball of mess.

    It's Highly Complex to Install

    So is installing (almost) any Enterprise tool. But let's take a step back here. What's so hard about a) download wss.exe b) run msi c) run config wizard and answer a few questions [e.g. where is your db server, account names, etc.] d) start central admin and create web app and site collection. Okay, that's 4 steps but in reality to setup SharePoint for a brand new environment (assuming WSS) you need about an hour (that's soup to nuts install). MOSS is a couple of hours depending on how your architecture is setup (i.e. multiple front-ends). Highly complex? You're not installing a desktop app where you run the setup program and click a few buttons. Grant you, I think *nothing* beats WordPress and it's 5 minute install (which actually takes about 30 seconds) but again, WordPress isn't SharePoint. I really wish SharePoint would install like this, but something people forget is that while it takes a few minutes to install WordPress you're still spending hours configuring your site/blog, installing plug-ins, downloading and trying out themes. The base install of WordPress isn't much different than SharePoint. It's the devil in the details afterwards that will suck your time. Highly Complex is realative. If you're building a 10,000 user system with 5 or 6 servers sure there are a lot of moving parts. If you're installing WSS for a small company to do collaboration it's a breeze.

    So what makes SharePoint successful?

    I don't know. Your modern ways frighten and confuse me. However what I do know based on experience is two things. If you're a Microsoft shop and use Office and there's a need for some form of departmental or corporate collaboration, SharePoint is probably your best bet. If this is true, install it. Sit down, plan out a way to use it (maybe starting small only with sharing documents). Then set it up. Do not release it to the world or get people on board that have no idea what to do with it. Get some people that are passionate about sharing and have an IQ higher than the temperature of the room you're sitting in right now. Try things out, see what works and what doesn't and get some champions behind it.

    SharePoint success is not about ripping it apart to see what makes it tick then reassembling it (because like that old map in your glove compartment, you'll never fold it up the same). If your first instinct is to crack open Visual Studio then you're probably not thinking in the SharePoint space. VS is an option as you can't do everything in the browser or SharePoint designer, but it's not the only option. There are people that will tell you that to make SharePoint useful you *have* to extend it with features your developers build (or you can get from CodePlex or other places like that). These are the same people that will probably want to sell you hundreds of hours of high priced consulting time and might even give you some magic beans for your troubles. OOTB SharePoint *is* powerful and quite business-enabling. You just have to think about the problem space a little differently and in some cases adjust the practice. If that's not going to happen then maybe creating custom Workflows or Web Parts is the answer, but ask yourself if you're solving the right problem first before you starting writing using(new SPSite()) statements.

    Once you do start using it the most successful factor to help you along is to empower your users. Don't lean on the IT department (whether it's 1000 experts or 2 guys and a small dog) for every little thing (like setting up permissions for users). During your eval, try things out and work out a governance plan for how users are going to access things, how you'll manage security, and how site creation and structure will work. Microsoft has hosted scenarios so you don't have to invest in infrastructure and there are virtual labs where you can spin up a SharePoint instance to give it a whirl. Don't unleash the beast unless you know what's behind the smoke and mirrors. And be careful what you ask for. Passionate users that think SharePoint is da bomb might actually turn your little collaboration experiement into a success.

    Again, caveat lector as I'm a SharePoint MVP so you can take my word in whatever way you want. I may be one that screams and yells at the SharePoint machine on a daily basis, but I'm not lining up with pitchforks and burning torches like some people have been.

  • Low impact text changing in SharePoint with jQuery

    Mike Smith over at Tech Training Notes had a nice simple post a few weeks back on changing the default text displayed at the bottom of stock web parts in SharePoint. For example discussion boards show this text when it's blank:

    "There are no items to show in this view of the "Test" discussion board. To create a new item, click "New" above. 

    That's great but what if the "New" link isn't avaiable (if you turn off the full toolbar and put a discussion list on a page this would happen). Or what if you don't like calling it a discussion board (for various reasons) and want to say forum. Or want to provide additional information.

    His solution is a little bit of JavaScript and then pushing his function into an array _spBodyOnLoadFunctionNames (which is a list of scripts SharePoint will run when the page loads). Here's the original version:

       1:  <script type="text/javascript">
       2:   
       3:  function ChangeDiscussionMessage()
       4:  {  
       5:      var a = document.getElementsByTagName("TD")  
       6:      for (var i=0;i<a.length;i++)  
       7:      {    
       8:          if (a[i].className=="ms-vb")    
       9:          {      
      10:              if (a[i].innerText.indexOf("There are no items to show in this view")>-1)      
      11:              {         
      12:                  a[i].innerHTML = "There are no active discussions";      
      13:              }    
      14:          }  
      15:      }
      16:  }
      17:   
      18:  _spBodyOnLoadFunctionNames.push("ChangeDiscussionMessage") 
      19:   
      20:  </script>

    Here's a more simplified jQuery version:

       1:  <script type="text/javascript">
       2:   
       3:  $(document).ready(function(){
       4:      $("td .ms-vb:contains('There are no items to show in')").text('There are no active discussions');
       5:  });
       6:   
       7:  </script>

    P.S. I'm still trying to find time to write up the blog post from this last weekend's code camp and will post the SharePoint developer resources soon!