DataView WebPart in sharepoint designer - sharepoint

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.

Related

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?

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

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>

Sharepoint data view web part toolbar sorting default

I have a data view web part on a page which is displaying a table of data.
I want to allow users to choose which column to sort by. I think the only way to do this is go into the data view properties, and enable the toolbar with sorting. This works and allows the user to select a column to sort using a dropdown list of columns. The default is 'none', and when the page first loads, there is no sorting applied (rows are shown by their ID, which is pretty much random).
I want the default sort to be a particular column - i.e. when the page is first opened, I want the data to be sorted by a 'Surname' column. I can't figure out how to achieve this using the toolbar sort.
I have tried specifying an ORDER BY SURNAME in the SQL statement which gets the data - however this ends up overriding the toolbar sort, so sorting is always by surname, regardless of the toolbar sort selection.
There is another 'sorting' option in the data view properties which allows you to specify a sort, however again this overrides everything and renders the toolbar sorting option useless (selectiong something else has no effect).
I'm thinking surely there must be a solution to this simple problem?
The generated code for the sorting toolbar is below. I have tried making the surname the selected item in the dropdown box by changing to - this makes the surname column selected in the dropdown by default but the sorting isn't actually applied.
Any ideas?
<table cellSpacing="0" cellPadding="2" border="0" class="ms-toolbar" style="margin-left: 3px; margin-right: 5px;">
<tr>
<td id="dvt_tb_sort" nowrap=""><table><tr><td nowrap="" class="ms-toolbar"><nobr>Sort by: <select>
<xsl:variable name="clvar1_dvt_sortfield">&apos; + this.options[this.selectedIndex].value + &apos;</xsl:variable>
<xsl:variable name="clvar2_dvt_sortfield">&apos; + this.options[this.selectedIndex].fieldtype + &apos;</xsl:variable>
<xsl:variable name="clvar3_dvt_sortfield">&apos; + this.options[this.selectedIndex].title + &apos;</xsl:variable>
<xsl:variable name="clvar4_dvt_sortfield">&apos; + this.options[this.selectedIndex].sorttype + &apos;</xsl:variable>
<xsl:attribute name="OnChange">javascript:<xsl:value-of select="ddwrt:GenFireServerEvent(concat('NotUTF8;dvt_sortfield={', $clvar1_dvt_sortfield, '};dvt_sortdir={', $dvt_sortdir, '};dvt_sorttype={', $clvar4_dvt_sortfield, '}'))" /></xsl:attribute>
<option value="">None</option>
<option value="Location">
<xsl:if test="$dvt_sortfield='Location'">
<xsl:attribute name="selected">yes</xsl:attribute>
</xsl:if>
Location</option>
<option value="Email">
<xsl:if test="$dvt_sortfield='Email'">
<xsl:attribute name="selected">yes</xsl:attribute>
</xsl:if>
Email</option>
<option value="Mobile">
<xsl:if test="$dvt_sortfield='Mobile'">
<xsl:attribute name="selected">yes</xsl:attribute>
</xsl:if>
Mobile</option>
<option value="Position">
<xsl:if test="$dvt_sortfield='Position'">
<xsl:attribute name="selected">yes</xsl:attribute>
</xsl:if>
Position</option>
<option value="Telephone">
<xsl:if test="$dvt_sortfield='Telephone' and not($dvt_sorttype='number')">
<xsl:attribute name="selected">yes</xsl:attribute>
</xsl:if>
Telephone</option>
<option value="Telephone" sorttype="number">
<xsl:if test="$dvt_sortfield='Telephone' and $dvt_sorttype='number'">
<xsl:attribute name="selected">yes</xsl:attribute>
</xsl:if>
Telephone(Number)</option>
<option value="Forename">
<xsl:if test="$dvt_sortfield='Forename' or $dvt_sortfield=''">
<xsl:attribute name="selected">yes</xsl:attribute>
</xsl:if>
Forename</option>
<option value="Surname">
<xsl:if test="$dvt_sortfield='Surname'">
<xsl:attribute name="selected">yes</xsl:attribute>
</xsl:if>
Surname</option>
</select><a>
<xsl:attribute name="href">
<xsl:choose>
<xsl:when test="$dvt_sortdir='descending'">javascript:<xsl:value-of select="ddwrt:GenFireServerEvent(concat('dvt_sortfield={', $dvt_sortfield, '};dvt_sortdir={ascending}'))" /></xsl:when>
<xsl:otherwise>javascript:<xsl:value-of select="ddwrt:GenFireServerEvent(concat('dvt_sortfield={', $dvt_sortfield, '};dvt_sortdir={descending}'))" /></xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:if test="$dvt_sortfield" ddwrt:cf_ignore="1"><img border="0">
<xsl:attribute name="src">
<xsl:choose>
<xsl:when test="$dvt_sortdir='descending'"><xsl:value-of select="ddwrt:FieldSortImageUrl('Asc')" /></xsl:when>
<xsl:otherwise><xsl:value-of select="ddwrt:FieldSortImageUrl('Desc')" /></xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:choose>
<xsl:when test="$dvt_sortdir='descending'">Descending</xsl:when>
<xsl:otherwise>Ascending</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</img></xsl:if>
</a></nobr></td></tr></table></td><td width="99%"></td>
</tr>
</table>
James,
Search for the parameter binding labeled dvt_sortfield, then manually write in: Default="FIELDNAME" line.
This should do the trick.
ParameterBinding Name="dvt_sortfield" Default="ID" Location="Postback;Connection"
If you need to change the default sort there is also a sort parameter called dvt_sortdir and you can set it again in the ParameterBinding tag.
Dan
What happens if you select the Surname column first in the SQL?

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>

