September 2011
Current page:
 

SharePoint custom field XSLT rendering with custom properties

By: Vladi Gubler | Comments [0] | Category: Development | 9/22/2011

Hi,

For our new product, URL Plus Field, we needed to render a field value different depending on field settings. For instance, you can set to open links in a new window or replace the description text with an icon. In 2007, this is pretty easy, once you define your custom property as an attribute of field schema (do not use PropertySchema, you must set you custom values as attributes, you can do that by directly manipulating the underlying XML in your field class). In 2010, there is no way (as far as I can tell, please enlighten me) to know what the field values are in the XSLT rendering.

First we tried to fall back to old school CAML rendering by setting CAMLRendering property to true. That basically brought the whole list rendering down with an error, it is something specific to URL fields, as it works fine with text or number fields.

So I needed to come up with a way to get the property values and keep the XSLT rendering. After spending an entire day looking for a solution, approaching it from different angle and basically pulling my hair out, I still was nowhere near the solution.

The break came the next day, when I had an idea - if I cannot read the properties, maybe I can incorporate the property values as part of the item value (the URL itself). AND IT WORKED!!!

What I did was override the GetFieldValue method of my field class:

public override object GetFieldValue(string value) 
  {
          if (IsSharePoint2010)   
        {     
          if (string.IsNullOrEmpty(value)) 
                return value;
                 return value + string.Format(",{0},{1},{2},{3}", DisplayFormat, ShowAsIcon, IconUrl, OpenInNewWindow);   
       }  
          else     
           return base.GetFieldValue(value);  
       }

Here I'm basically checking if the current SharePoint version is 2010 (using a helper method that compare the build version of the local farm to 12, which is 2007), if not, I attach my additional property values to the URL itself. Now we are getting the property value in XSLT through the back door :)

So now we can use these values in our XSLT template.

Using the following two helper templates I can split my field value into parts and get value of each separate part:

This template split the value into sort of an array (in the XSL world):

<xsl:template name="IWURLPLUStokens">
    <xsl:param name="str" select="."/>
    <xsl:param name="splitString" select="','"/>
<xsl:choose>
      <xsl:when test="contains($str,$splitString)">
        <token>
          <xsl:value-of select="substring-before($str,$splitString)"/>
        </token>
        <xsl:call-template name="IWURLPLUStokens">
          <xsl:with-param name="str"    select="substring-after($str,$splitString)"/>
          <xsl:with-param name="splitString" select="$splitString"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <token>
          <xsl:value-of select="$str"/>
        </token>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

And this one will return value according to index:

  <xsl:template name="IWURLPLUSGetPartAtIndex">
    <xsl:param name="splits"/>
    <xsl:param name="index"/>
    <xsl:value-of select="msxsl:node-set($splits)/token[position()=$index]"/>
  </xsl:template>

So now we can split our value into the URL itself (index=1) and the property values (the other 4 parts in our example).

Using the regular XSLT template we can now use these values to produce the exact outcome that we need in any XSLT view!

 <xsl:template match="FieldRef[@FieldType='UrlPlusField']" mode="URL_body">
    <xsl:param name="thisNode" select="." />
    <xsl:variable name="thisValue" select="$thisNode/@*[name()=current()/@Name]"/>
    <xsl:variable name="url">
      <xsl:choose>
        <xsl:when test="contains($thisValue, ',')">
          <xsl:value-of select="substring-before($thisValue, ',')" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$thisValue" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:variable name="splits">
      <xsl:call-template name="IWURLPLUStokens">
        <xsl:with-param name="str" select="$thisValue"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="displayFormat">
      <xsl:if test="contains($thisValue, ',')">
        <xsl:call-template name="IWURLPLUSGetPartAtIndex">
          <xsl:with-param name="splits" select="$splits"/>
          <xsl:with-param name="index" select="2"/>
        </xsl:call-template>
      </xsl:if>
    </xsl:variable>
    <xsl:variable name="openInNewWindow">
      <xsl:if test="contains($thisValue, ',')">
        <xsl:call-template name="IWURLPLUSGetPartAtIndex">
          <xsl:with-param name="splits" select="$splits"/>
         <xsl:with-param name="index" select="5"/>
        </xsl:call-template>
      </xsl:if>    </xsl:variable>
    <xsl:variable name="showAsIcon">
      <xsl:if test="contains($thisValue, ',')">
        <xsl:call-template name="IWURLPLUSGetPartAtIndex">
          <xsl:with-param name="splits" select="$splits"/>
          <xsl:with-param name="index" select="3"/>
        </xsl:call-template>
      </xsl:if>
    </xsl:variable>
    <xsl:variable name="iconUrl">
      <xsl:if test="contains($thisValue, ',')">
        <xsl:call-template name="IWURLPLUSGetPartAtIndex">
          <xsl:with-param name="splits" select="$splits"/>
          <xsl:with-param name="index" select="4"/>
        </xsl:call-template>
      </xsl:if>
    </xsl:variable>

    <xsl:variable name="desc" select="$thisNode/@*[name()=concat(current()/@Name, '.desc')]" />
    <xsl:choose>
      <xsl:when test="$url=''">
      </xsl:when>
      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="$displayFormat='Image'">
            <img src="{$url}" alt="{$desc}" />
          </xsl:when>
          <xsl:otherwise>
            <a href="{$url}" >
              <xsl:if test="$openInNewWindow='Always'">
                <xsl:attribute name="target">_new</xsl:attribute>
              </xsl:if>
              <xsl:choose>
                <xsl:when test="$showAsIcon='True'">
                  <img border="0">
                    <xsl:attribute name="alt">
                      <xsl:choose>
                        <xsl:when test="$desc=''">
                          <xsl:value-of select="$url"/>
                        </xsl:when>
                        <xsl:otherwise>
                          <xsl:value-of select="$desc"/>
                        </xsl:otherwise>
                      </xsl:choose>
                    </xsl:attribute>
                    <xsl:attribute name="src">
                      <xsl:choose>
                        <xsl:when test="$iconUrl='Link'">/_layouts/images/LINK.GIF</xsl:when>
                        <xsl:when test="$iconUrl='Help'">/_layouts/images/hhelp.gif</xsl:when>
                        <xsl:when test="$iconUrl='Warning'">/_layouts/images/WARN16.GIF</xsl:when>
                      </xsl:choose>
                    </xsl:attribute>
                  </img>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:choose>
                    <xsl:when test="$desc=''">
                      <xsl:value-of select="$url"/>
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:value-of select="$desc"/>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:otherwise>
              </xsl:choose>
           </a>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

 

