Archive for October 25, 2012

SharePoint 2013 – The new “Preview Feature” in Search Results

In SharePoint 2013 Search has an Incredible new feature where for each search result that gets displayed on the search results page users can now “Hover Over” the result to view a Preview box for that Item.

Here is the quick Screen about the “Hover Panel” or the Preview box.

Some of the Features of this Hover Panel dialog box are –

* Hover panel has a high-fidelity Web Application Viewer or Preview that is available for all Office documents saved to SharePoint. These Interactive previews are big enough to give you a idea of the structure, contents, and styling of the document you’re hovering over.

* The hover panel contains rich metadata that enables users to investigate a result more thoroughly, without having to click through and load the document. See “Last Modified” and “Contributors include” in the above screen.

* In addition to the Metadata it also displays Section headings and slide titles that are inside of a document, under the heading “Take a look inside. These are called “deep links” and you can see them in the above hover panel. These headings and titles are links—clicking through will take you directly to that section (or slide) in the document.

* The bottom of the hover panel contains a list of actions that may be performed on a result. Now you can follow the document, Edit the document, View the document’s library, View duplicates, and\or send the document in an email message right from the results page. These actions are also completely customizable, so your results can be more actionable.

Custom Field Types in SharePoint 2013 Apps

Synopsis and Key Take-Aways

Custom field types in SharePoint provide the ability to customize all aspects of SharePoint form fields– from how they are displayed, to how values are validated to how values are stored within SharePoint and a couple of other things along the way. They provide significant capability for enforcing business rules and providing a much more user friendly experience than what is available via the out-of-the-box field types.  Unfortunately, this power has never been available in a cloud-hosting scenario such as Office 365.  Things are changing for the better, however, with new capabilities available in SharePoint 2013 Preview.  We now have the ability to provide the same functionality to our end users without running custom code on the server.  With SharePoint 2013 Preview, we can modify the presentation and validation of a custom field (or technically any field) on any form in SharePoint as well as in Views simply via JavaScript.  This is an incredibly powerful capability.  It provides a nice, easy, standard (and supported) way of customizing the end user experience to be more efficient and friendly.

This article introduces the scenario, walks through the end user experience using a sample custom field and then dives into a code-level review of how to implement this new functionality.  The commented source code listing for the required JavaScript is available for download.

Note that as of the initial publication of this article (October 2012), this is based on the SharePoint 2013 Public Preview.  Once I can download RTM I’ll look to revisit this and update the article as necessary.

Introduction

Custom field types in SharePoint provide the ability to customize all aspects of SharePoint form fields– from how they are displayed, to how values are validated to how values are stored within SharePoint and a couple of other things along the way.  They provide significant capability for enforcing business rules and providing a much more user friendly experience than what is available via the out-of-the-box field types (single line of text, yes/no, date/time, user, url, etc.) Unfortunately, this power and flexibility is simply not available in a cloud scenario such as Office 365 because they require that files be deployed to the server file system which you can’t do in a cloud solution.  For the 2010 release of SharePoint, there have been various attempts at simulating custom field types in a cloud scenario, but all have suffered from varying degrees of fragility or other problems. Fast-forward to SharePoint 2013 and Microsoft has made things much easier for developers and much less fragile all around with regard to custom field types.  For the first time, it is possible to truly get most of the value of custom field types in a cloud scenario such as Office 365 or an on-premises scenario (without all of the work of doing it the old way).  Notice that I said most of the value.  There are some things that are still not possible and two major caveats of which you must be aware.  First the caveats:

  1. Even though we are building things which look and act like custom field types, we are not technically building custom field types.  We are technically just customizing the rendering and validation of the out of the box field types.  More on this later; just remember it for now
  2. All of our customizations are happening on the client side via JavaScript.  There are implications to this for your data and business rules.  What happens if a user has JavaScript turned off and therefore your customizations do not run?  What are the implications to the security and validity of your data?  We will touch briefly on custom validation later, but just keep it in mind – it’s not guaranteed to run)

Acknowledgements

