Friday, September 28, 2012

Difference between List Definition, List Template and List Instance



 List Definition:

A list definition defines a schema for a SharePoint list. It contains information on what views are being used, which columns and content types are being used, and other metadata information.
 
List Template:
A list template can either be created by end users through the SharePoint user interface using an existing list as a pattern or using an existing list instance. If based on a user-created list it is called a custom list template. A custom list template includes everything that defines the list, including list columns and site columns used by the list, content types used by the list, views defined for the list, and so on.
 
Tips
A list template may sound like a list definition but they are effectively the same thing, a pattern for a SharePoint list. They differ mainly in how they are created:
- A list templates are created in SharePoint or SharePoint designer.
- A list definitions in Visual Studio.

List Instance:
A list instance is an instance of a specific SharePoint list definition or list template. All of its data is stored in the relevant content database. Typically a list in SharePoint used by end users to enter and view data and it is based on either a list template or list definition.

Preventing Record Modification but Allowing Metadata Modification by Overriding the Upload Page in Windows SharePoint Services 3.0

Overview
The Upload page that is provided by Windows SharePoint Services 3.0 enables users to upload files to
a Document Library. In addition to letting you select a file, the page contains an Upload Multiple Documents
link and a check box for overwriting existing files, which is selected by default. In this Microsoft Office Visual How To,
 you learn how to use the functionality of the Upload page, but you will modify and extend it to ensure that an
 existing file is not accidentally overwritten during the upload process. To do this, you create a new ASPX page
based on the existing Upload page, clear and hide the Overwrite Existing Files check box, and remove the
ability to upload multiple files. This enables you to inject specific business rules and processes for adding files
to the library.

Code It
Instead of creating a completely new Upload page, you will derive from the existing Upload page and
functionality, making the tweaks necessary for the functionality you want. To do this, you reference the
Microsoft.SharePoint and Microsoft.SharePoint.ApplicationPages assemblies in your project. Then you create
 a class that derives from theMicrosoft.SharePoint.ApplicationPages.UploadPage class. This class uses the
Microsoft.SharePoint andMicrosoft.SharePoint.ApplicationPages namespaces.
using Microsoft.SharePoint;
using Microsoft.SharePoint.ApplicationPages;

The functionality that you want is to clear and hide the Overwrite Existing Files check box, and also hide
theUpload Multiple Files link. To do this, you override the OnLoad event and modify the controls that control
 this functionality. The Upload Multiple Files link is provided by a HyperLink control
named UploadMultipleLink. To hide this link, set the Visible property to false.
 The Overwrite Existing Files check box is provided by theOverwriteSingle control. To clear and
hide the check box, set the Checked property and the Visible property tofalse. The assembly is now
complied with a strong name.
These steps are shown in the following code example.

namespace CustomUpload
{
    public class MyUpload : Microsoft.SharePoint.ApplicationPages.UploadPage
    {
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            // Hide the link to multiple upload.
            this.UploadMultipleLink.Visible = false;

            // Make sure the single overwrite is not checked and hide it.
            this.OverwriteSingle.Checked = false;
            this.OverwriteSingle.Visible = false;

        }
    }
}

Creating the ASPX Page
The next step is to create the ASPX page, making a custom page based on Upload.aspx.
 The Upload.aspx page you use is in the 12\TEMPLATE\LAYOUTS directory. You do not replace this file,
 but rather you create a new file based on the existing one.

To create the ASPX page

  • Create a new file in your project named MyUpload.aspx, and replace its contents with
     a copy of the contents from the Upload.aspx file. To make your custom ASPX page use your class,
    modify the Assembly and Pageinformation to reference your assembly and class.
    [MyUpload.aspx]
    <%@ Assembly Name="CustomUpload, Version=1.0.0.0, Culture=neutral, 
    PublicKeyToken=2ddef81d28ad7a84"%> 
    <%@ Page Language="C#" Inherits="CustomUpload.MyUpload" 
    MasterPageFile="~/_layouts/application.master"      %>
    ...Remaining content copied from Upload.aspx
    
After you perform this step, the next step is to put the assembly and ASPX page in locations that
 Windows SharePoint Services can use. In this example, you put the assembly in the global assembly cache,