And that's it. Pretty easy, huh?!

 

Demo application - Construction Initiation Project

By: Vladi Gubler | Comments [1] | Category: Sample Applications | 9/5/2011

Hi,

In this demo application we are showing off how our Bi-directional Lookup bundle can help you create real-life application in SharePoint in just minutes. The bundle contains two products:

  • Connected Field - extends the built-in lookup field, adding various new capabilities, such as master-detail relationships between two or more fields, value sorting and filtering, in-line new value creation and more
  • Associated Tasks Field - allows creating relationships between lists, allowing managing related items or documents in the context of the parent item

The demo application is a construction initiation project. In it, we create an entry for a proposed constructions project, add various required documents to it, publish the documents for review and collect reading confirmations from the designated users. Once all the required reading tasks have been completed, the project is completed and we can now proceed on with our construction. As we only cover this initial stage, we will not be handling the actual construction stages here.

Watch the following video to see the system in action:

So lets get started.

First, we need to create a new blank site for the project. Then, we will create several lists that will manage our data.

Lists

  1. Designations - a simple Custom list holding list of designations for the project, such as Residential, Commercial or Agricultural. Just create the list from the Custom list template and enter some demo data, no changes to the list structure are required
  2. Building Types - for each designation we list several building types, such as House or Appartment Building for Residential, Bank or Shop for Commercial. Create a custom list and add a lookup column for the Designations list.
  3. Signing Tasks - list hoding reading confirmation tasks. We can either use the built-in Tasks list or the supplied Associated Tasks list. In the first case we will need to replace the built-in Task content type with the provided Associated Task content type. Using the built-in list type involves a little bit more work, but gives you the added benefit of email notification when a task is assigned.
    1. Create the list from Tasks list template
    2. In Advanced Settings enable content type management
    3. Add content type from Infowise group called Associated Task
    4. Remove built-in Task content type
    5. Remove unnecessary column, leaving only Title, Start Date, Due Date and Assigned To
    6. Add yes/no column Confirm Reading, set default value to No
    7. Signing Tasks
  4. Documents - document library to manage the construction documents
    1. Create the document library
    2. Allow content type management under Advanced Settings
    3. Add Associated Document content type under Infowise group
    4. Remove built-in Document content type
    5. Add Signers (person or group) field
    6. Add All Signed (choice) field with option Yes and No, No is the default. Set the column to be hidden in forms in the content type settings as we will be updating it programmatically using a workflow
    7. Add Document Type (choice) field with some demo data, such as Budget or Structural Plans
    8. Documents
    9. Add Read & Sign (Associated Tasks) field, pointing the the Signing Tasks list. Allow task generation for users in Signers field.
    10. Documents ATF
  5. Construction Projects - this is the main list of the system, where the actual projects are managed.
    1. Create list from Custom list template
    2. Create columns as shown in the following figure.
    3. Project
    4. The Building Type column is a Connected Field, it must be set to be filtered by the parent Designation column
    5. Connected Field
    6. The Document column is an Associated Tasks column pointing to the Documents library
    7. Documents ATF
    8. Status column contains values New, In Process, Completed (New is default). Set the column to be hidden in forms using the content type settings as we will be updating it using a workflow

Now we can add a couple of workflow to take care of our status columns. These are simple workflows created using SharePoint Designer 2007 or 2010.

First, let's create a workflow to run on the Signing Tasks list to update the All Signed column of the parent document. The workflow will run each time any task is updated, it will check if all tasked for the particular document are completed and then will update the document itself.

