The DataSheet view in SharePoint provides the means to edit lists in bulk, but sometimes it would be convenient to be able to edit items in a standard SharePoint view without opening the associated form each time. This is possible using a bit of Google Jquery wizardry which combines AJAX with traditional JavaScript.

In a typical SharePoint task list, both the Status and the Priority fields can be set direct from the Edit Control Block as follows:

Clicking the menu items changes the entry in the list directly. To make use of this functionality, you should insert a Content Editor Web Part in the page and past the following code into the Source:

<script type=”text/javascript” src=”http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js”></script&gt;

<script type=”text/javascript”>

// Ajax Enabled SharePoint 2007 Lists and Document Libraries version 1.0

// Created by Jan Tielens, http://weblogs.asp.net/jan, http://twitter.com/jantielens

// **** INSTALLATION INSTRUCTIONS

// – Navigate to the page where you would like to use it (e.g.

// http://yoursite//Lists/Tasks/AllItems.aspx for the Task list).

// – Click Site Actions, Edit Page (top right)

// – Click Add a Web Part

// – Select the Content Editor Web Part in the Miscellaneous section and click Add.

// – Optionally drag the Content Editor Web Part to the bottom of the screen (otherwise a

// small space will be displayed on top of the page).

// – Click open the tool pane in the web part.

// – Click Source Editor … in the properties task pane.

// – Copy and paste the modified script in the Text Entry dialog and click Save.

// – Click Exit Edit Mode (top right) and verify the result.

// ****

var ajaxListConfig = {

columns :new Array(“Status”, “Priority”), // columns to ajaxify

values :new Array(

new Array(“Not Started”, “In Progress”, “Completed”,

“Deferred”, “Waiting on someone else”), // values for Status

new Array(“(1) High”, “(2) Normal”, “(3) Low”) // values for Priority

),

debug :0, // set to 1 to see log messages

animationSpeed :”fast” // possible values: “slow”, “normal”, “fast” or a number (milliseconds)

};

function Custom_AddListMenuItems(m, ctx) {

ajaxListLog(“Custom_AddListMenuItems entered.”)

// the element ID of the table containing the rows is a combination of the List ID and View ID.

var tableid = ctx.listName + “-” + ctx.view;

var wsurl = ctx.HttpRoot + “/_vti_bin/lists.asmx”;

// loop over all configured columns

for(var j in ajaxListConfig.columns) {

var column = ajaxListConfig.columns[j];

// create menu item for column

var menuItem = CASubM(m,”Update ” + column);

var currentValue = getColumnValueViaWS(column, ctx.listName, currentItemID, wsurl);

//var currentValue = getColumnValueViaHTML(column, ctx.listName, currentItemID, tableid);

// loop over all possible values for the column and add sub menu items

for(var i in ajaxListConfig.values[j]) {

var colValue = ajaxListConfig.values[j][i];

if(colValue != currentValue)

CAMOpt(menuItem, colValue , “setColumnValue(‘” + column + “‘,'” + ctx.listName + “‘,'” + currentItemID + “‘,'” +

colValue + “‘,'” + tableid + “‘,'” + wsurl + “‘);”);

}

}

CAMSep(m);

return false;

}

function getColumnValueViaHTML(column, list, itemID, tableid) {

var $td = getItemTD(column, tableid, itemID);

return $td.text();

}

function getColumnValueViaWS(column, list, itemID, wsurl) {

ajaxListLog(“getColumnValueViaWS entered.”)

// build soap envelope to retrieve a list item based on it’s id

var soapEnv =

“<soapenv:Envelope xmlns:soapenv=’http://schemas.xmlsoap.org/soap/envelope/’&gt; \

<soapenv:Body> \

<GetListItems xmlns=’http://schemas.microsoft.com/sharepoint/soap/’&gt; \

<listName>” + list + “</listName> \

<viewFields> \

<ViewFields> \

<FieldRef Name='” + column + “‘ /> \

</ViewFields> \

</viewFields> \

<query> \

<Query><Where> \

<Eq> \

<FieldRef Name=’ID’ /> \

<Value Type=’Integer’>” + itemID + “</Value> \

</Eq> \

</Where></Query>\

</query> \

</GetListItems> \

</soapenv:Body> \

</soapenv:Envelope>”;

ajaxListLog(“- Initializing AJAX call …”);

var itemStatus;

$.ajax({

async: false,

url: wsurl,

type: “POST”,

dataType: “xml”,

data: soapEnv,

contentType: “text/xml; charset=\”utf-8\””,

complete: function(xData, status) {

// data is received, get and return the value

ajaxListLog(“- AJAX call done, status: ” + status);

var $itemElement = $(xData.responseXML).find(“z\\:row:eq(0)”);

itemStatus = $itemElement.attr(“ows_” + column);

}

});

return itemStatus;

}