and you put the ASPX page into the 12\TEMPLATE\LAYOUTS directory. Again, you do not want to replace
the existing Upload.aspx page, but rather add your own page.
After you reset Internet Information Services (IIS), your assembly and ASPX page are available,
 and they can be accessed from the _layouts directory: http://{weburl}/_layouts/MyUpload.aspx.
This URL must include a Listparameter that contains the GUID of the list in which the file is to be uploaded.
It can also optionally contain aRootFolder parameter that is used to identify the folder in which the file should
 be uploaded.
In this example, you are not replacing the existing Upload.aspx page, but instead you are implementing
your own page based on the functionality of the existing page. Because of this approach,
 you are not replacing the functionality of the Upload link in the document libraries.
 This means that you must find another way to access your custom Upload page.
You configure the New functionality within a document library so that it redirects the user to
your custom Upload page.
Redirecting the User to the New Upload Page
In this example, you redirect the user to your Upload page when the user selects New and then
selects Documentin the document library. To redirect to your Upload page,
you must first enable content types on the library.

To redirect users to the new page

  1. In a document library, click Settings, and then select Document Library Settings.
  2. On the Customize page, select Advanced Settings.
  3. On the Advanced Settings page, select Yes for Allow Management of Content Types, and then click OK.
    After you return to the Customize page, a new Content Types section appears.
  4. Click the Document content type, and then click Advanced Settings.
  5. Finally, enter the path to the custom Upload page, /_layouts/MyUpload.aspx in this example.


Figure 1. Content type

Content type
Now, when users click New and then click Document to create a new document, they are redirected to
 your custom Upload page.


Figure 2. Custom Upload page

Custom Upload page
An alternative way to redirect to the custom Upload page from the New action is to, in the content type schema
, define the path to the custom Upload page in the TargetName attribute of the DocumentTemplate.
[Example Content Type Schema]
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <ContentType
    ID="0x0101002852FFD6990A4ca1BEB33A2FDA0A8052"
    Name="My ContentType"
    Group="Custom"
    Description="This content type uses the custom upload page"
    Version="0">
    <FieldRefs>
      <FieldRef
        ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}"
        Name="Title"
        Required="TRUE"/>
    </FieldRefs>
    <DocumentTemplate TargetName="/_layouts/MyUpload.aspx" />
  </ContentType>
</Elements>

Read It
This particular scenario makes the most sense when the site administrator has a high degree of control
over the content types, libraries, and the site. It may not make sense in a typical team site where authority is
 often delegated and users have flexibility in how they work.
It is important to also point out that this example provides functionality that helps users perform the
 correct tasks and enforce the business rules—such as preventing the accidental overwriting of an existing file—
but it is not a replacement for security. For example, the alternative methods for adding a document to a library,
 such as through Windows Explorer/WebDav, are not handled in this example; they provide a method with
 which a user can overwrite an existing file. Also, hiding a control on the page is not meant to be a means
 for enhanced security because it does not prevent a malicious user from accessing those hidden controls
 and changing the behavior of the page. Instead, it is intended to help users follow the business rules and
processes that are necessary for uploading and interacting with the site content.

SharePoint 2010: Create Master / Detail Display Form for SharePoint Lists


SharePoint 2010: Create Master / Detail Display Form for SharePoint Lists

Problem: View on one screen Master / Detail ItemsOverview:There are two SharePoint lists connected each other. Business Area list is a master lookup list, whereas Business Entities is a Detail List that contains a Lookup column from Master list.

Solution: Edit the display form of the parent list and add the related list.
Go to Master List.
Select Default Display Form under Customize List section on the Ribbon:

Select Insert Related List option under Relationship section on Ribbon

Related Items in Business Entity Web Part is added:

Click Stop Editing
Select any item in Business Area list, the related Items in Business Entity are displayed



Adding HTML5 Drag and Drop to SharePoint Lists