Before going any further, I need to give credit where credit is due.  Andrew Connell and I hacked up the first portion of this together.  I took the rough POC AC and I had pulled together that almost did everything we wanted, finished it off and cleaned it up to produce the samples in this article.  Keep an eye on AC’s blog as he’ll be posting a follow-up article taking some of this in new directions.

Overview of the Solution

With all of that said, let’s see what it is that we’re going to get at the end of this.  Here are some screenshots and descriptions of what we’re going to build out in the rest of this article:

The New Item Form

In this example, we’ve customized the rendering of our custom field:image

Site Column 1 is our custom field.  Technically, it is just a simple text field.  Without our customizations, it would render as a textbox.  Our customizations change it’s rendering to a dropdown list. The choices available in the dropdown (One through Five) are added dynamically.  In a real world scenario, these could come from a web service call.  To keep things simple and focused here, I’m simply hardcoding an array.  You’ll see when we get to the code how simple it would be to make this truly dynamic. We’ve also added some rudimentary validation.  For the sake of this demo, FOUR is not a valid choice:image

(Michael Palin would be so proud) Notice, too, that our field is marked as required in SharePoint and regular field validation continues to function:image

One of the things I’d like to play with in a later version of this is the possibilities for additional validation via CSOM and perhaps even some event receiver work to provide additional server-side validation.

Display in Views

Once we’ve entered a legal value, our item is shown in a SharePoint View.  We also have the opportunity to customize the rendering here as well: image

For the sake of this demo, I’m not actually showing the field value in the View. Instead, I show a JavaScript link that pops up a simple alert when clicked to show the field value:image

The Display Form

Again, for the sake of this demo, I’m customizing the presentation of our field on the Display form as well.  Instead of showing the actual value, I show it’s numeric equivalent:image

The Edit Form

The Edit form looks largely identical to the New form (internally, it’s actually rendered via the same code).  The only difference is that we have to make sure that the current value of the field shows as selected in the dropdown:image

Technical Walkthrough

Now that we’ve seen what we’re building, let’s dive into how to make it all work.  Once you’ve figured it all out, it’s actually pretty easy.  (Figuring it all out, though, that was a royal PITA, especially during a beta cycle). The heart of everything we’re doing here is a new property on the out-of-the-box  SPField class (and all of it’s children) within the SharePoint server object model: JSLink (don’t  bother clicking on the link – there is NO documentation worth anything there right now – just a placeholder).  Similar to the JSLink property on SPView, SPField.JSLink gives us the opportunity to specify a custom JavaScript file that will be used to render our field.  Cool. From our SharePoint 2013 App (or, really, any SharePoint 2013 solution), we add an attribute to the Elements file that defines our custom Field to specify the JSLink value:

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Field
       ID="{23d7e8ae-29c3-4f05-ac4a-08bbf2bc2b1d}"
       Name="SiteColumn1"
       DisplayName="Site Column 1"
       Type="Text"
       Required="TRUE"
       JSLink="~site/Scripts/SampleJSField.js"
       Group="Custom Site Columns">
  Field>
Elements>

The SampleJSField.js file will now be used to render our field wherever it is used.  The full SampleField.js file is available at the end of this article for your reading pleasure..I’ve added some comments to explain what is going on, but the following sections spell out the highlights

IIFE

Because we are only specifying a JavaScript filename in our JSLink attribute, and not a particular method to be called, we need some way to actually execute our code.  We do this via an IIFE (Immediately Invoked Function Expression) declared right at the top of the file:

(function () {

    initFieldTypes();
    var r = new JSFieldText("SiteColumn1", viewFunc, editFunc, editFunc, displayFunc);
    r.initField()
})();

