Wednesday, October 24, 2012

onclick attributes do not fire on custom search XSLT on a Publishing page

I had a requirement for a client this week to create a search solution for a custom list (for Contractors). Basically the client wanted to use SharePoint Search and a custom XSLT to render the list items. The two challenges I faced (without reverting to full on development):
  1. Make the results sort by the Company name. Note that OOB, the Core Search Results web part does not support this. It only supports sorting by date or relevance (which is the default).
  2. Open the results in a modal popup window, rather than redirecting the whole page to the list item.

To solve point 1, I found the blog entry http://ddkonline.blogspot.com.au/2011/12/sharepoint-2010-modifying-core-search.html which allowed me to change the sort order to company.
The second problem was more frustrating to solve. I thought that within the XSLT I would add the onclick element, calling a function to load the given URL into a SharePoint modal window. But every time I tried, the onclick event just wouldn't fire. I went back to simple onclick="alert('hello')" and it still didn't work.  Within the body of the page I added straight links, switched to HTML mode and added the onclick events there, but every time I did this, SharePoint would strip it out. The blog entry at http://blog.mastykarz.nl/tracking-links-google-analytics-sharepoint-2010-mavention-google-analytics-links-tracking/ then gave me a clue. Basically SharePoint was blocking basic onclick events from firing or removing them all together. So to solve the problem, I removed the onclick attributes, then embedded a jquery function within the XSLT to iterate through all links and add the onclick event. This time it worked. FYI, below is the XSLT block:   

<xsl:text disable-output-escaping="yes">  
<![CDATA[  
<script type="text/javascript" src="/_layouts/Inflow/cqwp.js"></script>  
<script type="text/javascript">  
$(document).ready(function () {    
  if ($("#results-table").length) {  
    $("#results-table a").click(function() {   
      openDialog($(this).attr('href'));   
      return false;  
    });    
  }  
});  
</script>  
]]>  
</xsl:text>  
<div class="srch-results" accesskey="W">  
<table id="results-table" border="1"> <tr><th>Company</th><th>Active / Inactive</th><th>Full Name</th></tr>  
<xsl:apply-templates select="All_Results/Result">    
<!-- The xsl-sort needs operate upon a single field - it doesn't work if the sort has to evaluate child nodes-->    
<xsl:sort select="company" />  
</xsl:apply-templates>  
</table>  
</div>  
<xsl:call-template name="DisplayMoreResultsAnchor" /> </xsl:template>
<!-- This template is called for each result -->
<xsl:template match="Result">  
<xsl:variable name="id" select="id"/>  
<xsl:variable name="currentId" select="concat($IdPrefix,$id)"/>
<xsl:variable name="url" select="url"/>
<tr><td>
<a id="{concat($currentId,'_Title')}">          
<xsl:attribute name="href">            
<xsl:value-of select="$url"/>          
</xsl:attribute>          
<xsl:attribute name="title">            
<xsl:value-of select="company"/>          
</xsl:attribute>         
<xsl:value-of select="company"/>        
</a>
</td>
<td><xsl:value-of select="activeinactive" /></td>
<td><xsl:value-of select="fullname" /></td>
</tr>
</xsl:template>