Web Part Zone “Feature”

Yes, let’s call it a feature.  Couldn’t be a bug, could it?

If you set a Web Part Zone to have a side-to-side (rather than the default top-to-bottom), i.e., horizontal layout, everything looks fine in SharePoint Designer.  However, when you go to your browser and look at the result, there will be a new table cell (TD) element on the right set to class=ms-spzonecaption with id=MSOZoneCell_emptyZoneText.  It seems to be a placeholder for a caption for the Web Part Zone of some sort.  The net result of this is that the things you want to display get "smushed" over to the left.  In the top-to-bottom layout, a corresponding <tr> does not get created.

As far as I can tell, there’s no way to eliminate this unwanted <td>, as it is not present in the code within SharePoint Designer, but seems to be generated at runtime.

One easy solution is to put your content or controls on the page outside a Web Part Zone. This means that you cannot interact with the controls through the browser.  In my case, I was building a toolbar with various links and dropdowns, so this wasn’t really a problem.

Eliminating Duplicates in Data View Web Parts

A Data View Web Part (DVWP) that displays a dropdown can be a useful tool to drive navigation.  See my previous post about showing content archives (Displaying an Archive for a SharePoint List) as an example.

If you have a decent number of items in the list you are using, you will likely end up with duplicates in your dropdown, which isn’t really what you want.  Here’s the trick to remove the duplicates.

When you add your DVWP, add your column for the dropdown, and set your DVWP layout to a dropdown view type, you will get a chunk of code like the following:

<xsl:template name="dvt_1.rowview">
  <option>
    <xsl:attribute name="value">
      <xsl:value-of select="@Your_x0020_Column" />
    </xsl:attribute>
    <xsl:value-of select="@Your_x0020_Column" />
  </option>
</xsl:template>

Find this code, and change it as follows:

<xsl:template name="dvt_1.rowview">
  <xsl:variable name="NewGroup" select="ddwrt:NameChanged(string(@Your_x0020_Column), 0)" />
  <xsl:if test="string-length($NewGroup)">
    <option>
      <xsl:attribute name="value">
        <xsl:value-of select="@Your_x0020_Column" />
      </xsl:attribute>
      <xsl:value-of select="@Your_x0020_Column" />
    </option>
  </xsl:if>
</xsl:template>

The ddwrt:NameChanged function will return a value only when the value of the column has changed since the last new value.

Next up: How to make something happen when the user selects a value from the dropdown.

Data View Web Part Parameters Based on Server Variables

I wanted to get at the site name to use in a Data View Web Part’s (DVWP) filter.  An example is where you have a site per project, with the project number being the site name and you want to based various filters on that value.  To do this, you can set up a parameter within the DVWP based on the value of the IIS Server Variable "URL" and parse out the project number using XSL.

Here are the steps (you will be doing all of this within SharePoint Designer — I’ll assume that you know how to set up DVWPs already):

  • Once you have your DVWP set up on your page, click on the Common Data View Tasks (the little > twiddle button in the upper right of the DWVP when you’ve highlighted it) and choose "Parameters…"
  • Click the "New Parameter" button
  • Give your parameter a name, and set the "Parameter Source" to "Server Variable"
  • For "Server Variable Name", type the text value of the Server Variable.  There’s no help here from Designer; you need to type the value exactly right or it won’t work.  See the link below for your options.  In this case, we’ll type "URL" (without the quotes).  Click OK when you are finished.
  • Now click on "Filter:".  Under "Field Name", select the column that you’d like to filter on, the "Comparison" (in this case "Equals"), and choose the Parameter that you just created in the dropdown for "Value".  Check the "Add XSLT Filtering" checkbox and click "Edit".
  • Enter the XSL to trim the value that you want out of the URL.  for example, if all of your projects are below http://servername/Projects/, then the XSL would look like [substring-after(substring-before($URL,'/default.aspx'), '/Projects/')]

Now the filter that you wanted should be in place.  XSL has its vagaries, so if you get an error at any step, use your old friend Ctrl-Z to step back and try again.

A full reference of the available IIS Server Variables is at this link:
http://msdn2.microsoft.com/en-us/library/ms524602.aspx

Note: I previously blogged on this method referencing a post from Maarten Eekels, but there are many more options, as outlined in the link above.

How to Remove {generate-id()} from a Customized Form in SharePoint

If you’ve done much work using custom forms in SharePoint, you’ve probably run into the {generate-id()} bugaboo. For reasons that I’ve not been able to determine, if you use an id attribute in any HTML element, SharePoint Designer adds the {generate-id()} string to the end of the name you’ve set. Here’s an example. If you code this:

<input id="SubmitButton" type="button" onclick="javascript:DoSomething()" Value="Submit" />

when you save the page, Designer converts your code to:

<input id="SubmitButton{generate-id()}" type="button" onclick="javascript:DoSomething()" Value="Submit" />

Not all that helpful. I found a nice fix for this from Jorge (El Che) Vasquez. Simply create an empty dummy variable, like:

<xsl:param name="DummyParameter" />

and append it to your id attribute:

<input id="SubmitButton{$DummyParameter}" type="button" onclick="javascript:DoSomething()" Value="Submit" />

Designer will then give you what you wanted in the first place.

Check out Jorge’s blog post for a richer explanation of this if you need more details.

Nice Trick to Filter Data in a Data View Web Part Based on the URL of the Web Page

As usual, while looking for something else, I found a great trick.  This one is from Maarten Eekels.  I’ve tried to figure out how to do this several times before, and Maarten shows a nice, simple, elegant solution for it.  Check out his blog post.