Microsoft SharePoint is an enterprise platform with a long history and vast variety of features, which is why it can’t always react quickly enough to follow emerging Web technology trends. Despite a wide enterprise adoption of SharePoint and a huge effort to provide a broad number of features, SharePoint still lags behind modern CMS products in terms of immersive UIs, such as HTML5 and CSS3.
In my opinion, HTML5 is not only a hot new technology, but it truly has many practical benefits: it’s easy, convenient and rich—and it’s supported, more or less, by all the modern browsers (including mobile device browsers). Additionally, HTML5 and JavaScript are becoming major technologies for desktop programming in Windows.
So HTML5 definitely deserves its place in SharePoint to make portals much easier to use. And improving SharePoint interfaces can really help business users by enabling them to work better and faster.
Unfortunately, SharePoint doesn’t have any built-in HTML5 goodness, but what it does have is great flexibility. In this article, I’m going to demonstrate how easy it is to add HTML5 drag-and-drop support to SharePoint—and how smooth it can make the standard interface, as shown in Figure 1.
Drag and Drop in SharePoint
Figure 1 Drag and Drop in SharePoint
To implement this, I’ll use one of the essential SharePoint building blocks, which is also one of my favorite SharePoint tools—the XsltListViewWebPart and its XSL transformations (see the MSDN Library page atbit.ly/wZVSFx for details).

Why Not a Custom Web Part?

As always, when it comes to implementation, SharePoint offers a wide range of possibilities, and it’s exceedingly important to pick the one that will serve you best.
For the HTML5 drag-and-drop challenge, considering that drag and drop is mainly for managing data, many SharePoint developers would probably prefer to build a custom Web Part, which in this case acts just like an ordinary ASP.NET control: the data is stored in a standard SharePoint list, retrieved through the object model or SPDataSource control, and rendered with the help of ASCX markup and ASP.NET controls.
Simple, clear, plain ... but the best choice?
Two years ago I thought so. Today, I’d prefer to customize XsltListViewWebPart using its XSL transformations. Why did I change my mind?
Starting with SharePoint 2010, almost all kinds of list views (with the single exception of Calendars) are displayed through this very Web Part. Just imagine: all these data types, all these different views and styles and list types, all this great variety of data is rendered using XsltListViewWebPart and its XSL transformations. It’s a flexible and powerful tool.
If you decide to jump in and build your own custom Web Part to render some HTML5 markup for displaying list data, you’ll lose all of the built-in features. And based on my experience, that’s a huge loss. By the way, I haven’t seen a single custom Web Part yet that didn’t, at the very least, end up implementing half of the out-of-the-box XsltListViewWebPart features.
So, my plan is to reuse existing functionality rather than create a similar custom Web Part that would probably be much worse in terms of flexibility and power.
In fact, XsltListViewWebPart includes a bunch of useful features. It’s integrated into SharePoint Designer, it supports all possible Web Part connections and it displays all the SharePoint data types properly. It supports grouping, subtotals, paging, item context menus, inline editing, item selections, presence indicators and more. It has a contextual Ribbon interface, provides a UI for sorting and filtering, offers some basic view styles and more again. In sum, XsltListViewWebPart has a great many useful features that would be very hard to re-implement using the custom Web Part approach.

XsltListViewWebPart

XsltListViewWebPart provides many integration points for developers: a programmatic interface, a CAML interface and, of course, XSL transformations in conjunction with parameter bindings. And don’t forget, all these objects and properties also have their representations in the Client Object Model, so you can access your XsltListViewWebPart even from JavaScript or Silverlight.
So, XsltListViewWebPart is really a powerful tool. True, all this SharePoint-specific XML (or XSLT) looks a bit scary at initial glance, but there are some “life hacks” I’m going to show you that will help you puzzle it out.

The Scenario

Before I dive into the implementation details, let me describe the overall scenario.
What I’m going to do is inject HTML5 drag and drop into SharePoint list views to enable users to drag cells from one list to another list. My example will use a Tasks list and an Executors list, so the Project Manager can easily assign and reassign tasks, dragging executors to corresponding Tasks list cells.
As you might know, HTML5 introduces several new attributes for drag and drop, the most important of which is the “draggable” attribute. There are also a number of events for handling various stages of the drag-and-drop process. Handler functions for these events can be attached using corresponding attributes, such as “ondragstart,” “ondragend” and so forth. (For details, read the World Wide Web Consortium [W3C] HTML5 specification draft, Chapter 7.6, at bit.ly/lNL0FO.)
For my example, this means I just need to use XSLT to add some basic attributes to certain list view cells, and probably some additional custom attributes to attach the data values (that will be conveyed by dragging). Eventually, I’ll need to provide the corresponding JavaScript code for the handler functions.