Note: make sure the Associated Tasks WF Support feature is activated for the web application.

Document WF

  1. Open the site in SharePoint Designer
  2. Create a new List workflow for the Signing Tasks list. The workflow is to be set to run each time an item is updated
  3. Call the workflow Document Status as that's what it is supposed to update
  4. Add condition of type Associated Item value check
  5. Set check for Confrm Reading column to be actual to Yes
  6. Add action Infowise Associated Tasks Extract Parent ID to get the parent document item ID from the related task and store it in a workflow variable
  7. Add action to update the parent document in the Documents list, by setting the All Signed value to Yes for item with ID matching the stored variable
  8. Publish the workflow

Now we add a workflow to set the project status to Completed when all documents are read by all users

Project WF

  1. Open the site in SharePoint Designer
  2. Create a new List workflow for the Documents list. The workflow is to be set to run each time an item is updated
  3. Call the workflow Project Status
  4. Add action Infowise Associated Tasks Extract Parent ID to get the parent projectitem ID from the related document and store it in a workflow variable
  5. Add Update List Item action to update the status of the parent project to In Process. This way any update will change the project status from the default New status
  6. Add condition of type Associated Item value check
  7. Set check for All Signed column to be actual to Yes
  8. Add action to update the parent item in the Construction Projects list, by setting the Status value to Completed for item with ID matching the stored variable
  9. Publish the workflow

This is it, you now have a functioning system and it took you just a few minutes!

 

Discover your newsletter exposure

By: Vladi Gubler | Comments [1] | Category: Products | 9/4/2011

Hi,

SharePoint is a great platform to publish news and events. You can use rich text messages, links or even images and you can have it all in a centralized place where it is easy to find. To make it even more effective, you can use our Newsletter add-on to send the items directly to the inboxes of your employees or clients. By using your own custom email templates you can create the snazziest newsletters, complete with your company logos, colors and layout.

The newest features added to our Newsletter are Unsubscribe and Analytics.

Unsubscribe allows you to add a link to the newsletter message to allow users to remove themselves from the mailing list. The functionality is completely automated, you don't even have to edit your recipient list, Newsletter will handled everything for you.

Analytics allows you to know precisely when the newsletter message is read and by whom. The visual representation calculates totals, daily totals and lists the actual recipients, complete with the time and date of reading.

Newsletter Analytics

 

Note: both features require access from the newsletter message back to the server, so you need to set up your system accordingly.

 

Print your data with Smart Print Pro

By: Vladi Gubler | Comments [13] | Category: Products | 9/4/2011

Hello,

Announcing the latest addition to our product line: Smart Print Pro

Managing information inside SharePoint is just great. You can set up complex applications in virtually no time at all, especially with the help of such great tools as our Ultimate Forms bundle. It is just a bit more difficult to print the information or send it out to external parties. Simply printing the page will include the whole page with it, including the navigation bars, logos and all the unrelated stuff. Sure, you can export it to Excel first, but the extra steps required are simply not convenient.

This is where Smart Print Pro can really help you out. It adds a nifty Print buttons to all your lists and list items. Click on it and you will see the print preview in a pop-up window (yes, in SharePoint 2007 as well). There you can send it to the printer, convert to PDF or have it emailed to you for forwarding.

By default, the printed item includes all the columns. But you can create your own custom print templates, select the columns you want, group them into sections and add custom header and footer. You can created multiple templates for the same list, so you can have different print-out for customers, for archives and for internal use.

Print invoice

Get your 30-day trial installation today!

 

Get your bottom line with Summary columns

By: Vladi Gubler | Comments [1] | Category: Products | 9/4/2011

Hello,

As you might already know, our Associated Tasks Field helps you create relationships between items located in different lists. So you can assign tasks to events, add documents to projects and basically create any type of relationships to turn SharePoint lists into a real life application infrastructure.

Now, we offer you an additional treat - you can now use the bindled Associated Items Summary columns to count or summarize your related items. For instance, imagine that you use the product to create and manage customer invoices. You do it using two lists:

  • Invoices - where the actual invoices are managed, with such columns as Customer, Bill To and Ship To
  • Invoice Lines - here you enter the items for each invoice, by entering item title, unit price, quantity and line total (use Calculated field for that)

Using Associated Tasks field you can show the lines withing the context of each invoice and you can even create new lines for new or existing invoices straight from the invoice's Edit form.

But what if you wanted to calculate the grand total or simply show the number of item lines in the Invoices list view. This is where the Associated Items Summary column helps.

  • Create a new summary column in the Invoices list
  • Point it to the Associated Tasks column you created to show the invoice lines
  • Select the Line Total column to perform calculations on that column
  • Select Sum operation
  • You can even optionally add filters, so that only specific related items are included in the summary

Invoice

That's it. Now each time an invoice item is added, modified or deleted, the parent invoice has its summary value re-calculated.

By the way, check out the new Smart Print Pro to print our your invoices or convert them to PDF.