Creating Interactive SharePoint List Views Using the JavaScript Client Object Model
There are some situations where you prefer to allow users to directly interact with list items directly within the row of the list view. Normally interaction occurs through the edit control block (ECB), the ribbon, or one of the list item forms. However, sometimes the action is a simple toggle activity that the user should simply be able to directly initiate directly from the list view UI.
Here is a general approach for enabling this.
There are four components:
- 1. The XSLT to cause render the interface on each list item
- 2. A JavaScript file to handle the interaction using the SharePoint Client Side Object Model for JavaScript
- 3. (Optional) a form to handle optional input for the change
- 4. Some images for the interaction
In this example, we will allow the user to toggle the Status column of a document library between to arbitrary values “True” and “False”, and specify a comment in the comment history when toggling the value to “False”. Using this method you can allow the users to put a toggle switch on any list item, and have it write that value back to the list item directly from the list view.
Steps
Create a document library, or navigate to an existing one.
Modify the desired SharePoint view using SharePoint Designer (See: Create a custom list view using SharePoint Designer). Using Table layout tools, add a column to hold the toggle XSL (not another data column, just a layout column).
Add the following snippet to the column in code view, which looks at the Status column and displays the appropriate toggle UI, and wraps it with an OnClick event handler with the ID of the list item.
<!-- BEGIN Toggle Control -->
<xsl:if test="normalize-space($thisNode/@_Status) != 'False'" ddwrt:cf_explicit="1">
<div >
<xsl:attribute name="onclick"> ToggleOff('<xsl:value-of select="$thisNode/@ID"/>');
</xsl:attribute>
<div style='width:30px;display:inline-block'>On</div> <img src='/style library/images/ToggleIn.png' alt='Click to Toggle Off' title='Click to Toggle Off'/>
</div>
</xsl:if>
<xsl:if test="normalize-space($thisNode/@_Status) = 'False'" ddwrt:cf_explicit="1">
<div >
<xsl:attribute name="onclick"> ToggleOn('<xsl:value-of select="$thisNode/@ID"/>');
</xsl:attribute>
<div style='width:30px;display:inline-block'>Off</div> <img src='/style library/images/ToggleOut.png' alt='Click to Toggle On' title='Click to Toggle On' /></div>
</xsl:if>
<!-- END Toggle Control –>
Add a content editor web part to the page and put a script reference in the HTML of the content editor web part such as:
<script src=”/style library/SPQuickToggle.js”></script>
Upload the attached images to site collection /Style Library/Images/ and the .js and .aspx page to the /Style Library/. In this case we are using two simple graphics that resemble the Metro toggle control and we are prompting the user to provide a reason for turning off the switch. Note: you can, of course, put them anywhere, but you’ll have to simply change the references.
You can look at the source of the JS file, but the key portions are:
- the use of the SP.UI.ModalDialog to take in a reason, and then handle the comment return result.
- Using the SP.ListItem.set_item method, which uses the update method, followed by the executeQueryAsync method of the SP.ClientContext.
Here is the relevant snippet:
var ToggleDialog;
var SPQuickToggleConfig = {
ReasonDialogURL: "/style library/ToggleReason.aspx",
ToggleListTitle: "Documents",
ToggleField: "_Status",
ToggleOnValue:"True",
ToggleOffValue: "False",
ToggleReasonField: "ItemHistory"
};
function ToggleOut(itemID) {
///<summary>Prompts the user for a reason for tailoring out an item</summary>
///<param name="itemID" type="integer" mayBeNull="false" integer="true">The list item ID that is to be toggled off</param>
SP.UI.ModalDialog.commonModalDialogOpen(SPQuickToggleConfig.ReasonDialogURL, {
title: "Reason for Toggling",
width: 300,
height: 175
}, ToggleWithReason, itemID);
}
function ToggleWithReason(diagResult, diagReturnArgs) {
///<summary>This is called after the dialog closes</summary>
///<param name="diagReturnArgs" type="object"></param>
logger("Entering Toggling Reason");
if (diagResult == 1) {
ToggleDialog = SP.UI.ModalDialog.showWaitScreenWithNoClose("Toggling...", "Toggling this item", 200, 200);
var itemID = diagReturnArgs[0];
var toggleReason = diagReturnArgs[1];
//Get the current client context
context = SP.ClientContext.get_current();
var toggleLibrary = context.get_web().get_lists().getByTitle(SPQuickToggleConfig.ToggleListTitle);
//Get the list item to update
var listItem = toggleLibrary.getItemById(itemID);
//Set the new property value
listItem.set_item(SPQuickToggleConfig.ToggleField, SPQuickToggleConfig.ToggleOffValue);
listItem.set_item(SPQuickToggleConfig.ToggleReasonField, toggleReason);
logger("About to update list item.");
listItem.update();
logger("About to execute async query.");
context.executeQueryAsync(ToggleOffSucceeded, ToggleOffFailed);
}
else {
//Optional: show canceled notification
}
}
As always, the code carries no warranties express or implied.
Linkbacks are always appreciated.
Footnote: You’ll see my code references at the beginning of the JS file which enable great intellisense in Visual Studio.