First Steps

I need two lists. I can create a Tasks list from the standard Tasks template, or I can just create a custom list and add some columns, including an obligatory “Assigned To” site column. I create a second list, Executors, as a custom list, adding “Executor” as a column of type “Person or group,” making it required, indexed and unique.
The Executors list should display only user names; thus it doesn’t actually need the standard “Title” column. To hide this column, I go to list settings, enable management of content types, then go to the “Item” content type, click on the “Title” column and make the column hidden, as shown in Figure 2.
Making the Title Column Hidden in SharePoint List Settings
Figure 2 Making the Title Column Hidden in SharePoint List Settings
I filled these lists with sample data and then created a Web Part page for my dashboard, where I added these lists side-by-side (Tasks on the left and Executors on the right), as shown in Figure 3.
Adding the Lists to the SharePoint Dashboard
Figure 3 Adding the Lists to the SharePoint Dashboard
OK, now I have the lists and I have the data. Now it’s time for the actual implementation of the drag-and-drop functionality.

SharePoint Designer

Microsoft SharePoint Designer is a completely free tool for rapid development of SharePoint applications. SharePoint 2010 is greatly improved as compared with SharePoint 2007, and now it’s exceedingly useful, even for developers. The idea is that you can use the SharePoint Designer GUI to generate some really complex XSLT code and then just copy and paste the generated code into your Visual Studio project instead of writing the typo-prone and not always well-documented XML/XSLT by hand. I often use this trick in real-world projects and, I promise you, it saves plenty of time.
I open SharePoint Designer and navigate to the dashboard page I created earlier. I select a cell in the Assigned To column (right-click and choose Select | Cell). Now, the magic: in the status bar, I see the path to the XSL template (and to the corresponding HTML tag within this template) that’s responsible for displaying this particular cell (see Figure 4).
The Path to the Current XSL Template in SharePoint Designer
Figure 4 The Path to the Current XSL Template in SharePoint Designer
This information can be very useful for determining which XSL template to override in order to change the cell markup. You can find the original code for the templates in the 14/TEMPLATE/LAYOUTS/XSL folder, and use it in your own XSLT files or in the <Xsl> tag of the XsltListViewWebPart.
But I don’t need to deal with these huge and complicated XSLT files to achieve my goal. Instead, I can use the SharePoint Designer conditional formatting feature, which is designed to highlight certain rows or cells with special formatting, based on particular conditions. You don’t need any special skills to use this feature; the GUI makes it easy. But behind the scenes, it’s all implemented with XSLT. Thus, SharePoint Designer includes a kind of ready-to-use graphical XSLT generator, and I’m going to use it now for my own needs.
I select a cell, click the Conditional Formatting button on the Ribbon and then select Format Column, as shown in Figure 5.
Setting Conditional Formatting in SharePoint Designer
Figure 5 Setting Conditional Formatting in SharePoint Designer
Next, I create an unlikely condition, ID equal to zero, as shown in Figure 6.
The Conditional Formatting Dialog in SharePoint Designer
Figure 6 The Conditional Formatting Dialog in SharePoint Designer
Then I click the Set Style button and select some random style (such as “text-decoration: underline”). I press OK and switch to the Code View tab, where I locate the generated code; it is, of course, inside the <Xsl> tag of the XsltListViewWebPart control.

XSL Transformations

Now I’m ready to modify the markup of “Assigned To” cells. The “Assigned To” column is the “data acceptor” where I’ll drag executors, so I need to provide the “ondragover,” “ondragenter,” “ondragleave” and “ondrop” attributes, which will point to the corresponding JavaScript event handler functions.
The code generated by SharePoint Designer in the previous paragraph contains the XSL template with the following signature:
<xsl:template name="FieldRef_printTableCell_EcbAllowed.AssignedTo"
  match="FieldRef[@Name='AssignedTo']" mode="printTableCellEcbAllowed"
  ddwrt:dvt_mode="body" ddwrt:ghost="" xmlns:ddwrt2="urn:frontpage:internal">
