If you need to hide and display the SharePoint QuickLaunch menu on every page in a site then you are going to have to go into the master page to do it. (Be careful, screwing up a master page can lead to a completely damaged site!)

  1. Choose a location in the master page where you want your QuickLaunch toggle icon to be displayed. (I use the space at the top right of the page, just next to the blue Help Icon).
  2. Place the following line after the link to the Help Icon.

    <td class=”ms-globallinks”><a href=’#’ id=”controller”><img src=”/_layouts/images/bizdatawebpart.gif” border=”0″></td>

  3. You can use any image which suits your purpose from the /_layouts/images/ folder.
  4. In the <HEAD> section of the Master Page, reference the following files which are necessary for the Multiline Preview:

    <script type=”text/javascript” src=”/sites/pathtoyourdoclibrary/LimitMultilineTextInView.js”></script>
    <script type=”text/javascript” src=”/sites/ pathtoyourdoclibrary /jquery-1.3.2.min.js”></script>

  5. Place the following code at the foot of the page, just before the <BODY> tag:

            <script type=”text/javascript” src=”/sites/ pathtoyourdoclibrary /PreviewHover.js”></script>

            <script type=”text/javascript” src=”/sites/ pathtoyourdoclibrary /ToggleQuickLaunch.js”></script>


Please note that the JavaScript files must be in the order specified for the functionality to operate correctly.

If you want to control the width of the mouseover popup, go into the LimitMultilineTextInView.js script and hard-code the width parameter.



It is useful to use the Append text functionality to multiline text fields in SharePoint, but it is difficult to optimize the display of these entries in a SharePoint view. Using a content editor web part, however, it is possible to create a text box which will display the contents of the multiline text field in a box when the user hovers over an appropriate link.

To use this technique, add a Content Editor Web Part to the page with your view, below the view itself and place the following code in the source:

<script type=”text/javascript” src=”/test/English/Javascript/jquery-1.3.2.min.js”></script>

<script type=”text/javascript” src=”/test/English/Javascript/Preview_DispForm_metadata.js”></script>

<script type=”text/javascript”>

hoverImg = ‘/_layouts/images/OPENDB.GIF’;

hoverImgDescription = ‘Hover mouse over this image to preview the metadata’;

arrOfFieldsToShow = [‘MultilinePlainText’];

prependHoverImageTo = ‘MultilinePlainText’; // If “append-field” insert FieldInternalName here


You will need to insert the correct path to the two JavaScript files which are required and replace MultilinePlainText with the name of your text field.

You will also need two resource JavaScript files, Preview_DispForm_metadata.js, written by Alexander at who is the author of these techniques. The other is the jquery file.

The custom JavaScript is available from:


One of the major shortcomings of SharePoint 2007 is that there is no easy way to display items from a list in another site collection. This is the kind of thing which is needed on a daily basis, in order for information to be centralized effectively and to avoid duplication.

I am currently developing a series of SharePoint templates, and I want training resources for these templates to be grouped in one central site collection. Each site created from one of the templates will need to pick up certain list information of training materials relevant for the template which has been used to create the site.

To meet this need, I decided to tackle this issue and find a solution. As a result, I found an approach (by Christophe at Path to SharePoint) which is a pure JavaScript solution and so can be configured through the Content Editor Web Part, making it available to power users. To use it, follow the steps below:

  1. Create a web part page and insert a Content Editor Web Part.
  2. Paste the following code into the Source Editor:
<!– Load and display list – iframe version –>

<!– Questions and comments: –>

<DIV id=”ListPlaceholder”><IMG src=”/_layouts/images/GEARS_AN.GIF”></DIV>

<script type=”text/javascript”>

var mystring1 = “<iframe id=\”SourceList\” style=\”display:none;\” src=\””;

var mystring2 = “/sites/it-Outages”;

var mystring3 = “/lists/outages/sapoutages.aspx\” onload=\”DisplayThisList()\”></iframe>”;



<script type=”text/javascript”>

function DisplayThisList()


var placeholder = document.getElementById(“ListPlaceholder”);

var displaylist = null;

var sourcelist = document.getElementById(“SourceList”);

try {


// Firefox, Opera

{displaylist = sourcelist.contentDocument.getElementById(“WebPartWPQ2”) ;}

else if(sourcelist.contentWindow)

// Internet Explorer

{displaylist = sourcelist.contentWindow.document.getElementById(“WebPartWPQ2”) ;}

else if(sourcelist.document)

// Others?

{displaylist = sourcelist.document.getElementById(“WebPartWPQ2”) ;}


catch(err) { alert (“Loading failed”);}


var allDescendants = displaylist.getElementsByTagName(“*”);

for (i=0;i<allDescendants.length;i++) {






placeholder.innerHTML = displaylist.innerHTML;



  1. This example displays a list of SAP Outages from the IT-Outages site directly in a CDM Blog page. You will need to adapt the path according to your needs.

I will explain in a later blog post why it is useful to have variables available in the JavaScript file as shown above.

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=””></script&gt;

<script type=”text/javascript”>

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

// Created by Jan Tielens,,


// – 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 + “‘);”);




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=’’&gt; \

<soapenv:Body> \

<GetListItems xmlns=’’&gt; \

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

<viewFields> \

<ViewFields> \

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

</ViewFields> \

</viewFields> \

<query> \

<Query><Where> \

<Eq> \

<FieldRef Name=’ID’ /> \

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

</Eq> \


</query> \

</GetListItems> \

</soapenv:Body> \


ajaxListLog(“- Initializing AJAX call …”);

var itemStatus;


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);



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> \


var soapEnv =

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

<soap:Envelope xmlns:xsi=\”\” \

xmlns:xsd=\”\” \

xmlns:soap=\”\”> \

<soap:Body> \

<UpdateListItems xmlns=\”\”> \

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

<updates> \

” + batch + “</updates> \

</UpdateListItems> \

</soap:Body> \


ajaxListLog(“- Initializing AJAX call …”);

// make the ws call


async: true,

url: wsurl,

beforeSend: function(xhr) {



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)


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>”;




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.

It would be useful oftentimes in SharePoint, to be able to edit an item in a pop-up window. This can be done with a bit of Javascript in a Content Editor Web Part (CEWP) in the list view page concerned.

To use an additional Edit Content Block menu item as above, paste the following Javascript into a CEWP in the page concerned:

<script type=”text/javascript”>

function Custom_AddListMenuItems(m, ctx) {

var viewURL = window.location.protocol + “//” + +

ctx.displayFormUrl + “?ID=” + currentItemID;

var editURL = window.location.protocol + “//” + +

ctx.editFormUrl + “?ID=” + currentItemID;

var openMenu = CASubM(m,”Open in New Window”);

CAMOpt(openMenu, “View Item”, “‘” + viewURL + “‘);”);

CAMOpt(openMenu, “Edit Item”,

“‘” + editURL + “‘);”, “/_layouts/images/edititem.gif”);

return false; // render the default menu items too



With thanks to Jan Tielens