Outputting SharePoint Hyperlink Column as URL

I have some document URLs stored in a Sharepoint publishing column. When I output the info into a HTML page using:
<xsl:value-of select="#[ColumnName]" />
in ItemStyle.xml, I get [url], [document name] in the page. I would like to display this as a URL can anyone help with the XSL?
You could use:
<xsl:value-of select="substring-before(#[ColumnName],',')"/>
or whatever the separator is.
Thanks everyone, in the end I figured out the following based on a post at sguk
<xsl:variable name="Doc">
<xsl:call-template name="OuterTemplate.GetTitle">
<xsl:with-param name="Title" select="#DocumentLink1"/>
</xsl:call-template>
</xsl:variable>
with the following a tag code:
<a href="{substring-before($Doc,',')}">
<xsl:value-of select="substring-after($Doc,',')" />
</a>
or for an image:
<xsl:variable name="Image">
<xsl:call-template name="OuterTemplate.GetTitle">
<xsl:with-param name="Title" select="#img" />
</xsl:call-template>
</xsl:variable>
with the following img tag:
<img src="{substring-before($Image,',')}" alt="{substring-after($Image,',')}" />
I'm posting the solution back here as this proved ludicrously hard to figure out (probably my fault as I don't really 'get' XSL) but just in case anybody is looking for it, this code outputs images or links from the 'Hyperlink or Picture' column type in Sharepoint.
Another thing you can do is to take a list that shows URLs properly (like a Links list) and use SharePoint Designer to convert it to a DataView WebPart. In there will be the proper XSL for doing the conversion.
The easiest way to do this is with SharePoint designer:
click the field that shows "http://link, description"
a box with an > will appear, click it and you will get a "common xsl:value-of tasks" flyout.
It will have the field name and type, with the type set to "text".
Change the type to "hyperlink" and you will get a box allowing you to format the hyperlink. It will have all the necessary xsl already populated but you can input your own text or remove the link.
This hopefully helps. It shows "Project Site" when the hyperlink is entered and spaces when not.
<!--Project Site--><TD Class="{$IDAAO2UG}">
<xsl:variable name="Field" select="#Project_x0020_Site" />
<xsl:choose>
<xsl:when test="substring-before(#Project_x0020_Site, ', ')=''"><xsl:value-of select="substring-after(#Project_x0020_Site, ', ')" /></xsl:when>
<xsl:otherwise><A HREF="{substring-before(#Project_x0020_Site, ', ')}">
<xsl:choose>
<xsl:when test="substring-after(#Project_x0020_Site, ', ')=''"><xsl:value-of disable-output-escaping="no" select="substring-before(#Project_x0020_Site, ', ')" /></xsl:when>
<xsl:otherwise><xsl:value-of select="substring-after(#Project_x0020_Site, ', ')" /></xsl:otherwise>
</xsl:choose>
</A></xsl:otherwise>
</xsl:choose>
</TD>
In SharePoint 2013 you have to do things a bit differently because the #Url attribute is is no longer delimited with a comma. There is now a .desc sub property of #Url. Below is an example of how this works hopefully this saves someone else some time.
<xsl:template name="dvt_1.rowview">
<xsl:if test="string-length(#URL) > 0">
<div class="link-item item">
<a title="{#Comments}" target="_blank" href="{#URL}">
<xsl:value-of select="#URL.desc" />
</a>
</div>
</xsl:if>
</xsl:template>

Resources