As you might know, XSL templates can call each other, either by name or by condition. The first type of call is performed using the “xsl:call-template” element, and it’s very similar to a function call—such as what you’d use in C#, for example.
The second option is preferable and much more flexible: by using the “xsl:apply-templates” element, you can specify the mode and the parameter (which is selected using XPath so it can actually contain many elements), without specifying any particular template name. For each parameter element, the corresponding template will be matched using the “match” attribute. You can think of this approach as something similar to overloads in C#.
As you can see in the preceding code, this template will match “FieldRef” elements, where the Name attribute is equal to “AssignedTo.” Also, the “mode” attribute of the corresponding xsl:apply-template call must be equal to “printTableCellEcbAllowed.” So this template is essentially an overload for the standard function that displays fields’ values. And this overload will match only the “Assigned To” field values.
Now let’s take a look at what’s inside this template, as shown in Figure 7 (some code was removed for clarity).
Figure 7 Inside the XSL Template
<xsl:template match="FieldRef[@Name='AssignedTo']" mode="printTableCellEcbAllowed" ...>
  <xsl:param name="thisNode" select="."/>
  <xsl:param name="class" />
  <td>
    <xsl:attribute name="style">
      <!-- ... -->
    </xsl:attribute>
    <xsl:if test="@ClassInfo='Menu' or @ListItemMenu='TRUE'">
      <xsl:attribute name="height">100%</xsl:attribute>
      <xsl:attribute name="onmouseover">OnChildItem(this)</xsl:attribute>
    </xsl:if>
    <xsl:attribute name="class">
      <!-- ... -->
    </xsl:attribute>
    <xsl:apply-templates select="." mode="PrintFieldWithECB">
      <xsl:with-param name="thisNode" select="$thisNode"/>
    </xsl:apply-templates>
  </td>
</xsl:template>
As you see, the template contains two xsl:param elements, one <td> element, several xsl:attribute elements and an xsl:apply-templates element, which will cause some lower-level templates to be applied.
To achieve my drag-and-drop goal, I just add the drag-and-drop attributes to the <td> element, like so:
  1. <td ondragover="return UserDragOver(event, this)" ondragenter=
  2.   "return UserDragOver(event, this)" ondragleave=
  3.   "UserDragLeave(event, this)" ondrop="UserDrop(event, this)">
Pretty simple, isn’t it?
Alternatively, if you have jQuery deployed in your SharePoint environment, you might consider attaching JavaScript event handlers using the jQuery .on method.
The markup for the Assigned To column is ready (I’ll write the handlers a bit later). Now it’s time to customize the Executors list.
I switch back to the Design View tab, select a cell in the Executors column and repeat the conditional formatting trick for generating the XSLT code. Then I add the onstartdrag attribute to ensure that the drag and drop can properly start (I don’t need the draggable attribute here, because “Person or Group” field values are rendered as links and, according to the specification, links have the draggable attribute set to “true” by default):
  1. <td ondragstart="UserDragStart(event, this)">
Cool. But how will I track the data? How do I determine which executor is being dragged? Obviously, I need his login name or, better, his ID. Parsing the ID from inside the TD element is unreasonably complicated, in my opinion.
The point here is that in XSLT, for any field of type Person or Group, the user ID is available and can be easily retrieved with a simple XPath query.
In this query, I need to point to the current element’s values. The current element is usually referenced as the $thisNode parameter in all standard XsltListViewWebPart templates. To retrieve the user’s ID, you point to the attribute of the $thisNode parameter, with name equal to the name of the Person or Group column, with “.id” concatenated to its end.
So here’s my query:
  1. <td ondragstart="UserDragStart(event, {$thisNode/Executor.id}, this)">
The curly brackets are used for including the XPath expression right in the attribute value.
The markup is ready and can actually be used right away, but it would probably be a good idea to work with this code a little more to make it more reusable.

Making Templates Reusable