function getItemTD(column, tableid, itemid) {

// This function retrieves the TD (table cell) that contains the data for the

// specified item and column.

// first check if the requested TD is in the cache

if(ajaxListConfig.cachedItemColumn != column || ajaxListConfig.cachedTableID != tableid ||

ajaxListConfig.cachedItemID != itemid || ajaxListConfig.cachedTD == null) {

// not in in the cache, let’s get it

ajaxListLog(“- Building new TD”);

ajaxListConfig.cachedTableID = tableid;

ajaxListConfig.cachedItemID = itemid;

ajaxListConfig.cachedItemColumn = column;

// escape the table id ({ and } should become \{ and \}

tableid = tableid.replace(/{/g, “\\{“).replace(/}/g, “\\}”);

// select them TR for the item

$itemrow = $(“#” + tableid + ” table[id='” + itemid + “‘]”).parent().parent();

// select the header row

$headerrow = $(“>tr:eq(0)”, $itemrow.parent());

// select the table in the header row for the specified column

$idtable = $(“th>div>table[Name='” + column + “‘]”, $headerrow);

// calculate the index of the column, based on the idtable

var columnIndex =$(“>th”,$headerrow).index($idtable.parent().parent());

// based on the index, let’s get the TD

ajaxListConfig.cachedTD = $(“>td:eq(” + columnIndex + “)”, $itemrow);

}

else

ajaxListLog(“- TD retreived from cache”);

return ajaxListConfig.cachedTD;

}

function setColumnValue(column, list, itemid, newstatus, tableid, wsurl) {

ajaxListLog(“setColumnValue entered.”)

// animate the table cell so it fades out, after that the new value is set in the cell

getItemTD(column, tableid, itemid).fadeTo(ajaxListConfig.animationSpeed,.01 , function() {

getItemTD(column, tableid,itemid).text(newstatus);

});

var batch =

“<Batch OnError=\”Continue\”> \

<Method ID=\”1\” Cmd=\”Update\”> \

<Field Name=\”ID\”>” + itemid + “</Field> \

<Field Name=\”” + column + “\”>” + newstatus + “</Field> \

</Method> \

</Batch>”;

var soapEnv =

“<?xml version=\”1.0\” encoding=\”utf-8\”?> \

<soap:Envelope xmlns:xsi=\”http://www.w3.org/2001/XMLSchema-instance\” \

xmlns:xsd=\”http://www.w3.org/2001/XMLSchema\” \

xmlns:soap=\”http://schemas.xmlsoap.org/soap/envelope/\”> \

<soap:Body> \

<UpdateListItems xmlns=\”http://schemas.microsoft.com/sharepoint/soap/\”> \

<listName>” + list + “</listName> \

<updates> \

” + batch + “</updates> \

</UpdateListItems> \

</soap:Body> \

</soap:Envelope>”;

ajaxListLog(“- Initializing AJAX call …”);

// make the ws call

$.ajax({

async: true,

url: wsurl,

beforeSend: function(xhr) {

xhr.setRequestHeader(“SOAPAction”,

http://schemas.microsoft.com/sharepoint/soap/UpdateListItems&#8221;);

},

type: “POST”,

dataType: “xml”,

data: soapEnv,

complete: function(xData, status) {

ajaxListLog(“- AJAX call done, status: ” + status);

// data is received, animate the cell so it fades in again

getItemTD(column, tableid, itemid).fadeTo(ajaxListConfig.animationSpeed, 1);

ajaxListLog(“- UI updated”)

},

contentType: “text/xml; charset=utf-8”

});

}

function ajaxListLog(message) {

// if logging is enabled, a div is added on op of the page to display

// log messages and thier timestamps (in ms)

if(ajaxListConfig.debug != 1)

return;

if(ajaxListConfig.logDiv == null) {

$(“body”).append(“<div id=’ajaxListLogDiv’ class=’ms-vb’ style=’position:absolute; \

background-color:White; padding:2px; border-width:1px; border-style:solid; \

border-color:Black;display:none; position:absolute; width:600px; height:150px; overflow:auto;’></div>”);

ajaxListConfig.logDiv = $(“#ajaxListLogDiv”);

var topPos = document.body.clientHeight – ajaxListConfig.logDiv.height() – 20

var leftPos = document.body.clientWidth – ajaxListConfig.logDiv.width() – 20;

ajaxListConfig.logDiv.css(“top”, topPos).css(“left”, leftPos).show(“fast”);

logTimer = new Date();

ajaxListLog(“Log Initialized!”);

}

var logContent = “<div style=’width:60px; float:left’>” + (new Date().getTime() – logTimer.getTime())

+ “ms</div><div>” + message + “</div>”;

ajaxListConfig.logDiv.prepend(logContent);

}

</script>

As you will see, the script (written by Jan Tielens) makes use of a JavaScript file hosted at Google. To save bandwidth traffic you can put a copy of the .js file in a SharePoint list somewhere which is easily accessible by the page you are customizing and edit the reference in the heading of the code above.

Depending on the list you are using and the columns you want to reference, you will also have to change some of the JavaScript.

Advertisements