Scenario
SharePoint 2010 custom list (or a library) has a lookup column and we need to filter the values based on some criteria. This applies to cascading drop-down lists where the target drop-down is a look-up column.
A classic example here is filtering out Countries based on selected Region.
In SharePoint 2010, we would have both Region and Country as look-up columns which reference their respective lists. Country list would have a region column (lookup on Region List), indicating the region to which the country belongs to.
Normally, we would write a JavaScript code to do the following:
- Get the Country drop-down control, using
getTagFromIdentifierAndTitle
function (implementation of function provided in the code below). - Fetch the country values from Country list based on the selected region (using CAML query).
- Remove the values from Country drop-down which are not present in the retrieved values. We need to do this because Country column is a lookup column and values would be populated automatically.
Problem
The problem is with rendering of lookup column (in Internet Explorer) when the values in lookup column are more than 20. If the number of items in lookup column is less than 20, then it is rendered as a Option
tag. However, if the number of items is 20 or more than 20, then the lookup column is rendered as INPUT
tag. So while writing the logic of filtering, we need to consider this complication.
Solution
First, we will declare the required variables and configure On Load function for SharePoint.
var result;
_spBodyOnLoadFunctionNames.push("Initialize()");
In my example, I am picking up the value for filtering on which the target drop-down will be filtered, from a hidden field variable. Then I write a CAML query to get the values from the Country List and load the result in context variable.
function Initilize() {
var ctx = new SP.ClientContext.get_current();
var filterToken = document.getElementById(");
var website = ctx.get_web();
var targetList = website.get_lists().getByTitle("CountryList");
var camlQuery = "";
camlQuery += "" + filterToken.value + "";
camlQuery += "";
var query = new SP.CamlQuery();
query.set_viewXml(camlQuery);
result = targetList.getItems(query);
ctx.load(result);
ctx.executeQueryAsync(OnQuerySucceeded, OnQueryFailed);
}
If the above process is successful, we want to fire the OnQuerySucceeded
function, else we want OnQueryFailed
method to be called.
Here is the implementation of getTagFromIdentifierAndTitle
function:
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;
}
In OnQuerySucceeded
function, we will check whether the drop-down has been rendered as option tag or an input tag. Based on this value, we will process the filtering accordingly. In this example, I have written code only for more than 20 items conditions, i.e., when the drop-down list is rendered as input tag.
function onQuerySucceeded() {
var isOption = false;
var arrayLookUpValue = new Array();
var arrayLookUpId = new Array();
var walker = 0;
var theInput = getTagFromIdentifierAndTitle("select", "", "Country");
if (theInput == null) {
theInput = getTagFromIdentifierAndTitle("input", "", "Country");
theInput.setAttribute("readonly", "true");
isOption = false;
}
else {
isOption = true;
}
if (theInput != null) {
var enumerator = result.getEnumerator();
while (enumerator.moveNext())
{
var lookUpItem = enumerator.get_current();
var lookUpValue = lookUpItem.get_item
("Action").get_lookupValue();
var lookUpId = lookUpItem.get_item("Action").get_lookupId();
if (lookUpValue != null && lookUpValue != undefined){
arrayLookUpValue[walker] = lookUpValue;
}
else{
arrayLookUpValue[walker] = "";
}
if (lookUpId != null && lookUpId != undefined){
arrayLookUpId[walker] = lookUpId;
}
else{
arrayLookUpId[walker] = "";
}
walker++;
}
if (isOption != true) {
var newChoicesList = ";
for (var i = 0; i 0){
/*Set the values to choice property of the
drop-down variable*/
theInput.choices = newChoicesList.substring
(0, newChoicesList.length – 1);
}
else{
theInput.choices = "(None)|0?;
}
theInput.value = "";
}
else{
}
}
}
function onQueryFailed() {}