You could do this different ways, but this is the most concise and easiest.  Basically, in one shot, I’m declaring an anonymous JavaScript function and invoking it.  No magic inside the IIFE itself, it simply calls a function to set up our custom field objects (initFieldTypes), creates an instance of my custom JSFieldText object (passing in the field name and a couple of function objects – more on these later) and then initializes the field. I’m not going to go into details on the whole initFieldTypes function here.  It’s in the full source listing and it’s a bunch of pretty funky JavaScript at this point.  I plan on cleaning this all up but there’s no sense in doing that until I’m working with RTM bits.  Eventually, I’d like to centralize all of this in a common JavaScript library that can be used by multiple fields, but that will come later.  For now, it was enough just to build out a POC to show that this all works.  A good chunk of the  code in the “Global Code” section of the full source listing is based on some code from http://www.ruzee.com/blog/2008/12/javascript-inheritance-via-prototypes-and-closures but I’m not sure whether I’ll stick with that.  It introduces some complexity and I’m not sure it gets me a lot.  In the short term, however, it filled a void and let me focus on more pressing things.

Registering Our Custom Rendering

I will, however, focus on a few key areas within the initFieldTypes function.  The first is where we actually override the default rendering and tell SharePoint to use our custom rendering.  This is done via the initField function on the JSFieldText object:

if (hasValue(this.get_fieldName())) {
      var newCtx = {};

      newCtx["Templates"] = {};
      newCtx.Templates["Fields"] = {};
      newCtx.Templates.Fields[this.get_fieldName()] = {};
      //Views are handled slightly differently because of the way they are called by SP
      newCtx.Templates.Fields[this.get_fieldName()]["View"] = hasValue(this.viewCallback) ? this.viewCallback : null;
      newCtx.Templates.Fields[this.get_fieldName()]["NewForm"] = this.renderForNew;
      newCtx.Templates.Fields[this.get_fieldName()]["EditForm"] = this.renderForEdit;
      newCtx.Templates.Fields[this.get_fieldName()]["DisplayForm"] = this.renderForDisplay;

      SPClientTemplates.TemplateManager.RegisterTemplateOverrides(newCtx);
}

This code sets up an object hierarchy in a manner prescribed by SharePoint 2013 and registers the new functions to render each of our possible views of this field:

  • Views
  • Display Form
  • Edit Form
  • New Form

The last line of the snippet is what actually registers our custom handlers with  SharePoint. Views are handled slightly differently because of how they are called internally by SharePoint.  For Views, we simply pass the callback that was supplied in the constructor of our field. Note that we do check for null and undefined via some helper functions.  If we set the View or any of the Forms to a null or undefined value, SharePoint will use it’s default rendering. The Forms all use a function on our JSFieldText object because we need to do a little processing before invoking the callback. Once the callbacks are registered, they’ll be called by SharePoint instead of the default rendering mechanisms. One of the things that you’ll notice about all of these callbacks is that we’re not dealing with HTML objects.  In each case, we need to return the actual HTML text to render our desired UI, so we’re doing a lot of string manipulation.  That’s just the way SharePoint expects things to be, so we just run with it.

Technical Details: Views

The View callback is a simple method that modifies the value written into the standard SharePoint View as we saw in the screenshots above.  Here’s the code for that:

/// Function called to render the field in a View
function viewFunc(renderCtx, field, listItem, listSchema) {
    var currentVal = '(null)';
    if (renderCtx != null && renderCtx.CurrentItem != null)
        currentVal = eval('renderCtx.CurrentItem.' + field.Name);
    return " + currentVal + "')\">Show Field Value";
}

Notice that the name of our function (viewFunc in this case) was the value passed into our JSFieldText constructor earlier.  The other callbacks operate the same way.  Note also the use of the eval statement in there.  I’m not thrilled with that and would like to find a way around it but haven’t come up with anything yet.

Technical Details: Edit Form

The Edit Form callback is used to render the field on an Edit Form.  Here’s the code for the sample I built:

/// Function called to render the NewForm & EditForm view of the field
function editFunc(renderCtx) {
    var fieldHtml = '  ';
    fieldHtml += getStandardInputHtml(this, "hidden");
    return fieldHtml;
}

