Archives

Archives / 2004 / December
  • Wrapping long questions in SharePoint surveys

    Nothing like finding a solution to a problem for the end of the year. Don't say I didn't give you anything.

    I was recently asked about how to tackle long questions in surveys with SharePoint, specifically there's a problem that long questions don't wrap so you get a really ugly looking website. Go ahead, create a survey and add a really long question to it. Notice how you're stuck with horizontal bars from hell? Here's how to get rid of it.

    1. Create your survey as you normally would.
    2. Select Respond to this Survey.
    3. Click on the Edit with Microsoft Office FrontPage on the IE toolbar. This will launch FrontPage with the NewForm.aspx page loaded.
    4. Right click on the Survey form in FrontPage and select Customize SharePoint List Form from the popup menu. This will convert the form to something you can edit. NOTE: It's not pretty as all the HTML tags are now literal so be careful editing these!
    5. Scroll down and find a tag that starts with something like this:
      <Content xmlns="http://schemas.microsoft.com/WebPart/v2/ListForm">
      The rest of this tag will contain the HTML for your survey form (like I said all the HTML tags are literal so <TD> will look like &lt;TD&gt;)
    6. Find the tag that looks something like this TR&gt;&lt;TH nowrap valign=top class=&quot;ms-formlabel&quot;&gt;
    7. Change the TH nowrap to TH wrap
    8. Save the page and return to your browser.

    You'll see the change in FP and when you refresh the page in your browser. The text now wraps and all is well. Neat huh? Repeat this for each question (keep looking for the ms-formlabel class). These instructions are only for the NewForm.aspx page which is what users will see when they respond to a survey. There are still other pages which suffer from the "nowrap" tag so you'll have to edit each of those. They are:

    • DispForm.aspx (used to view a single result)
    • EditForm.aspx (when you edit an existing response)
    • summary.aspx (when you want to see a graphical view of all responses)

    AllItems.aspx and overview.aspx don't show the questions so you don't have to worry about this files.

    Another way to do this is to open up the site, not the page, in FrontPage and expand the survey you want to edit using the Folder List (Alt+F1) from the View menu. From here you can just edit NewForm.aspx and the other pages directly and take out that nasty "nowrap" attribute.

    Hope that helps and have a safe and happy New Year!

  • Quirky little things about Lists and Views

    Things always come together in two ways. A blessing and a curse. Take SharePoint lists and views for example.

    The blessing is that they're really powerful stuff where a user can define how they want to view the information in a list. Grouping, sorting, filtering, style. All great stuff.

    Now for the curse.

    Often what's displayed in a view isn't enough. Sometimes the user doesn't like the way the grouping works. The most common thing is the "Group: " tag that gets added and people want to just see the name of the group. Or maybe they want some funky javascript so that when you click on a group it expands and collapses the list (like Jim Duncan documents here). Little things that make usability a better thing.

    So here's the curse I came across that you might keep in mind. It's a great thing to save a list as a template for later use. You can even write a silly little tool like I did to generate hundreds of lists across multiple sites, all using the same template. The rub is that the template isn't forgiving.

    Case in point. I created a new list with various views that sliced and diced the data up so the user had a good set of links to quickly look at information in bundles rather than a big list of line items. The list was created and named ProjectSubmissions.

    TIP: When you create a list, view, or column it's best to name them without spaces and rename them later for display purposes. Why? If you create a list or column with the name "My List", internally SharePoint will store it as "My_0x00_List" (or something like that, it varies with the tides of the moon). When you're trying to do something programmatically with the list you'll be tearing your hair out trying to figure out the internal name. To avoid this, just name it "MyList" (no spaces) and then after it's been created go into the settings and change the name to something more visually friendly like "My Fabulous List". You'll always refer to it in code or by url as "MyList" but it makes it easier in the long run, trust me.

    Okay, so I had my list and created various views to sort/group the information. One of the fields was called "SiteType" but the user wanted a view grouped on this field but rather than seeing "SiteType: <group data>" in the grouped label, they wanted it to say "Program: <group data>" and filter the grouping so that it only showed data where SiteType = "Program" (which was a choice field). Follow me so far? Okay, easy enough. Each view is a new .aspx page that SharePoint creates for you when you build a new view so you can easily load this up into FrontPage and with a quick conversion to an XSLT view, change whatever you like. 2 minutes later the grouped view was renamed and all was well.

    Now here's the killer. After a few hours of development (Creating lists and views is so damn easy with SharePoint!) we packaged it all up for remote deployment via a tool to create hundreds of these little things. At the last minute it was decided to change the name of the list from "ProjectSubmissions" to "SiteCatalog". No problem. That's easy enough right? It was and everything seemed to work. Zoom, zip, off goes the deployment to the various sites and everything works. Until someone clicks on the one customized view when then points back to the originally named list! ARGH! For whatever reason, the internal name that was originally created in the list was saved when the view was unghosted to do that simple little edit. All the other views, even though they were generated .aspx pages worked fine. The one unghosted page though was static and thus pointed back to the originally named list "ProjectSubmissions" which now was called "SiteCatalog". Boom, 404 is your result.

    Anyways, be careful with your templates. They remember everything and don't care if you didn't.

    Other things that irk me (and are fast elevating themselves to becoming a peeve) is the fact I can't group on a calculated field. Or that I can't filter lookup fields. And why can't I export/save the contents of a list created using the Issue template like I can with every other list? And the list goes one.

    Okay, enough ranting. Hopefully Microsquishy will listen to the cries of us stonecutters and make life better in a future version of service pack. Until then, we do what we can with what's there, twiddling and changing things hoping we're not shooting ourselves in the foot while we do it.

  • Managing Virtual PC Images with SharePoint Development

    I have a lot of Virtual PC images. A lot. Like 20+ just for SharePoint development alone. It seems excessive, but there are a lot of configurations I need to suport (https vs anonymous vs workgroup) as well as various sites we host at work (several SharePoint based applications, a few portals and a couple of Enterprise portals in development for 2005/06). On top of that, I have a few setups that are the SharePoint 2003 / Visual Studio 2005 experiments (which are pretty ugly at this point). Managing all these images is a bit of an issue and even at 5-10gb per image, a 200gb drive fills up pretty quick.

    I stumbled across a nice post by Jan Tielens on Virtual PC images and differencing. Something I hadn't done before as all my images are built from scratch. This is not only time consuming in the construction (and something a trained monkey or a well-written NAnt script could do) but they're time consuming to copy around when you need something "almost" like that image but not quite. There is a nice walkthrough blog here on Matt Hausmann's site that gives you a nice visual guide on building difference images.

    So after spending a dozen hours or so butchering my SharePoint images, I've reduced my VPC files from 180gb down to 25gb with the same number of images. Pretty slick and creating a new one takes about a minute. I highly recommend you take a look at this for your own VPC image management if space or time is a concern. Now onto my Visual Studio images. Sigh.

    Okay, so this post wasn't really a HOWTO on managing Virtual PC images but hey, it's something to blog about.

  • SharePoint Code Camp

    I recently stumbled over Thom Robbins .NET Weblog (now a new place I visit on a regular basis) and found a cool idea called Code Camp! Code Camp is where you get as many developers together as you can and, well, code. It's somewhat of a new concept (new to me anyways) but really looks like it rocks and has somewhat of an open source quality to it (all code is free and openly shared with everyone). Best of all, it's FREE! The "official" Code Camps are composed of hundreds of developers and there's one coming up in February. Check out the MSDN Code Camp site for more info (although it's pretty slim on details right now). Additionally, Thom published what he calls the Code Camp Manifesto which puts together some simple protocols to follow.

    Anyways, the idea really interests me and will be a blast so I'm going to look at organizing a SharePoint Code Camp. On the off-chance I can't get enough raw SharePoint developers (which may not be surprising), I'll look at doing a more general .NET/Web Services Code Camp (perhaps talking to SharePoint, have to get it mixed in there somewhere). I'll hit up the local RD John Bristowe and my MSDN contacts to get something happening in Western Canada for the new year.

    As Code Camp content is determined by the community I'll be looking to you to contribute. So come by, learn, teach, have fun, whatever. Let me know if you're interested in attending, participating, helping, etc. and we'll see what we can shake up.

  • Consuming Web Services with SharePoint

    Merry Christmas! Hope you and yours are having a happy holidays.

    I've been working a lot with consuming web services and DataView Web Parts (DVWP) with SharePoint lately. FrontPage 2003 lets you create these very cool things called DataView Web Parts. Basically they consume a web service (either one your write or something someone can provide) and expose the results as a webpart that you can use/re-use on your SharePoint site. With the magic of XSLT you can get the results looking grand.

    This example walks you through consuming a web service from the Microsoft Money site and get live stock quotes (well, 20 minute delay anyways) all without a stitch of code. Okay, no C# written here but some people will say that coding XSLT is pretty much the same as writing code. You be the judge however the example here was to get a single stock quote web part consuming an external web service, all without having to break out your Visual Studio.NET toolkit.

    First we'll need a page to add the DVWP to. This can be your default.aspx page but I prefer to create a new webpart page, stick it into a document library and edit the page from there. That way I'm not un-ghosting my default.aspx page and I can delete the doclib later and not use it in production. Either way, your choice.

    1. Load the page up into FP2003
    2. Select (or create) a Web Part Zone
    3. Select Data | Insert Data View from the menubar
    4. Expand the XML Web Services Data Source from the Task Pane
    5. Select Add to Catalog...
    6. Enter http://office.microsoft.com/Research/Providers/MoneyCentral.asmx?WSDL the Service description location. This is the URL to the Microsoft Money Web Service.
    7. Select Connect Now. This will populate the rest of the dialog with the available services
    8. Select MoneyCentralRemoteSoap from the dropdown list
    9. Select DDSQuery from the Operation list
    10. Double click on symbol in the Parameters list
    11. Enter your stock symbol in the Value field (for this post I used Canadian Pacific Railway which is "CA:CP" but you can use any valid symbol like MSFT for Microsoft, YHOO for Yahoo, etc.)
    12. Select the checkbox so you can enter this value at runtime.
    13. Double click on language in the Parameters list
    14. Enter en-US as a value here (English/United States, you can enter other values here for other languages)
    15. Click OK

    This will add a new Data Source into your catalog called MoneyCentralRemote on office.microsoft.com. You can now drag and drop this data source onto a Web Part Zone. Once you do this your web part will look like this:

    DDSQueryResult <StockData xmlns:dt="urn:schemas-microsoft-com:datatypes"><Quotes><Quote Symbol="CA:CP"><Last dt:dt="float">40.98</Last><LastTime dt:dt="string">10:05 AM</LastTime><LastSize dt:dt="float">100.00</LastSize><Ask dt:dt="float">40.98</Ask><Bid dt:dt="float">40.90</Bid><Open dt:dt="float">41.00</Open><Close dt:dt="float">40.80</Close><High dt:dt="float">41.00</High><Low dt:dt="float">40.61</Low><Volume dt:dt="float">20,172</Volume><Change dt:dt="float">0.18</Change><PercentChange dt:dt="float">0.44</PercentChange><EPS dt:dt="float">2.87</EPS><PE dt:dt="float">14.28</PE><SharesOut dt:dt="float">100.00</SharesOut><Currency dt:dt="string">CAD</Currency><Exchange dt:dt="string">Toronto</Exchange><Type dt:dt="string">Equity</Type><CompanyName dt:dt="string"><![CDATA[CANADIAN PACIFIC]]></CompanyName></Quote></Quotes><Attributions><Timing><![CDATA[Quotes delayed at least 20 min]]></Timing><Attribution priority="1"><![CDATA[<a href="http://www.comstock-interactivedata.com"><img border="0" align="absmiddle" src="http://office.microsoft.com/Research/Images/splgo.gif" /></a> Quotes supplied by <a href="http://www.comstock-interactivedata.com">Standard & Poor's ComStock, Inc.</a>]]></Attribution><Attribution priority="1"><![CDATA[<a href="http://moneycentral.msn.com/investor/partsub/funds/mstar.asp"><img border="0" align="absmiddle" src="http://office.microsoft.com/Research/Images/mornlgo.gif" /></a> Fund data provided by <a href="http://moneycentral.msn.com/investor/partsub/funds/mstar.asp">Morningstar, Inc.</a>]]></Attribution><Attribution priority="2"><![CDATA[<a href="http://privacy.msn.com/tou">Terms of Use</a>]]></Attribution></Attributions><Warning>NoWarning</Warning></StockData>

    Now you'll want to let your users enter a stock symbol and the web part will do the lookup based on that value. Do this from inside FP2003 (I find you can't always perform a connection between a DVWP and another web part in the browser)

    1. Click on a zone and select Insert Web Part
    2. From the Task Pane select the Form Web Part and add it to the page
    3. Right click the Form Web Part in FP2003 and select Web Part Connections... from the popup menu
    4. Select Provide Form Values To in the action dropdown and click Next
    5. Select Connect to a Web Part on this page and click Next
    6. Choose the DVWP in the Target Web Part dropdown
    7. Choose Modify View Using Parameters From in the Target Action dropdown
    8. Select the column next to symbol (should be the second one) and select T1 as the dropdown value. T1 is the default name for the input field on the Form Web Part.
    9. Click Next then Finish to complete the connection

    You now have a connection from the Form Web Part to your DVWP. When a user enters a stock symbol in the Form Web Part and clicks on Go, the information is fed to the DVWP (mapping the value in T1 from the Form Web Part to the symbol parameter in the DVWP). This will re-invoke the webservice behind the DVWP with the symbol value updated and return the result.

    That's it! Live stock quotes from the Internet on your WSS/SPS site (this works with both) all without a single line of code. My XSLT knowledge is abysmal (read:none) so you'll have to bear with me on the formatting of the results here but I'm some of you are crafty enough to work with this. You'll probably want to format the XSLT so it displays something like this maybe:

    Symbol MSFT
    Last 27.01
    Change +0.04
    % Change +0.15%
    Volume 65.82 Mil
    Day's High 27.15
    Day's Low 26.83

    Or whatever works for you. Just do a match on the XML so you find the Last, Change, Volume, etc. nodes and make it pretty. (and if someone wants to email me a xsd file I'll update this post and probably learn about XSLT a little). In my effort to try to achieve this look from the XML returned from the web service, it keeps coming out the same. One big XML dump. Sigh.

    Hope that gets you started using Web Services with FP2003 and SharePoint. I'm sure you'll have other uses that make sense to you as this is just an example.

  • Corporate Branding with SPS

    I gotta love the web. Somehow, somewhere, you'll be taken to corners of the web you've never seen before and find little gems of information that otherwise you might stumble across someday if you get the right sequence of keywords pumped into Google. Thanks to Chris Johnson's blog I was pointed to 2 new documents on Corporate Branding with SPS. I've been doing a lot of customization work in SharePoint lately as we're building some apps (like a new contract management system) right into the application. Some of things we've done is pretty cool (like making it look like no matter where you are, WSS or SPS, you always see the same navigation metaphor).

    So here's two Office Development articles on branding your SPS site with some great examples and ideas (like being able to add new buttons to the action area that I didn't know before). Hope it helps you:

    Part 1, Understanding the Use of the Corporate Brand
    Part 2, How to Apply your Corporate Brand

  • Applying Permissions to Lists in Areas

    A nice feature of SharePoint Portal Server are areas. Think of an area as a mini-WSS site of it's own. You can create document libraries, custom lists, discussion threads, etc. all within an area. Items in the portal, including entire areas, have the added advantage over WSS sites of being able to use audience filtering and thereby only show content to those that it's aimed for (remember audience filtering is just what's presented, you still need to apply appropriate security to deny access to something to someone).

    Security for areas is the same as you would apply security anywhere else in SharePoint. You can add new users, change permissions, etc. (although when you select the advanced permissions for an area you get more options like being able to apply stylesheets, browsing directories, etc.) One of the issues security in an area is that if you have say several document libraries in that area, the security is the same for all libraries.

    When you select a list or document library (through the Manage Content option) in SPS, you'll see the typical interface like Change general settings, Delete this list, etc. What you won't see is the option that you see when you go into the settings in a list or library in a WSS site. Namely the Change permissions for this list option. When you apply permissions to an area (using the Manage Security option), you'll see the typical SharePoint interface to add users, etc. but no option to set permissions for a list or library. You can however still use a feature of SharePoint to apply individual permissions to a document library or list in the area, it just takes a little typing to get there.

    If you hover over the Change permissions for this list option in a WSS site, you'll see a url similar to the following:

    http://servername/sites/sitename/_layouts/1033/ShrOpt.aspx?obj={1234567A-BBBB-C999D9999999},list

    This is the page where you can set permissions for a list or document library (for document libraries, the end of the url will say ",doclib" instead of ",list"). The page exists in a virtual directory that's available to any WSS site and... portal area! This same url format can be used for an individual document library or list at the portal. You just need to know the GUID (the 1234567A number above). To find this out:

    1. Select Manage Content from there area where your document library or list lives in the portal
    2. Select the document library or list from the ones available
    3. Select Modify settings and columns for that list
    4. Take a look at the url you've gone to. You'll see listedit.aspx?List={... The numbers between the {} characters is the GUID for that list. The easiest way to get from this page to the ShrOpt page is to change the URL from this:
      http://servername/_layouts/1033/listedit.aspx?List={30BDBE4A-829A-4FD1-A237-D1D3D60EFF02}
      to this:
      http://servername/_layouts/1033/ShrOpt.aspx?obj={30BDBE4A-829A-4FD1-A237-D1D3D60EFF02},list
    5. Now you'll be at the Change Permissions: Document Library (or list) page
    6. Modify the permissions as you normally would, adding or removing users and setting up permissions.

    These permissions will only be applied to the document library and not to the entire area so you can now create read-only areas with editable lists. Enjoy!

  • Creating custom pages in SharePoint

    One of the really cool things about SharePoint is that you can create your own custom aspx pages like you would any ASP.NET application, but with a few tips you can leverage all the features of SharePoint like using web part zones and allowing customization and personalization.

    When creating a custom page be sure to inherit from WebPartPage. Here is how you get the navigation on your own page.

    1. Inherit from the WebPartPage class in your new webpage:

    <%@ Page language="C#" Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage,
    Microsoft.SharePoint,Version=11.0.0.0,
    Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>

    2. Create references to required tag libraries

    <%@ Register Tagprefix="SPSWC" Namespace="Microsoft.SharePoint.Portal.WebControls" Assembly="Microsoft.SharePoint.Portal, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

    3. Apply Theme server control

    <SHAREPOINT:THEME id="Theme1" runat="server"></SHAREPOINT:THEME>

    4. Add CSS Link server control

    <SharePoint:CssLink DefaultUrl="/_layouts/1033/styles/ows.css" runat="server" ID="Csslink2" />

    5. Add client-side script links

    <script src="_layouts/1033/owsbrows.js"></script>
    <script src="_layouts/1033/ows.js"></script>

    6. Create table and add navigation server controls

    <TABLE class="ms-main" CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%" HEIGHT="100%">
    <!-- Banner -->
    <TR valign="top">
    <TD COLSPAN="3" WIDTH="100%">
    <!--Top bar-->
    <table class="ms-bannerframe" border="0" cellspacing="0"
    cellpadding="0" width="100%">
    <tr>
    <td nowrap valign="middle"><img ID="onetidHeadbnnr0"
    alt="Logo" src="/_layouts/images/logo.gif"></td>
    <td class="ms-banner" width="99%" nowrap ID="HBN100"
    valign="middle">
    <!--webbot Bot="Navigation" startspan-->
    <SharePoint:Navigation LinkBarId="1002" runat="server" ID="Navigation1" />
    </td>
    <td class="ms-banner">&nbsp;&nbsp;</td>
    <td nowrap class="ms-banner" style="PADDING-RIGHT: 7px">
    <SharePoint:PortalConnection runat="server" ID="Portalconnection1" />
    </td>
    </tr>
    </table>
    </TD>
    </TR>
    </TABLE>

    That's it! Once you've done this your page is "SharePoint" ready. You can define web part zones (using FrontPage 2003) for your web designers and developers to add new webparts to for customization and personalization. Enjoy!