I'm putting asp server-controls into my SharePoint XSLT using SharePoint Designer. I've found it's really handy for pre-populating values into the form, or providing a different experience than the SharePoint defined layout (hidden fields, etc).
For example, I can use a asp:TextBox control instead of the SharePoint:FormField control if I define it as such:
<xsl:stylesheet ... xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime">
<xsl:param name="Name" />
<xsl:template match="/">
<!-- omitted for clarity -->
<asp:TextBox id="txtName" runat="server" Text="{$Name}"
__designer:bind="{ddwrt:DataBind('i','txtName','Text','TextChanged','ID',ddwrt:EscapeDelims(string(#ID)),'#MySharePointField')}"
</xsl:template>
</xsl:stylesheet>
I've googled but can't seem to find a good reference for the parameters for ddwrt:DataBind method.
Does anybody know?
The ddwrt:DataBind method is a wrapper for DataFormWebPart.AddDataBinding
The mysterious first parameter refers to the "operation". It will either be "i" (insert), "u" (update), or "d" (delete). Sadly, these are literal values because the XSLT doesn't have access to enumerations, etc.
The other curious fields are the propertyName and eventName, which are members of the control you're binding. The event is wired up using reflection to the sharepoint form, and the property is used to retrieve the value.
The remaining fields refer to the primary key and value to bind.
Full details on the method signature and how to use it can be found here
Related
I am really struggling to find a workable solution to this for Sharepoint Online/365.
Desired end result - Sharepoint list - View all items - Columns which are multi line append show the entries OR last entry within the all item view INSTEAD of the awful 'View Entries' link.
Solutions I have tried - I've tried to create a mirror column which is does not append and just copies information. I have created a flow which takes the information from the multi line append and copies it into the mirror column. However, this doesn't work as the updates are appending to the multi line column before the flow kicks in so it sees the column as blank and therefore copies nothing.
I am looking for any solutions or workarounds for this which will allow the 'View Entries' to be removed and the actual history to be displayed, or the most recent update, or show all or recent updates in the mirror column.
Thank you in advance.
It has been a while since you asked this, but I thought I would post a solution incase anyone else finds this in a Google search as I did.
I had SharePoint 2010 and had this working by making a new view using SharePoint Designer. I replaced <xsl:value-of select="#AppendField" disable-output-escaping="yes" /> with <SharePoint:AppendOnlyHistory FieldName="AppendField" runat="server" ControlMode="Display" ItemId="{#ID}"/>.
I am currently upgrading to SharePoint Online and this did not work when I copied the file from the old SharePoint host to the new one.
I re-created the view in SharePoint Designer (used 2013 for SharePoint Online) and the same code replacement gave an error, so I was searching for a solution.
I found a site that used the same tag, but the ItemId field was set different (instead of ItemId="{#ID}" it was ItemId="{$thisNode/#ID}").
I found the section of the code that referenced the AppendField and changed <xsl:value-of select="$thisNode/#*[name()=current()/#Name]" disable-output-escaping="yes"/> to be <SharePoint:AppendOnlyHistory FieldName="AppendField" runat="server" ControlMode="Display" ItemId="{$thisNode/#ID}" />.
Here are the code examples from SharePoint Designer (Change AppendField to be the name of your appended field):
Before (displayed "View Entries")
<xsl:template name="FieldRef_Note_body.AppendField" ddwrt:dvt_mode="body" match="FieldRef[#Name='AppendField']" mode="Note_body" ddwrt:ghost="" xmlns:ddwrt2="urn:frontpage:internal">
<xsl:param name="thisNode" select="."/>
<div dir="{#Direction}" class="ms-rtestate-field">
<xsl:value-of select="$thisNode/#*[name()=current()/#Name]" disable-output-escaping="yes"/>
</div>
</xsl:template>
After (displays the history in the view coilumn)
<xsl:template name="FieldRef_Note_body.AppendField" ddwrt:dvt_mode="body" match="FieldRef[#Name='AppendField']" mode="Note_body" ddwrt:ghost="" xmlns:ddwrt2="urn:frontpage:internal">
<xsl:param name="thisNode" select="."/>
<div dir="{#Direction}" class="ms-rtestate-field">
<SharePoint:AppendOnlyHistory FieldName="AppendField" runat="server" ControlMode="Display" ItemId="{$thisNode/#ID}" />
</div>
</xsl:template>
Here are the links I referenced when I found my solution:
https://social.technet.microsoft.com/Forums/windows/en-US/91e04d78-f2a5-466e-9a6b-fdd7b493d76d/display-entries-instead-of-quotview-entriesquot-option-in-multipleline-text-column-in?forum=sharepointadmin (another site where someone was having the same problem, but this is what led me to the next link)
https://www.brightwork.com/blog/show-content-sharepoint-2013-append-rtf-column-view#.WL9yLeS7pes (Good reference on how to create your own view)
https://mossipqueen.wordpress.com/2013/03/06/display-all-appending-field-entries-in-a-single-list-view/ (the site that showed the different ItemId that I used in my custom view)
Salve, folks! I have a choice field in my sharepoint page with choices like this:
(1) Go
(2) Warning
(3) Stop
Now, I want that to appear in the list as an icon instead of text. I have a working jquery script for that, but it takes to long to search through all the list for the contained text, and it would be better to use xsl anyway because it renders before it is displayed.
So how can I accomplish this in xsl? Here is as far as I have gotten, as I am only learning xsl:
<xsl:stylesheet
xmlns:x="http://www.w3.org/2001/XMLSchema"
xmlns:d="http://schemas.microsoft.com/sharepoint/dsp"
version="1.0"
exclude-result-prefixes="xsl msxsl ddwrt"
xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
xmlns:asp="http://schemas.microsoft.com/ASPNET/20"
xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:SharePoint="Microsoft.SharePoint.WebControls"
xmlns:ddwrt2="urn:frontpage:internal">
<!-- Convert the Scope Field into an icon -->
<xsl:template match="FieldRef[#Name='Scope']">
<xsl:param name="thisNode" select="."/>
<xsl:choose>
<xsl:when test="$thisNode/#Scope='(1) Go'">
<td class="statusRating1"></td>
</xsl:when>
<xsl:when test="$thisNode/#Scope='(2) Warning'">
<td class="statusRating2"></td>
</xsl:when>
<xsl:when test="$thisNode/#Scope='(3) Stop'">
<td class="statusRating3"></td>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$thisNode/#Scope" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Here is the css I want to apply:
.statusRating1{background-image: url("/_layouts/custom/images/go.png"); }
.statusRating2{background-image: url("/_layouts/custom/images/warning.png"); }
.statusRating3{background-image: url("/_layouts/custom/images/stop.png"); }
Now, I've tried this with and without mode="Choice_body" or mode="MultiChoice_body and even Text_body, and have also tried adding <xsl:apply-templates />
but it never even seems to hook. The column is definitely named "Scope". Maybe I just have to add the right mode?
In firebug, I can see that the class is never added.
[update] I have noticed that in other places where I have used the template in this fashion, that the template never "took" unless it had the correct mode defined. However, I've googled the world over and can't find the right mode to use for a choice field. I even created a question for that, here. Also, the use of thisNode is from Microsoft's examples, where you can modify field types very easily (except in the case of this here choice field).
In order to define Custom Rendering for a SPFieldChoice field in template for mode attribute should be used value body
Template for modes with names Choice_body MultiChoice_body are not defined.
So, in your case template would look like this:
<xsl:template match="FieldRef[#Name='Scope']" mode="body">
Template mode attributes defined for rendering SharePoint fields are not documented, but you could find this information in %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\LAYOUTS\XSL\fldtypes.xsl. See implementation of template PrintField for details.
Hope this helps,
Vadim
The fact that you have written a template isn't enough for this template ever to be executed.
And if it is selected for execution by the code of the XSLT built-in (default) templates, these templates don't know about any parameter named $thisNode, and don't pass such parameter to your template.
This means that the value of the$thisNode parameter when the template is initiated is the empty string -- therefore none of the xsl:when test conditions is satisfied and thus the xsl:otherwise is chosen.
Solution:
Either:
Have an explicit xsl:apply-templates in your code, that selects the nodes to be matched by the tempate, or:
Delete the <xsl:param> and replace in the code every occurence of $thisNode with ..
I'm working in a list with a custom NewForm.aspx and a custom EditForm.aspx, which I've called New.aspx and Edit.aspx. I'm far from a SharePoint expert, but it looks like the only differences between the two files are the miscellaneous ControlMode attributes set throughout the file.
ControlMode="New" for New.aspx and ControlMode="Edit" for Edit.aspx
As a test, I took the code from my New.aspx and copied it into my Edit.aspx and just changed the ControlMode attributes to 'Edit.' Everything seems to be working fine. So what I'd like to do is just use one file rather than a separate one for New and Edit. I'm not sure if this is possible, but the first step I took was to create an XSL variable:
<xsl:variable name="ControlMode" select="'Edit'" />
Then I can do something like this:
<xsl:choose>
<xsl:when test="$ControlMode = 'New'">
<SharePoint:AttachmentUpload runat="server" ControlMode="New"/>
<SharePoint:ItemHiddenVersion runat="server" ControlMode="New"/>
</xsl:when>
<xsl:when test="$ControlMode = 'Edit'">
<SharePoint:AttachmentUpload runat="server" ControlMode="Edit"/>
<SharePoint:ItemHiddenVersion runat="server" ControlMode="Edit"/>
</xsl:when>
</xsl:choose>
My form is still working fine at this point, but it's still two different files. So the question is, does anyone know a way I can populate the xsl:variable dynamically so that I can specify just one file for new and edit modes?
Thanks in advance!
I'm not sure if answering my own question is correct etiquette or not, but I found my answer... turns out to be much simpler than I thought.
As I was reading Brian's reply, it occurred to me that editing a post changes the query string. There's an ID specified of course. So I started looking for the best way to parse the query string. That's when I realized that this is already done for me in the ParameterBindings:
<ParameterBinding Name="ListItemId" Location="QueryString(ID)" DefaultValue="0"/>
The xsl:param tag was not specified however, so I added this to the top of my xsl:stylesheet:
<xsl:param name="ListItemId"></xsl:param>
Then, instead of using the ControlMode variable that I created in my original post, I can now test directly against the ListItemID:
<xsl:choose>
<xsl:when test="$ListItemId = '0' or not($ListItemId)">
<SharePoint:AttachmentUpload runat="server" ControlMode="New"/>
<SharePoint:ItemHiddenVersion runat="server" ControlMode="New"/>
</xsl:when>
<xsl:otherwise>
<SharePoint:AttachmentUpload runat="server" ControlMode="Edit"/>
<SharePoint:ItemHiddenVersion runat="server" ControlMode="Edit"/>
</xsl:otherwise>
</xsl:choose>
Basically, I'm just checking for a 0 value (the default specified in the ParameterBinding) and showing different controls.
I've been testing this for a bit this afternoon, and thus far it works brilliantly.
the built in sharepoint controls will attempt to function differently based on the control mode defined. Obviously if it is edit, then it will attempt to not only just render a control but populated that control with the current value. If the mode is new, it will simply render the control without a predefined value. There's a lot more to it but that's the high level overview.
If you are using custom new vs edit form I'd personally keep them seperate for the organizational purposes. An easy solution would be to use an XSL include after you have defined the variable inside each pages form.
I', trying to display the Body property of an Announcements List in my CQWP, but it is always blank.
In CommonViewFields I've tried to set Body type to Text, RichHTML, Note... all with no result. Also, as suggested elsewhere. I've tried disable-output-escaping="yes" in the xsl. Nothing changed.
Printing out the passed key / values reveals that Body is empty. It should be not.
<xsl:for-each select="#*">
Key:<xsl:value-of select="name()" />
Value:<xsl:value-of select="."/>
</xsl:for-each>
Any help?
Generally when you need to output HTML that exists in your data source (or any kind of "result tree"), try invoking the xsl:copy-of element.
To use your example, it would look like:
<xsl:for-each select="#*">
Key:<xsl:value-of select="name()" />
Value:<xsl:copy-of select="." />
<xsl:for-each select="#*">
What I would like to do is the following:
I'm currently deploying a huge collection of lists and codebehind. But, what I also want to deploy is the 'visual side' of the package. But, currently, this is done using Sharepoint Designer 2010.
My guess is that all the modifications I do in Sharepoint Designer 2010 can be done in one way or another in Visual Studio 2010, using either the Schema.xml of the view, or codebehind. I don't really mind either.
I can't have any static XSL transforming though. My XSL file will be based on the recently added dynamic columns, and I want to start with something like this.
<xsl:include href="/_layouts/xsl/main.xsl"/>
<xsl:include href="/_layouts/xsl/internal.xsl"/>
<xsl:param name="AllRows" select="/dsQueryResponse/Rows/Row[$EntityName = '' or (position() >= $FirstRow and position() <= $LastRow)]"/>
<xsl:param name="dvt_apos">'</xsl:param>
<xsl:template name="FieldRef_User_body.Employee" ddwrt:dvt_mode="body" match="FieldRef[#Name='Employee']" mode="User_body" ddwrt:ghost="" xmlns:ddwrt2="urn:frontpage:internal">
<xsl:param name="thisNode" select="."/>
<span>
<xsl:attribute name="style">
<xsl:if test="normalize-space($thisNode/#Employee) = 'Mats-PC\Mats'" ddwrt:cf_explicit="1">background-color: #DEF0FA;</xsl:if>
</xsl:attribute>
<xsl:value-of disable-output-escaping="yes" select="$thisNode/#*[name()=current()/#Name]" />
</span>
</xsl:template>
To explain, this will set the background colour to something else when the Employee value (Of type User) is equal to 'Mats-PC\Mats'
How would I go and make this dynamic, and add this to that one view? I've looked in the SPView object, and all I see is Xsl and XslLink, but I have no clue what to do with them. Any ideas?
Greetings,
Mats
Grab a copy of SharePoint Manager to get a look at the values of objects in a SharePoint instance. The properties Xsl is usually used to store the Xsl that will be used to render the view, but if a url is provided in XslLink, that will override and pull out the Xsl from there. You may have trouble with xsl some includes because of SharePoint security.