how to concatenate (part of) variable to String in XSLT - string

I would like to see the first couple of characters of the variable 'vari' to be concatenated to String abc=' here:
href="{concat('abc=', substring-before('vari', '='))}"
Here is the whole snippet:
<xsl:template match="report:subelement">
<tr>
<td>
<message>
<xsl:variable name="vari" select="."></xsl:variable>
<xsl:copy-of select="." />
</message>
</td>
<td>
<button type="button" onclick="window.location.href=this.getAttribute('href')" href="{concat('abc=', substring-before('vari', '='))}" >Kill thread</button>
</td>
</tr>
</xsl:template>
that is probably a trivial question but I am just learning xslt.

You are quite close, but:
To access the value of a variable you have to use an dollar ($) as prefix. Do not put variable name in apostrophe.
Therefore try:
href="{concat('abc=', substring-before($vari, '='))}
Than this will throw an error because your variable declaration is not in the same context as the usage.
The variable declaration has to be in the same element or in an ancestor. Put the declaration at the top of the subelement template or the in the <tr element.
Updated working template:
<xsl:template match=""report:subelement">
<xsl:variable name="vari" select="."></xsl:variable>
<tr>
<td>
<message>
<xsl:copy-of select="." />
</message>
</td>
<td>
<button type="button" onclick="window.location.href=this.getAttribute('href')"
href="{concat('abc=', substring-before($vari, '='))}" >Kill thread</button>
</td>
</tr>
</xsl:template>

Related

New table row in primefaces repeat

I have a list that I want to display in table along with radio buttons. UI Requirement is that there are grouped in table, 3 in a row. My idea was to use <p:repeat> and <p:fragment> on every third index to close last <tr> and open a new one.
Code is/was:
<table>
<tr>
<p:repeat
value="#{bean.arrayInBean}"
var="value" varStatus="status">
<td>
<span title="#{value.description}">
<input type="radio" value="#{value.code}"
name="valueName" /> #{value.code}
</span>
</td>
<p:fragment rendered="#{(status.index + 1) % 3 eq 0}">
</tr>
<tr>
</p:fragment>
</p:repeat>
</tr>
</table>
Unfortunately i get Error Parsing...The element type "p:fragment" must be terminated by the matching end-tag "</p:fragment>"

rich faces selectionChangeListener for two different column

I have a richtree like this :
<rich:tree id="positionTree"
value="#{positionAdminBean.positionTree}"
var="pos" switchType="ajax" binding="#positionAdminBean.htmlTree}"
nodeSelectListener="#{positionAdminBean.onCmdSelectPosition}"
ajaxSubmitSelection="true" reRender="positionPanel,mainTabbedPane,selectGroupPanel">
<rich:treeNode id="treeNodeId">
<table width="100%">
<tr>
<td width="50%">
<h:outputText value="#{pos.name}" id="treeposNameId"/>
</td>
<td width="40%">
<h:outputText value="#{pos.humanResourceName}" id="treeposHumanResName"/>
</td>
</tr>
</table>
</rich:treeNode>
</rich:tree>
these codes generate and show a tree of data correctly.
but my problem is that when you click on a row it fires nodeSelectListener="#{positionAdminBean.onCmdSelectPosition}".
as you see my tree has two columns , I need to do something with this code that every columns has its own select listener .
or do something that when user click on each columns it does different works
Well, a nodeSelectListener is fired when a node is selected. You can not assign it to something that is only a part of the node.
You can define an <a4j:jsFunction> and call it when the table cell is clicked.
<a4j:jsFunction name="firstColumnListener" actionListener="#{bean.doSomething}" … >
<a4j:param name="id" assignTo="#{bean.selectedId}" />
</a4j:jsFunction>
<td onclick="firstColumnListener(id)">
…
</td>

How can I apply an xslt template to a string?