This one is a little more complex than the View, but it is still just building up an HTML string to be returned to SharePoint and ultimately stuffed down the pipe to the client’s browser.  There are a couple of helper functions that you can review in the full source code listing.  In the listing above, all I’m rendering is the select box to present the choices.  The actual field used by SharePoint is handled in the getStandardInputHtmlfunction.  Remember, it renders as a hidden field and I use a simple JavaScript function (moveValue, shown below) to copy the selected value from the dropdown list to the hidden field so it is available to SharePoint. The moveValue function also handles my custom validation:

function moveValue(targetId) {
    var mySelect = document.getElementById('myNiftySelect')
    var selectedVal = mySelect.options[mySelect.selectedIndex].text
    if (customValidationPasses(selectedVal, mySelect)) {
        var targetTextBox = document.getElementById(targetId);
        targetTextBox.value = selectedVal;
    }
}

function customValidationPasses(newValue, selectControl) {
    if (newValue === "Four") {
        alert("Four is right out! Counteth thou to THREE and then lobbeth thou the holy handgrenade of Antioch at thy foe, who, being naughty in my sight, shall snuff it.");
        selectControl.selectedIndex = selectControl.selectedIndex - 1;
        return false;
    }
    return true;
}

There’s a fair amount going on in the editFunc function, but none of it is very complex.  This is another area I’d like to work on tweaking a bit. As I said before, for the sake of this demo, I have hardcoded in an array to provide the choices for the dropdown:

//keeping it simple for the sake of this demo code - not really calling a service to get values
function getOptionsFromSimulatedWebServiceCall() {
    return ["One", "Two", "Three", "Four", "Five"];
}

If you needed to make this dynamic, simply change the code in that method (and probably itsa name, too) to do whatever you need.

Technical Details: New Form

The New Form rendering is actually handled by the editFunc function.  Notice back in the IIFE when we create the JSFieldText object that we pass editFunc in twice:

var r = new JSFieldText("SiteColumn1", viewFunc, editFunc, editFunc, displayFunc);

The first one is actually the New Form callback.  If you needed to render your field differently on the New Form, simply pass in a unique callback here.

Technical Details: Display Form

Last but not least is the Display Form.  Remember this shows the numeric representation of our field’s value (kind of lame, I know, but I wanted to show something different for each type of rendering and this was the best I could come up with).  The displayFunc function handles this for us:

/// Function called to render the DisplayForm view of the field
function displayFunc(renderCtx) {

    if (renderCtx != null && renderCtx.CurrentFieldValue != null) {
        var fieldVal = renderCtx.CurrentFieldValue.toString();
        switch(fieldVal)
        {
            case "One":
                return "1";
                break;
            case "Two":
                return "2";
                break;
            case "Three":
                return "3";
                break;
            case "Four":
                return "4";
                break;
            default:
                return "5";
        }
    }
    return '';
}

Create a List Definition in SharePoint 2010 using Visual Studio 2010

In this demonstration, I am going to create a list definition using Visual Studio 2010. For the demonstration purpose, I am going to create a list definition for storing expenses, once deployed, the list definition can be used to create lists to store expenses. The list definition will define a list template that inherit from custom list and add columns expensedate and amount.

Open Visual Studio, Go to File -> New project, In the Template selection dialog, choose List Definition as the template type.

Give a proper name to your List Definition project. Make sure the .Net framework selected is 3.5 as SharePoint 2010 is built on .Net framework 3.5.clip_image002

Click OK button, once you entered all the details.

In the next dialog you need to choose the SharePoint portal you need to use for debug. Also you need to specify whether it is a farm solution or sand boxed solution. Enter your SharePoint portal address and Click Next

clip_image003

Click Next once you are done

Now Visual Studio will bring you the List definition settings dialog. Here you can define the title for your list definition and choose a base list to inherit from. I choose my base list as “Custom List”. In addition to this you can decide whether to include a list instance when deploying this feature. Since I want to check my list definition, I selected “Add a list instance to this list definition” option. Click finish button, once you are done

clip_image004

Click Finish button once you are done with this step.

Visual Studio will add a default feature to your project and add a list definition. In the solution explorer the project will look similar to the following. I published an article for developing a SharePoint 2010 feature using Visual Studio, to read that article click here.

