Introduction
I found an interesting post of Rob Howard: Using Javascript to Manipulate a List Form Field. It describes how you can set default values based on the query string.
I started playing around a bit with it and elaborated a case more in detail.
Business Scenario
I have a list with items, which can be ordered. Each item has a price and belongs to a category.
Next to each item, I want a hyperlink: clicking on it will open a window where the end-user can give in the quantity the user wants to order for that item. I want to pass to that window the title, the category and the price of the item. As such, these fields are available for searching, sorting and so on in the transaction list. Off course, I want to avoid that the end-user has to give in again the price and the category of the item. Moreover, the end-user shouldn't be able to manipulate these fields.
Custom list with items
- Title column
- Category column (choice)
- Price column (currency)
Custom list with transactions
- Title column
- Category column (choice)
- Price column (currency)
- Quantity column (number)
Solution: Use some Javascript
- Open the AllItems.aspx page in Microsoft Office SharePoint Designer 2007.
- Right-click on the ListViewWebPart and choose Convert to XSLT Data View.
- Right-click the last column and choose Insert -> Column to the Right
- Right-click in a cell of the newly added column and choose Hyperlink.
- Enter the text you want to set as hyperlink in the Text to display and enter the address to the NewForm.aspx page of your transactions list. Additionally add the parameters you want to pass. In my case, it results in an address of: ../Transactions/NewForm.aspx?Title={@Title}&Category={@Category}&Price={@Price}. Hereby is the part to the left of the = free to choose, the part to the right of the = is the name of your column within {@}.
- Re-open the Items list: there will be a hyperlink available on each line. Clicking on it will redirect you to the NewForm.aspx page of the transaction list, and you pass to it some parameters through the querystring.
So far, so good. Now we still need to fill out the values based on the values in the querystring, and set the fields uneditable.
- Open the NewForm.aspx page of the transactions list in Microsoft Office SharePoint Designer 2007.
- Add following code right after the opening PlaceHolderMain tag within Javascript script tags:
_spBodyOnLoadFunctionNames.push("fillDefaultValues");
function fillDefaultValues(){
var qs=location.search.substring(1,location.search.length);
var args=qs.split("&");
var vals=new Object();
for (var i=0; i<args.length;i++){
var nameVal=args[i].split("=");
var temp=unescape(nameVal[1]).split('+');
nameVal[1]=temp.join('');
vals[nameVal[0]]=nameVal[1];
}
var title=vals["Title"];
if(title==undefined)
return;
var theSelect=getTagFromIdentifierAndTitle("select","Lookup","Title");
if(theSelect==null){
var theInput=getTagFromIdentifierAndTitle("input","","Title");
if(theInput==null){
return;
}
theInput.value=title;
document.getElementById(theInput.id).readOnly=true;
}
else{
theSelect.value=title;
document.getElementById(theSelect.id).readOnly=true;
}
var price=vals["Price"];
if(price==undefined)
return;
var theSelect=getTagFromIdentifierAndTitle("select","Lookup","Price");
if(theSelect==null){
var theInput=getTagFromIdentifierAndTitle("input","","Price");
if(theInput==null){
return;
}
theInput.value=price;
document.getElementById(theInput.id).readOnly=true;
}
else{
theSelect.value=price;
document.getElementById(theSelect.id).readOnly=true;
}
var category=vals["Category"];
if(category==undefined)
return;
var theSelect=getTagFromIdentifierAndTitle("select","DropDownChoice","Category");
if(theSelect==null){
var theInput=getTagFromIdentifierAndTitle("input","","Category");
if(theInput==null){
return;
}
theInput.value=category;
freezeValue(theInput);
}
else {
theSelect.value=category;
freezeValue(theSelect);
}
}
function setSelectedOption(select,value){
var opts=select.options;
var l=opts.length;
if(select==null)
return;
for(var i=0; i<l; i++){
if(opts[i].value==value){
select.selectedIndex=i;
return true;
}
}
}
function getTagFromIdentifierAndTitle(tagName,identifier,title){
var len=identifier.length;
var tags=document.getElementsByTagName(tagName);
for(var i=0;i<tags.length;i++){
var tempString=tags[i].id;
if(tags[i].title==title && (identifier=="" ||
tempString.indexOf(identifier)==tempString.length - len)){
return tags[i];
}
}
return null;
}
function freezeValue(tag){
var chosen=tag.options.selectedIndex;
tag.onchange=function(){
tag.options.selectedIndex=chosen;
}
tag.className="ms-MenuUIItemTableCellDisabled";
}
- Reclick the Order hyperlink on the Items list: your values will be filled in automatically on the transactions NewForm.aspx page and they will be uneditable by the end-user.
Some extra explanation:
For the functions fillDefaultValues, setSelectedOption and getTagFromIdentifierAndTitle: see Using Javascript to Manipulate a List Form Field.
Text fields can be set uneditable by using following code: document.getElementById().readOnly=true.
Choice (drop-down fields) cannot be set uneditable. To solve this, I created the function freezeValue.
This function resets each time an end-user clicks the drop-down box to its initial value: as such the end-user won't be able to post the form with another value than the one filled in by default by the values of the querystring.
To make it somewhat more userfriendly, I used a class of the SharePoint default css files: as such the drop-down box is grayed out, making it already somewhat clearer for the end-user that touching it makes no sense.
Continue reading......