You might have noticed that the templates are tightly bound to specific column names and that these templates are intended only for particular lists. But it’s actually very simple to modify these templates so you can reuse them for other lists with other column names.
To start, if you examine the template signature I presented earlier, you’ll see the following attribute:
match="FieldRef[@Name='AssignedTo']"
Obviously, this binds the template to the Assigned To column. To make this template a bit broader-based, you can replace the name binding with a type binding, so that any Person or Group column will match. So be it! Here’s the code:
match="FieldRef[@Type='User']"
The same modification should be applied to the second template, where the FieldRef element is matched to the “Executor” field internal name.
Now, because I can have any column of type Person or Group and any list, I need to pass some additional information to my JavaScript handlers. When drag and drop is performed, I need to update the value of the Assigned To column in the Tasks list, so I need to know the name of the column and GUID of the list.
As I mentioned previously, SharePoint XSLT has some standard parameters that are available globally. One such parameter is $List, which stores the current list’s GUID. And the internal name of the field can be easily retrieved from the matched FieldRef element.
So, I’m going to pass the list GUID and the column internal name to the UserDrop handler, as follows (I’m omitting the “ondragenter,” “ondragover” and “ondragleave” attributes for clarity):
  1. <td ... ondrop="UserDrop(event, this, '{$List}', '{./@Name}'">
The “.” points to the current FieldRef element (which was matched previously by the template).
Next, I need to get rid of the “Executor” string in the id parameter in the Executors list XSLT using the following code:
  1. <td ondragstart
  2. ="UserDragStart(event, {$thisNode/@*[name()=
  3.   concat(current()/@Name, '.id')]}, this)"
  4. >
The templates are now ready and reusable, and now I’m going to write the corresponding JavaScript code to implement the handlers.

Writing JavaScript Handlers

Although there are four different handlers to write, most of them are primitive and they’re all rather obvious.
Usually I’d recommend placing this code in a separate JavaScript file. And it generally would be a good idea to use Visual Studio to create it, as you’d get the benefit of IntelliSense there. In some circumstances, however, it’s reasonable to put this code inside the XSLT, overriding the root template (match=“/”) for this purpose. This lets you use some XSLT variables and parameters inside your JavaScript code and it also means you don’t have to be concerned about deploying JavaScript files.
So let’s look at the code for the handlers—DragStart, DragEnter, DragOver, DragLeave and Drop.
In the UserDragStart handler, you need to initialize the data transfer. This means you need to store dragged data in a special HTML5 DataTransfer object, like this:
  1. function UserDragStart(e, id, element) {
  2.   e.dataTransfer.effectAllowed = 'copy';
  3.   e.dataTransfer.setData('Text', id + '|' + element.innerHTML);
  4. }
