Reviewing for Black Magic Solutions for White Hat SharePoint

I have been working on reviewing drafts for the EUSP Black Magic Solutions for White Hat SharePoint project. The drive behind the project is to share the amazing things that can be done at the client side of SharePoint without the need for server access, Visual Studio or hard programming. Instead these solutions use the corner stone of web programming, javascript, to manipulate the both the end user experience and the back-end SharePoint data store to produce applications and interfaces that stretch the functionality of SharePoint into territory you would expect to pay thousands of pounds for from “proper” software houses.

So far I have reviewed Paul Tavares’ SharePoint in Agile: Managing an Agile Development Project. Even as someone who spends quite a bit of my time working with jQuery this was a revelation. The application is elegant and effective in itself and also achieves the aim of inspiring me to think of lots of other applications for these techniques, not only in SharePoint but other web applications I work on.

This is another really valuable initiative from the Nothing But SharePoint team and everyone should look out for the final version as it becomes available. For anyone disappointed with what seem to be the limitations of SharePoint or who feels that the barrier to development in the SharePoint corner of .NET are too high there are bound to be plenty of solutions to try.

I has also been a reason use Yammer for serious work.  Reviewing has been managed through the SPYam network.  While I have read a bit about Microsoft’s movement towards “social SharePoint” through Yammer, I had not really used it before.  Compared to other platforms/envrionments I have used for reviewing it has been a lot more free-form, and does tend to get a bit disjointed even thought there are only a few active participants.  As a serious social space it is pretty nice, but I think I need to commit a lot more effort to get the most out of it and I do wonder how I would manage dipping in and out if I was in a much larger/more active community.  So I will have to add it along with Twitter, Facebook, LinkedIn and Feedly as places to keep track of.

Publishing InfoPath Forms to SharePoint 2007 “The following URL is not valid:”

We have been making quite a bit of use of InfoPath forms recently and have published successfully to a number of sites across our farm.  However yesterday I tried to publish to a new site and got this error:

The following URL is not valid: https://…….

After a lot of googling I confirmed that this was not an uncommon error, but none of the scenarios matched our situation; i.e. we already have a root site and have been publishing successfully for some time, and could still publish to other sites.

After trying some test the culprit seems to be the Office SharePoint Server Publishing Infrastructure feature!

  • trying to publish to sites which have Office SharePoint Server Publishing Infrastructure enabled throws this error
  • publishing to a subsite which does not have Office SharePoint Server Publishing Infrastructure enabled works fine

It would have been nice to have seen this documented somewhere when I googled, but I suppose that is the danger of just searching.

URI encode Source attribute in SharePoint 2007 Data View Web Part calling an InfoPath form

In the previous post, Javascript in Data View Web Part XSLT, I showed how to use javascript to do things that XSLT alone cannot do in the SharePoint 2007 Data View Web Part.

The primary motivation for investigating this was wanting to

  • add a DVWP that showed items from a Forms Library
  • include in that DVWP a link that would open the InfoPath web form
  • direct the user back to the DVWP when he/she closed the InfoPath web form (including any querystring that could be used to filter the DVWP)

Creating a link to an InfoPath web form is tricky enough because of the syntax, but the real challenge was URI encoding the current page URL so that it could be used as the Source attribute and direct users back to the DVWP.

This approach calls a javascript function from the link column in the DVWP that constructs the InfoPath friendly URL and redirects the browser to that address.

This function uri encodes both the url and the query string and then inserts them as the Source attribute.

trgt = @FileDirRef

function uses trgt to calculate the subsite address for the /_layouts/FormServer.aspx url using trgt.substring(0,trgt.lastIndexOf(“/”))

(typically the DVWP will be showing the contents of the form library so this will work)

fn = @FileRef

This is the full file name of the form that is to be opened

Javascript in Data View Web Part XSLT

Javascript in Data View Web Part XSLT

One of the great frustrations working with XSLT in Data View Web Parts is the very limited set of functions available in XSLT 1.0 available in SharePoint 2007. However (as in so many things) javascript offers a solution.

This method is the simplest I have found and is based on posts at SharepointalistProgrammingsharepoint and  Sharepointboris.

Inserting the javascript functions

The method here works for inline scripts, but would probably also work with script references

  1. Locate the root XSLT template
  2. Insert the script within a CDATA tag

Calling the javascript functions

xsl:attribute

One method is to use xsl:attribute to build a link and add an onclick attribute

using parameters and writing results back to template

This example takes the formatted modified date, passes it through a javascript function, and writes out the result

The countup() javascript function ends with document.write(var); to output the result into the xslt

uriencode the page location for use the source element of a link

This would be particularly useful for making DVWPs portable and for working with InfoPath Form Libraries.  See URI encode Source attribute in SharePoint 2007 Data View Web Part calling an InforPath form for a solution that uses these techniques.

Adding links in SharePoint Data View Web Parts

I am sure this is well documented elsewhere, but it is something that always flummoxes me when I am working on a Data View in SharePoint Designer 2007. Typically you will want to add a link to the field in one of the columns in the data view so users can view the detail. One way to achieve this is with Web Part Connections that allow you to pass filter values to web parts on this or other pages.  However I was looking for a simple hyperlink that would open the list item view using the ID of the record.

