Tuesday, May 1, 2007

Connecting to Two Web Parts with a Different Parameter for Each

Had a solution requiring a single drop-down list in a dataview web part to filter the contents of two other data view web parts, each of which required a different field as the input parameter - i.e. the Controls web part was to be filtered by Control Refs and the Gaps web parts was to be filtered by Gap Refs. The two fields (Control Refs and Gap Refs) are multi-select lookup columns in the Risks list.

After much experimentation (and a fair bit of cursing!), I found the answer.

The dropdown dataview uses the following code for each row. The important points to note are the concatenation of the two required field values in the fields variable, and the concatenation of the two consumer GUIDs in the GenFireCOnnection call.

<option>
    
<xsl:attribute name="value">
        
<xsl:variable name="cursel">dvt_curselkey={<xsl:call-template name="dvt.gencurselkey"><xsl:with-param name="RowPath" select="." /></xsl:call-template>}</xsl:variable>
        
<xsl:variable name="fields">@Control_x0020_Refs=<xsl:value-of select="ddwrt:ConnEncode(string(@Control_x0020_Refs))" />#@Gap_x0020_Refs0=<xsl:value-of select="ddwrt:ConnEncode(string(@Gap_x0020_Refs0))" /></xsl:variable>
        
<xsl:text>javascript:</xsl:text>
        
<xsl:value-of select="ddwrt:GenFireConnection( concat( 'g_1a7694bc_1a99_427e_aece_bcbfdf0ba2b9#g_c79865fa_2833_4543_aefe_0a8f466211aa*', $fields),string($cursel))"></xsl:value-of>
        
<xsl:text>;</xsl:text>
    
</xsl:attribute>
    
<xsl:if test="$dvt_curselkey=@ID">
        
<xsl:attribute name="selected">true</xsl:attribute>
    
</xsl:if>
    
<xsl:value-of select="@Risk_x0020_Ref" /> - <xsl:value-of select="@Title" />
</
option>

4 comments:

ashiena said...

If I understand it correctly, we have two list web part and one and filter with one dataview web part? (Which both list has relationship to the risk list?)

Where should I put the code you've given?

whats.to.learn.today said...

You are correct in your understanding - the page has two list view web parts, and one data view web part.

The data view web part is added using SharePoint Designer, and the type of the data view is changed to be a dropdown.

Then the code view of the data view web part is opened in SharePoint designer, and the XSL of the data view is adjusted as shown in the example in this post.

Hope that helps!

abdul said...

I have question not related to the post but related to DVWP, i hope that i get some help.

I have a page with 4 DVWP, in which one is the main and rest 3 are connected to it. the Main DVWP is a list with paging enabled. the data is sorted in ID desc showing the receent most on top. when user clicks on any item of that Main DVWP, the data of rest of the 3 DVWP is refreshed based on the slection, by default the first item is selected. this is working fine.

now there is a requirement that user wants to see data of 2nd, 3rd, or 4th item of main DVWP instead of first. i can passes ID or title of these 2nd, 3rd, or 4th item when calling this page but i cannot find way to tell those 3 DVWPs to show data for the 2nd, 3rd, or 4th item without clicking the Main DVWP item.

any solution?

whats.to.learn.today said...

Hi abdul,

I can't answer about the DVWP for sure as I have not tried that type of connection, but I would imagine that it is going to be hard to achieve that relationship between the main DVWP and the other three.

If i were given the taks of fulfilling that requirement, I personally would these tend to create a new main DVWP that is not connected to the other web parts through web part connections. Instead I would create a main DVWP with links that trigger client-side JavaScript calls to the lists web service.

In this approach, clicking on a link in the main DVWP could refresh the page, but add the ID of the selected item as a querystring value in the refreshed page's address. The other three web parts would then independently make client-side web service calls to get data from the related lists. You then have far more control over the connections, as you can edit the query in the web service calls to suit your exact requirements.

The nice thing about this approach is that there already a number of JavaScript framework that abstract the "nastiness" of generating the SOAP envelope for the web service calls. They make a web service call in JavaScript as simple as a method-call. One example of this is the SPAPI library - have a search for it.

Good luck, and hope this suggestion helps!