clip_image005

Let me explain the files exists under the List Definition

Elements.xml – this file defines the list template and fields such as name, display name, type etc. The properties specified in this file will be displayed in the Create Page, when you create a list template from this file.

Let us examine the Elements.Xml file. See the snapshot of the elements.xml file

clip_image006

The complete reference for Elements file for List template can be found in the below URL

http://msdn.microsoft.com/en-us/library/ms462947.aspx

The type identifier must be unique within the feature, but need not be unique across all feature definitions or site definitions. So make sure when you have multiple list templates in the same feature, you made them with different type attributes. It is also recommended to create Type value greater than 10000. For my List Instance I assigned the Type attribute with a value of 10001.

After Modifications, the List template file looks as follows.

clip_image007

Notice that, I just updated the Type attribute, but depending on your needs you may add other attributes.

Now I am going to add fields for my List template. As I mentioned initially, I will have only 2 fields date and amount. Refer this link to under stand more about Field element http://msdn.microsoft.com/en-us/library/ms437580.aspx

When you define a field, you need to specifiy a guid as ID enclosed in braces{}. To create a Guid, do the following steps.

From visual Studio menu, select tools, then select create guid

clip_image009

The Create Guid dialog will appear as follows

clip_image010

I have added the following fields to List Template.

 

 

Make sure for each field you create you use unique guid. Now I want to create a content type that includes these fields. When you define a content type, you need to define an ID for the content type. This is a bit tricky. Refer the below article to under stand more about content type ID.

http://msdn.microsoft.com/en-us/library/aa543822.aspx

My content type should be a sub of item content type, so I am going to use the following rule to create my list content type id.

 

System

Item

prefix

Hexadecimal GUID

0x

01

00

4FDDEDBF38D14332A625BCBC60F1667A

 

(for hexadecimal guid, I create a guid from visual studio and then removed braces and hyphens)

So my content type id is 0x01004FDDEDBF38D14332A625BCBC60F1667A

Add the following content type tag just above the ListTemplate start tag.

 
   
     
     
 
 

The definition is very straight forward. See the tags where you add the reference to previously created fields.

Find the snapshot of Elements.xml file after the above items added.

clip_image012

Now you have defined fields, content type and list template. Now you need to link your list definition to content type. You need to perform this in the schema.xml file. Open schema.xml file, by default it will look similar to the below snapshot.

clip_image013

Now you need to replace the element with the below

 

 
   

Now copy all the tags from Elements.xml and paste in between and . This is a duplication of work but you need to do this. After replaced, the Fields tag will look as follows.

 

 
   
  StaticName=”ExpenseDate” Name=”ExpenseDate” Group=”Expense Columns” /> 
   
  StaticName=”Amount” Name=”Amount” Group=”Expense Columns” /> 

Now you need to add the field references to view fields. There will be multiple tags, you can add field references in all or atleast in the View with BaseViewID=1, as this is the default view. See the snapshot of default view in the schema.xml file

clip_image014

In between ViewFields add the below markup.

See the snapshot of schema.xml after made the changes.

clip_image016

clip_image018

Now you are done with the list definition. Now you need to modify the List Instance to use the template you just created. Open the elements.xml file under the List Instance 1, the snap shot of default Elements.xml is as follows.

clip_image019

You need to change the TemplateType to the Type attribute you mentioned in the List Template, i.e. 10001. Also you can modify the list title, url etc. Also you can add initial data to the list instance so that the data will be inserted to the default list instance on feature activation.

Place the below xml inside tag for inserting initial data

 
   
     
      travel expense 
      01-01-2011 
      20.00 
   
 
     
       your expense title 
      01-01-2011 
      10.00 
   
 
 
 

See the snap shot of List Instance 1 after all changes were made.

clip_image020

Now we are ready to deploy the List defenition. Right click the project and click on deploy.

clip_image021

If you made everything correct, visual Studio will successfully deploy the list definition. Now you can find one list instance created in your SharePoint site. Open the list instance, you will find the data already inserted to it.

clip_image023