Given a template used for building some html around a value, I want to pass in a string, rather than a node set. As an example I want to concat some values and pass that to the template. How can I achieve that sort of thing?
<xsl:template match="text()" mode="kvp-print-single">
<tr>
<td colspan="3"><xsl:value-of select="."/></td>
</tr>
</xsl:template>
...
<xsl:apply-templates select="concat=(haba/hiba:text(), ' - ', huba/baba:text())" mode="kvp-print-single"/>
ErrorMsg: xml or stylesheet file is invalid!
Exception: System.Xml.Xsl.XsltException: Expression must evaluate to a node-set.
If the aim is code re-use, to use the template in multiple places, then what you could do is give your template a name (in addition to the template match), and give it a default parameter
<xsl:template match="text()" name="kvp-print-single" mode="kvp-print-single">
<xsl:param name="text" select="." />
<tr>
<td colspan="3"><xsl:value-of select="$text"/></td>
</tr>
</xsl:template>
Then just use xsl:call-template to call it with you concatenated string as a parameter
<xsl:call-template name="kvp-print-single">
<xsl:with-param name="text" select="concat(haba/hiba:text(), ' - ', huba/baba:text())" />
</xsl:call-template>
Note, the template will still match "text()" nodes in the normal way when matched using xsl:apply-templates.
You could use call-template and a named template, rather than apply-templates, thus:
<xsl:template name="kvp-print-single">
<xsl:param name="theValue"/>
<tr>
<td colspan="3"><xsl:value-of select="$theValue"/></td>
</tr>
</xsl:template>
<xsl:call-template name="kvp-print-single">
<xsl:with-param name="theValue" select="concat(haba/hiba:text(), ' - ', huba/baba:text())"/>
</xsl:call-template>
The point of apply-templates is to take a nodeset, and apply the most appropriate template to each node in turn. call-template and named templates allows you to break up your XSLT into more manageable chunks, without changing the context.
You can't "pass in a string, rather than a node set" because templates are not called like functions. With XSLT, not the code controls the execution order but the data does by matching templates. It is possible to use named templates that can be called instead matched, but to pass values, you can use parameters for each templates.
In your case, you don't even have to as you can adress the text parts (given haba/hiba is the address) like so:
<xsl:template match="some_element" mode="kvp-print-single">
<tr>
<td colspan="3">
<xsl:value-of select="concat=(/root/haba/hiba/text(), ' - ', /root/huba/baba/text())"/>
</td>
</tr>
</xsl:template>
The adress needs to be correct XPath, of course (absolute or even relative to matching element).
#Mithon: The other answers require parameters. Use as many modularized templates as you want, but why would you want to add parameters if you don't need them?

DataView WebPart in sharepoint designer

I would like to display the list items using DataView WebPart and I am successful so far. But I would like to show the items in two columns for each row, instead of one columns per one row. How can i achieve this.
<tr>
<xsl:if test="position() mod 2 = 1">
<xsl:attribute name="class">ms-alternating</xsl:attribute>
</xsl:if>
<xsl:if test="$dvt_1_automode = '1'" ddwrt:cf_ignore="1">
<td class="ms-vb" width="1%" nowrap="nowrap">
<span ddwrt:amkeyfield="ID" ddwrt:amkeyvalue="ddwrt:EscapeDelims(string(#ID))" ddwrt:ammode="view"></span>
</td>
</xsl:if>
<xsl:variable name="ImageURL">
<xsl:value-of select="#ImageURL" />
</xsl:variable>
<td class="ms-vb">
<img alt="" src="{$ImageURL}" />
</td>
</tr>
I would like to show the items from a list in two columns and the table should be increased dynamically based on the number of items. Can someone guide me on how to achieve this.
Actually you can achieve this more easily with Item Lister Web Part. Try to check that out.

Compare Author to UserID in SharePoint XSLT

I've got a simple DataFormWebPart where I'm using XSLT to render out the contents of list. I want to compare the #Author field each list item to the current user, however the following won't evaluate to true:
in the header of the XSL:
<xsl:param name="UserID" />
and within the template that evaluates the rows:
<xsl:value-of select="#Author" />
<xsl:if test="#AuthorID = $UserID">(you)</xsl:if>
I have values for both #Author and $UserID:
#Author renders as a hyperlink to their user-profile
$UserID renders as the same text, but without the hyperlink.
What expression can I use to get the non-hyperlink value of the user-profile?
Found a quick win:
<xsl:value-of select="contains(#Author,concat('>',$UserID,'<'))" />
Should refer
https://sharepoint.stackexchange.com/questions/21202/custom-form-does-not-display-created-by-value
<tr>
<td valign="top" class="ms-formlabel"><nobr>Created by</nobr></td>
<td valign="top" class="ms-formbody">
<SharePoint:CreatedModifiedInfo ControlMode="Display" runat="server">
<CustomTemplate>
<SharePoint:FormField FieldName="Author" runat="server" ControlMode="Display" DisableInputFieldLabel="true" /><br/>
<SharePoint:FieldValue FieldName="Modified" runat="server" ControlMode="Display" DisableInputFieldLabel="true"/>
</CustomTemplate>
</SharePoint:CreatedModifiedInfo>
</td>

Resources