Firing an Event When a User Selects a Value from a Data View Web Part Dropdown

I was skimming my old postings, and I realized that in a previous post, I had said that I would post about firing an event when a user selects a value from a DVWP dropdown.  Better late than never, I guess.

When you create a dropdown type of DVWP through the UI in SharePoint Designer, the dropdown is created just fine, but there is absolutely nothing there to make that dropdown actually *do* anything.  Helpful, but not much.  Here’s how you can make it worth something.

In this example, my goal was to pass the chosen value to another page through the query string (There are other ways to do this, but for this client, there was auditing software that made having the value in the URL of use.) so that I could display the set of items that were created during a specific archive period.  (I had a calculated column that gave the archive period based on the published date — see this post on how that works.)

  • Add a DVWP to the page
  • Drop the column you want to see onto it
  • Change layout and choose the second from the bottom option — Dropdown menu of titles

To get at the query string variable ArchivePeriod (seen in the code below referred to as $ArchivePeriod) you go to the DVWP ‘Common Dataview Tasks’ (click on the little > button to the right on the DVWP), and set up a Parameter as seen in the screen snippet below.  If you search the code for the page for ArchivePeriod after doing this, you can see the effect of your actions.  You can, in fact, add the variable directly into code, as you see! (There are two lines for ArchivePeriod now.)

Data View Parameters

The key portions of the code that SharePoint creates when you add this DVWP to the page as in the three steps above are as follows:

<xsl:template name="dvt_1">
...
<select name="ID" size="1">
<option selected="true" value="0">Choose One...</option>
<xsl:call-template name="dvt_1.body">
<xsl:with-param name="Rows" select="$Rows" />
<xsl:with-param name="FirstRow" select="1" />
<xsl:with-param name="LastRow" select="$dvt_RowCount" />
</xsl:call-template>
</select>

and

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

While Designer has created a nice dropdown for you, nothing will happen if you make a selection; that work is left to you.  Here are the changes that I made; I’ve explained the changes below.

<xsl:template name="dvt_1">
...
<select size="1" onchange="HandleFilterSelection('default.aspx', 'PageFilterArchive.aspx', 'ArchivePeriod', this.options[selectedIndex].value)">
<xsl:choose>
<xsl:when test="not(string-length($ArchivePeriod))" >
<option value="0">Choose Dates</option>
</xsl:when>
<xsl:otherwise>
<option value="*">All Dates</option>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="dvt_1.body">
<xsl:with-param name="Rows" select="$Rows" />
</xsl:call-template>
</select>

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

function HandleFilterSelection(defaultpath, filterpath, parameter, selection)
{
if(selection == "*")
{
document.location.href = defaultpath;
}
else
{
document.location.href = filterpath + "?" + parameter + "=" + selection;
}
}
  • Line 3: Adding the onchange event allows you to provide an action if the value in the dropdown changes.  I decided to handle this in an externally stored Javascript function called HandleFilterSelection so that I could reuse it easily.
  • Lines 4-11: This xsl:choose lets me alter the prompt based on whether there is currently a filter in place or not.
  • Lines 18-19: This code lets me test to eliminate duplicate values.  This works because I have the list items sorted in descending order by Publish Date.
  • Lines 22-24: If the value is the currently selected value (i.e., it is driving the current filter on the page), this code lets me set it as the selection in the dropdown.
  • Lines 26-28: Unless you specifically set the value that will be returned for the selection, it’s an unpredictable number.  By setting it to the actual text of the selection, we can ensure the it is both recognizable and unique.

UPDATE 2009-05-01 — As a response to Patrick’s question below (It’s hard to include code in a comment.):

In my example, the HandleFilterSelection JavaScript was stored externally from the page because I used it in many places.  (I usually create a Document Library in the root site of the Site Collection called JavaScript to store .js files. I then include them in the pages where I want to use them by adding a <script src=”blah.js”> into the page.)

You can have the onchange event for the select do anything you want.  For example, I often just call the same page with a Query String parameter, like in the code snippet below:

<select name="SelectFluid" size="1">
<xsl:attribute name="onchange">
document.location =
&apos;<xsl:value-of select="$URL"/>&apos; +
&apos;?F=&apos; + this.options[selectedIndex].value;
</xsl:attribute>

To have this work, declare a parameter in the ParameterBindings section for the URL server variable (see my post entitled Data View Web Part Parameters Based on Server Variables for more on using IIS server variables):

<ParameterBinding Name="URL" Location="ServerVariable(URL)" DefaultValue=""/>

and then declare the parameter at the start of your XSL:

<xsl:stylesheet [...]>
<xsl:output method="html" indent="no"/>
<xsl:param name="URL"/>

Similar Posts

52 Comments

  1. hi,

    am using web part connection instead of document.location.href, how to stop drop-down setting back to displaying “Choose One” on selection on any value.

    Please help

      1. Anu:

        Your code didn’t come through. Web Part Connections never seem to work the way anyone wants them to. That’s why I alway build my own “connections” inmy DVWPs and script.

        M.

  2. Hi Marc,
    I am trying to use value of onchange event from drop down list using javascript for filtering ?
    In this post you are using javascript to get selected value .I want to use that value for filtering . How I can do that ?

    1. Hard to say, really. Note that I pass this.options[selectedIndex].value to the function, which contains the selected value. The JavaScript runs client side, so you can’t use the selection in your DVWP.

      M.

    1. As I said earlier, you can’t use script to grab the selected value and pass it to your DVWP directly. You’ll have to do a postback.

      M.

  3. Hi Marc,

    I just want to save the page that contains the drop down list. ie. the user can select names from the drop down list, and then save that page with the selections that they have made.
    Is this simple, or even possible? I’ve looked around but this is beyond my abilities… please help if you have the time.

    ps. thanks for the great posts that have got me thus far :-)

    1. Marcel:

      I’m not sure what you mean by “save the page”. Do you mean that you want to save the item to the list when the user makes a selection in the dropdown? If so, I’m not sure that would make for a very good UX – it’s easy to choose the wrong item in a dropdown.

      M.

  4. Hey Marc.

    I am at a complete loss with this (great way to start a post, huh?).

    Anyway..trying to do this. I have a SP links list, and all I want to do is create a dropdown list of the urls. Redirect on change.

    Can’t seem to wade through the spaghetti code and figure out what to modify.

    I can post code if you like. This post is so outdated now. I’m hoping you catch it.

    Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.