When you create new item in SharePoint, you will find the expense template.

clip_image025

It is easy to create List Definitions for SharePoint 2010 using Visual Studio 2010. Once you successfully tested your list definition project, you can package it to WSP file and deploy to multiple farms.

Creating a Folder in a SharePoint List and adding Items to it programatically

So, this took me a little while to get straight today when I was writing a web part.  It is pretty straight forward but the only information I could find online dealt with Document Libraries or didn’t provide code that worked.

I wanted to create a folder in a list, and then add items to that folder.  Furthermore, I needed to be able to find the folder in the future by name and add additional items to it.  Well, that seems like it should be quite simple, but there is no lookup by name, just GUID or int ID for the SPFolder object.

Here is the code to create the SPFolder for a list (Notice how it is actually an SPListItem…).  Note that this code already grabs the list from an SPWeb object.

SPListItem auditFolder = auditList.Items.Add(auditList.RootFolder.ServerRelativeUrl, SPFileSystemObjectType.Folder, auditFileName);
auditFolder.Update();

Then, the code to add an item to a folder inside of a list is below – note that I don’t update any fields before saving the list item with an Update call.

SPListItem auditItem = auditList.Items.Add(auditFolder.Folder.ServerRelativeUrl, SPFileSystemObjectType.File, null);
auditItem.Update();

But to the point I made before about not being able to do a lookup on a folder by its Name is kind of a pain, I ended up using a for loop, iterating through the folders in the list and looking for a specific one by name as shown below. Also note that you may need to call allowunsafeupdates for this to work in your environment.

SPList auditList = ElevatedWeb.Lists[auditLogList];
SPListItem auditFolder = null;
bool folderExists = false;
// Check to see if folder already exists, if not create it
for (int i = 0; i < auditList.Folders.Count; i++)
{
if (auditList.Folders[i].Folder.Name == auditFileName)
{
auditFolder = auditList.Folders[i];
folderExists = true;
}
}

if (!folderExists) // The folder does not exist so we create it and add the item
{
auditFolder = auditList.Items.Add(auditList.RootFolder.ServerRelativeUrl, SPFileSystemObjectType.Folder, auditFileName);
auditFolder.Update();
SPListItem auditItem = auditList.Items.Add(auditFolder.Folder.ServerRelativeUrl, SPFileSystemObjectType.File, null);
// Fill in properties of the list item here
auditItem.Update();
}

Well, like I said I used this inside of a web part, and since there wasn’t much to it I will probably put it up here in a few days. Hopefully this saves someone some time, Later.

Union in datatable using LINQ

 

DataTable dt1 = new DataTable();

    dt1.Columns.Add(new DataColumn(“Name”));

    dt1.Rows.Add(dt1.NewRow()[“Name”] = “Imran”);

    dt1.Rows.Add(dt1.NewRow()[“Name”] = “Amir”);

    dt1.Rows.Add(dt1.NewRow()[“Name”] = “Asif”);

 

    DataTable dt2 = new DataTable();

    dt2.Columns.Add(new DataColumn(“Name”));

    dt2.Rows.Add(dt2.NewRow()[“Name”] = “Tandulkar”);

    dt2.Rows.Add(dt2.NewRow()[“Name”] = “Amir”);

    dt2.Rows.Add(dt2.NewRow()[“Name”] = “Sheqwag”);

 

     DataTable dtUnion = dt1.AsEnumerable()

      .Union(dt2.AsEnumerable()).CopyToDataTable();

 

class CustomComparer : IEqualityComparer

{

    #region IEqualityComparer Members

 

    public bool Equals(DataRow x, DataRow y)

    {

        return ((string)x[“Name”]).Equals((string)y[“Name”]);

    }

 

    public int GetHashCode(DataRow obj)

    {

        return ((string)obj[“Name”]).GetHashCode();

    }

 

    #endregion

}

 

var comparer = new CustomComparer();

DataTable dtUnion = dt1.AsEnumerable()

      .Union(dt2.AsEnumerable(), comparer).CopyToDataTable();