Note that the ID of the user is not the only part of the data that’s transferred. I also added the inner HTML of the <td> element, to avoid having to refresh the page after dropping the data (see the UserDrop handler code in Figure 8 for the details).
Figure 8 The Drop Event Handler
  1. function UserDrop(e, toElement, listGuid, columnName) {
  2.   // Terminate the event processing
  3.   if (e.stopPropagation)
  4.       e.stopPropagation();
  5.   // Prevent default browser action
  6.   if (e.preventDefault)
  7.       e.preventDefault();
  8.   // Remove styles from the placeholder
  9.   toElement.style.backgroundColor = '';
  10.   //toElement.className = '';
  11.   // iid attribute is attached to tr element by SharePoint
  12.   // and contains ID of the current element
  13.   var elementId = toElement.parentNode.getAttribute('iid').split(',')[1];
  14.   // Transferred data
  15.   var data = e.dataTransfer.getData('Text');
  16.   var userId = data.split('|')[0];
  17.   var userLinkHtml = data.split('|')[1];
  18.   // Setting value of the field using SharePoint
  19.   // EcmaScript Client Object Model
  20.   var ctx = new SP.ClientContext.get_current();
  21.   var list = ctx.get_web().get_lists().getById(listGuid);
  22.   var item = list.getItemById(elementId);
  23.   item.set_item(columnName, userId);
  24.   item.update();
  25.   // Asynchronous call
  26.   ctx.executeQueryAsync(
  27.     function () { toElement.innerHTML = userLinkHtml; },
  28.     function (sender, args) { alert('Drag-and-drop failed.
  29.       Message: ' + args.get_message()) }
  30.     );
  31.   return false;
  32. }
For the DragEnter and DragOver events in this case, the handlers are identical so I’m using a single function for them. You should indicate in these events that the user can drop his data here. According to the specification, for this purpose you should call the event.preventDefault method (if available), and then return false.
The DragEnter/DragOver handler is the perfect place to apply custom styles to the drag-and-drop placeholder to notify the user that he actually can drop his dragged data. To simplify the example, I’ll use inline CSS styles, but in a real-world project I’d recommend using CSS classes (see the commented lines shown in Figure 9).
Figure 9 The DragOver and DragLeave Event Handlers
  1. function UserDragOver(e, toElement) {
  2.   // Highlight the placeholder
  3.   toElement.style.backgroundColor = '#efe';
  4.   // toElement.className = 'userDragOver';
  5.   // Denote the ability to drop
  6.   if (e.preventDefault)
  7.       e.preventDefault();
  8.   e.dataTransfer.dropEffect = 'copy';
  9.   return false;
  10. }
  11. function UserDragLeave(e, toElement) {
  12.   // Remove styles
  13.   toElement.style.backgroundColor = '';
  14.   // toElement.className = '';
Obviously, in DragLeave I need to remove the previously applied styles, as shown in Figure 9.
During the Drop event in Figure 8, two important actions need to be performed:
  1. Apply the changes. Using the SharePoint EcmaScript Client Object Model, set the field value to the transferred user ID.
  2. Replace the inner HTML code in the current cell (TD) with code from the transferred one to make the changes appear without refreshing the page.
Now all handlers are implemented and you can deploy the Java­Script. Actually, you can do this in many different ways: customize the master page, use delegate control, create a custom action with Location set to “ScriptLink” or, as I mentioned earlier, include JavaScript right in the XSLT.
The simplest way here is to customize the master page file using SharePoint Designer, as it doesn’t require any special skills. But because you’re a developer, chances are you’d prefer to gather together all these JavaScript and XSLT customizations and create a deployable solution. OK, let’s do it!

Building a Deployable Solution

To create a ready-to-use solution you can send to your customers, you need to perform some very simple steps:
  1. Open Visual Studio and create an Empty SharePoint Project. Then select “deploy as a farm solution” in the project settings dialog.
  2. Add a SharePoint “Layouts” Mapped Folder to your project, and add three new files to it: UserDragHandlers.js, UserDragProvider.xsl and UserDragConsumer.xsl.
  3. Paste the previously created JavaScript code and the XSLT code (generated in SharePoint Designer) into corresponding files.
  4. Add an Empty Element project item, open Elements.xml and paste the following code there:
            <CustomAction ScriptSrc="/_layouts/SPDragAndDrop/UserDragHandlers.js" Location="ScriptLink" Sequence="10" />
    This will deploy the link to your JavaScript file to all site pages.
  5. Finally, add an Event Receiver to Feature1 (which was created automatically when you added the Empty Element project item), uncomment the FeatureActivated method and paste the following code in it:
  1. var web = properties.Feature.Parent as SPWeb;
  2.         SPList list;
  3.         SPView view;
  4.         list = web.Lists["Tasks"];
  5.         view = list.DefaultView;
  6.         view.XslLink = "../SPDragAndDrop/UserDragConsumer.xsl";
  7.         view.Update();
  8.         list = web.Lists["Executors"];
  9.         view = list.DefaultView;
  10.         view.XslLink = "../SPDragAndDrop/UserDragProvider.xsl";
  11.         view.Update();
And, yes, that’s all—you’re done! Pretty simple, isn’t it? Now if you build and deploy the solution with the Tasks and Executors lists created previously, and then create a dashboard containing default views of each of them, your dashboard will sport a handy drag-and-drop feature.

Browser Support

By now, just about all of the major browsers except Opera support HTML5 drag and drop. I’ve tested Internet Explorer 9.0.8112.16421, Chrome 16.0.912.75 and Firefox 3.6.12, and they’re all fully compatible with the described solution. I expect that some older versions of these browsers will work too. Actually, Safari should also work, but as of this writing, it has some strange bugs in its HTML5 drag-and-drop implementation that prevent the solution from working as expected.