<td>
<xsl:value-of select="@ows_LinkTitle"/>
</td>

However simply trying to use the concat function with strings of html fails to parse

<xsl:value-of select="concat(‘<a href="/research/resportal/events/Lists/Events/DispForm.aspx?ID=’, @ows_ID, ‘">’, @ows_LinkTitle, ‘</a>’)" />

There are two solutions to this

  • using the attribute tag: probably the right way to do this
  • creating a variable: almost certainly a lot slower, but more flexible

The Attribute Tag

The facility to add attributes to an <a> is built into XSLT

This approach elegantly mixes HTML and values

 

Creating a variable

The trick is to declare the HTML strings as variables and then concat these variables

<td class="ms-vb"> <xsl:variable name="L1Text">&lt;a href="/Events/DispForm.aspx?ID=</xsl:variable> <xsl:variable name="L2Text">"&gt;</xsl:variable> <xsl:variable name="L3Text">&lt;/a&gt;</xsl:variable> <xsl:value-of select="concat($L1Text, @ows_ID, $L2Text, @ows_LinkTitle, $L3Text)" disable-output-escaping="yes" /> </td>

The only two tricks are

  1. all HTML tags in the strings need to be escaped, i.e. &amp;
  2. set disable-output-escaping="yes"

As the variables are static they could be declared earlier in the XSL so the are not reset on each iteration.

Querying SharePoint 2007 Lists from InfoPath using XML

As a number of bloggers have noted, InfoPath does not read SharePoint lists quite as well as you would expect it to be able to do, at least in its 2007 incarnation.  The most obvious ways to query a SharePoint list have serious limitations

  • Creating a data connection using the SharePoint list wizard only allows lookups on the ID column (great for master->detail lookups but not a lot else)
  • Using the SharePoint web service GetListItems simply fails

The approach presented here builds on a Sharepoint Tips And Tricks article which explains these limitations and suggests an alternative approach.

Unlike in the article, in this situation we need to connect to SharePoint to look up a value in a list based on values on the InfoPath form, i.e using a respondent’s age, gender and body fat percentage the system returns a result ranging from “very lean” to “very fat” from a SharePoint list which has all the permutations for gender, body fat and ages (about 350 records).

By using an XML data source InfoPath is able to filter the SharePoint list data on arbitrary fields rather than just ID, in our case gender, age range and body fat.

Create an XML data connection

The process is the same as described in the article with one small exception.

  • add data connection
  • Choose XML
  • paste in the address in the form http://server/infopath/_vti_bin/owssvr.dll?Cmd=Display&List={listGUID}&XMLDATA=TRUE
    • http://server/infopath is the full path to the web where the list is found
    • {listGUID} is the list GUID (which can be found from the List Setting URL)
  • choose “Access the data from the specified location”
  • Give the data connection a name
  • Check “Automatically retrieve data when form is opened” (important!)
    • this is different from the article

The list data is now available to InfoPath, but with a few provisos.

Using the XML Data Connection

Opening http://server/infopath/_vti_bin/owssvr.dll?Cmd=Display&List={listGUID}&XMLDATA=TRUE in your browser will show you how SharePoint has “re-interpreted” the list data

  • all the column names are prefixed with “ows_” and use the “internal name” (i.e. no spaces)
  • number values are returned to thirteen decimal places
  • calculated columns are included (unlike in a SharePoint-type data connection), but the formatting may be different
    • in my case concatenating gender, age range identifier and body fat percentage returned a value  ows_uniq=”string;#Female130″

Bearing this in mind values from the XML data source can be used in the same way as other Secondary Data sources, in the XPath formula editor choose the column to return from within rs:data, z:row and click on the filter button to construct a filter.

Considerations

This approach seems to be well suited to my situation where

  • the form is lightly used by a small group of people
  • the SharePoint list data is effectively static
  • the SharePoint list contents are quite small

If this was not the case the option of writing a small webservice proxy might have been preferable.

Permanent URLs in SharePoint document libraries

We are looking to embed links to documents in SharePoint document libraries into spreadsheets and other documents to make it easier for users to quickly jump to the relevant document.  This is pretty trivial at one level, use right-click to copy the URL and paste into the target application, but what if the document moves?

I am not thinking of documents moving between document libraries, I am just thinking about documents to move from the “live” folder to the “archive” folder.  The problem is that the document URL includes the folder name.  This persists even if you change the view so that it does show folders.  Looking at the library in SharePoint Designer it is clear that SharePoint “actually” stores documents in folders.  In fact it looks as if the document does not have a guid but is linked to a particular list

Options

Redirection Library

A “global” solution that would not only accommodate this use case but would also manage the situation when content gets moved to another library would be implement something link the Zeven Seas Link Conductor which uses a redirection table to maintain redirection links.  While this is a neat solution it has drawbacks in the this instance

  • you would need to add an entry for every item even if it never moved
  • any changes have to be manually entered

Never move a document

Rather than using folders it would be possible to reorganise the library so that a column holds a status entry rather than moving documents from folder to folder.  The Encoded Absolute URL link would then remain the same.

In most circumstances this would be the most straightforward solution.

Other options

It would be great to hear if there are other options.