Solved

How To Call XSL Template With Parameter From OnClick Event

Posted on 2003-11-03
6
2,195 Views
Last Modified: 2010-10-05
I need to be able to allow users to click on a link from a summary page and open up a detailed window based on what was chosen.  How do I call an XSL template with a parameter from an OnClick event?

Is this possible with or without javascript?  I have tried many things with no success.

In its simplest form, here's what I'm trying to do.  Thanks!

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml:stylesheet type="text/xsl" href="test.xsl"?>
<INVENTORY>
      <ITEM>
            <ITEM_NO>1</ITEM_NO>
            <SUMMARY_INFO>Summary Info</SUMMARY_INFO>
            <DETAILS>
                  <DETAIL_INFO>Detail Info</DETAIL_INFO>
            </DETAILS>
      </ITEM>
</INVENTORY>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="html" indent="no"/>
      <xsl:template match="/">
            <html>
                  <head>
                        <script language="javascript" type="text/javascript">
                        <!-- //
                              function callDetail(item_no)
                              {
                                    <xsl:call-template name="detail">
                                          <xsl:with-param name="item_input">
                                                <xsl:value-of select="$item_no"/>
                                          </xsl:with-param>
                                    </xsl:call-template>
                              }
                        // End -->
                        </script>
                  </head>
                  <body leftmargin="0" marginwidth="0" topmargin="0">
                        <xsl:variable name="item_no" select="'1'"/>
                        <a href="#" onclick="callDetail($item_no)">
                              &#160;<xsl:value-of select="INVENTORY/ITEM[ITEM_NO=$item_no]/SUMMARY_INFO"/>
                        </a>
                  </body>
            </html>
      </xsl:template>

      <xsl:template name="detail">
            <xsl:param name="item_input"/>
            <html>
                  <head>
                  </head>
                  <body leftmargin="0" marginwidth="0" topmargin="0">
                        <xsl:copy-of select="INVENTORY/ITEM[ITEM_NO=item_input]/DETAIL_INFO"/>
                  </body>
            </html>
      </xsl:template>
</xsl:stylesheet>
0
Comment
Question by:bparmelee
  • 3
  • 2
6 Comments
 
LVL 15

Expert Comment

by:dualsoul
ID: 9676446
hm...i know how to do that with Xalan4J XSL Tarnsformer, may be it will help you, ot at least give some idea:

1) declare stylesheet paramter within your xslt:
.....................
<?xml version="1.0"
encoding="windows-1251"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:link="http://www.whitestudio.ru/java/SiteManager.site.LinkGenerator"      
            exclude-result-prefixes="link"
                >
       <xsl:param name="link"/> <!-- here is the stylesheet parameter -->
.....................................

2) use Transformer methods to assign value to this parameter (sample in Java):
      transformer.setParameter("link",link);                  

  I think if you have Transformer object you can do similiar in any language.

Alternative:
     1) use extension-funstions to pass you parameter
 

or i don't understand what do you want? :)
0
 

Author Comment

by:bparmelee
ID: 9680002
I'm not sure how this would allow me to call a template with that parameter from the onClick event in an anchor in the xsl page.  Thanks!
0
 
LVL 15

Expert Comment

by:dualsoul
ID: 9688406
you want just to call template from onClick event?
so use javascript for this, what's wrong?
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 

Author Comment

by:bparmelee
ID: 9690418
I cannot call-template from the javascript.  See the code I posted.  It doesn't work, nor any of the many variations I tried.
0
 
LVL 6

Accepted Solution

by:
PeterCiuffetti earned 500 total points
ID: 9694819
The fundamental problem to the approach you are trying is that the XSL processing instruction...

<?xml:stylesheet type="text/xsl" href="test.xsl"?>

...is done once, immediately upon loading the document resulting in an HTML object.  This result is then like any static HTML file that then goes through Javascript event handling.  The OnClick event handling is done much later when the user starts interacting with the transformed document.  By this time the XSL processing is long over.  XSL template handling is a set of operations that fire when the document is read.  There is no opportunity to influence the processing with user input.

If you want your javascript to perform XSL functionality that varies based on user input, then you have to run your transforms using MSXML and set up runtime parameters using MSXML method calls.

The way you've done it, the value of your variable $item_no is set inside your XSL file and is read only.  To have the XSL processing use a run-time varaible set by user input, you have to use a 'top-level' param (i.e. not iside a template) in the XSL.  These can be modified via the XSLT api with an addParameter instruction  To illustrate, the following XML produces an HTML page with javascript links that each choose a different section of the XML file based on which hyperlink is clicked:


Given the following test document:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml:stylesheet type="text/xsl" href="test.xsl"?>
<INVENTORY>
     <ITEM>
          <ITEM_NO>1</ITEM_NO>
          <SUMMARY_INFO>Summary Info 1</SUMMARY_INFO>
          <DETAILS>
               <DETAIL_INFO>Detail Info 1</DETAIL_INFO>
          </DETAILS>
     </ITEM>
     <ITEM>
          <ITEM_NO>2</ITEM_NO>
          <SUMMARY_INFO>Summary Info 2</SUMMARY_INFO>
          <DETAILS>
               <DETAIL_INFO>Detail Info 2</DETAIL_INFO>
          </DETAILS>
     </ITEM>
     <ITEM>
          <ITEM_NO>3</ITEM_NO>
          <SUMMARY_INFO>Summary Info 3</SUMMARY_INFO>
          <DETAILS>
               <DETAIL_INFO>Detail Info 3</DETAIL_INFO>
          </DETAILS>
     </ITEM>
</INVENTORY>

...and test.xsl stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="html" indent="yes"/>

<xsl:template match="/">
          <html>
               <head>
                    <script language="javascript" type="text/javascript">
                    <xsl:comment> //
                         function callDetail(item_no)
                                     {
                                           // load the detail stylesheet
                                          var xslt = new ActiveXObject("Msxml2.XSLTemplate.4.0");
                                          var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.4.0");
                                          var xslProc;
                                          xslDoc.async = false;
                                          xslDoc.resolveExternals = false;
                                          xslDoc.load("detail.xsl");
                                          if ( xslDoc.parseError.errorCode != 0 ) {
                                            var myErr = xmlDoc.parseError;
                                            alert("You have error " + myErr.reason);
                                          } else {
                                                // process the inventory through the detail stylesheet
                                                xslt.stylesheet = xslDoc;
                                                var xmlDoc = new ActiveXObject("Msxml2.DOMDocument.4.0");
                                                xmlDoc.async = false;
                                                xmlDoc.resolveExternals = false;
                                                xmlDoc.load("test.xml");
                                                if (xmlDoc.parseError.errorCode != 0) {
                                                  var myErr = xmlDoc.parseError;
                                                  alert("You have error " + myErr.reason);
                                                } else {
                                                  xslProc = xslt.createProcessor();
                                                  xslProc.input = xmlDoc;
                                                  // pass the function parameter to the stylesheet and transform
                                                  xslProc.addParameter("item_input", item_no );
                                                  xslProc.transform();
                                                  if (document.all) {       
                                                        document.write(xslProc.output);
                                                  }
                                                }
                                          }
                                     }
                    // End </xsl:comment>
                    </script>
               </head>
               <body leftmargin="0" marginwidth="0" topmargin="0">
                           <!-- Create a link for each item of inventory -->
                           <xsl:for-each select="INVENTORY/ITEM">
                                 <h3>Click below to see item <xsl:value-of select="ITEM_NO"/></h3>
                    <a href="#">
                                    <!-- compute the onclick attribute based on the item_no -->
                                    <xsl:attribute name="onclick">
                                          <xsl:text>javascript:callDetail(</xsl:text>
                                          <xsl:value-of select="ITEM_NO"/>
                                          <xsl:text>)</xsl:text>
                                    </xsl:attribute>
                        &#160;<xsl:value-of select="SUMMARY_INFO"/>
                    </a>
                        </xsl:for-each>
               </body>
          </html>
     </xsl:template>

</xsl:stylesheet>

When you load test.xml into IE, test.xsl will produce a menu of links, one for each inventory item.  Note how the onclick attribute of each link is computed on this first pass using xsl:attribute.  You could have just as easily produced a form with a dropdown list or somthing like that.

The callDetail javascript function takes the parameter and calls another stylesheet (detail.xsl) to output the requested detail.  Note how the xslProc.addParameter passes the function parameter to the detail.xsl stylesheet.  The result of the transformation is then written to the browser.

The detail.xsl looks like this

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:param name="item_input" select="'1'"/>

<xsl:template match="/">
          <html>
               <head>
               </head>
               <body leftmargin="0" marginwidth="0" topmargin="0">
                    <xsl:copy-of select="INVENTORY/ITEM[ITEM_NO=$item_input]/DETAILS/DETAIL_INFO"/>
               </body>
          </html>
</xsl:template>

</xsl:stylesheet>

To run this code, paste the xml into test.xml, the first xsl into test.xsl and the second xsl into detail.xsl.  Then load test.xml with IE.
0
 

Author Comment

by:bparmelee
ID: 9698738
This works great!  Thank you so much!
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Suggested Solutions

The Problem How to write an Xquery that works like a SQL outer join, providing placeholders for absent data on the outer side?  I give a bit more background at the end. The situation expressed as relational data Let’s work through this.  I’ve …
The Confluence of Individual Knowledge and the Collective Intelligence At this writing (summer 2013) the term API (http://dictionary.reference.com/browse/API?s=t) has made its way into the popular lexicon of the English language.  A few years ago, …
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now