Friday, December 18, 2009

List Checkboxes, Indexing, and Input Forms

When you have a SharePoint List you can easily create columns. The Choice column type is great as you can specify a list of possible choices for the user. If a user should have the option to select multiple options from the list you can set the choice column to display using checkboxes. Good stuff, unless you want the user to be able to search on those choices.

SharePoint has a limitation in that choice columns set to use checkboxes cannot be indexed for searching.

If you must have a list of choices that allow multiple selections via checkboxes and is indexable then a workaround is required. The best option found so far is using a “Multiple lines of text” column, setting it to be indexed, and then modifying the input form with the checkboxes and using that to populate the text box.

After that you must set up your New and Edit import forms. Start off with the steps in the Working with a List Input Form post.

Once you are ready, you can add your choices and the JavaScript needed to add selected choices to the text field. The following work is built off of the following Microsoft post for Using Javascript to Manipulate a List Form Field.

This is a very basic implementation showing the general idea. Future posts will focus on using AJAX to pull lists of items which could be used to automatically populate the set of checkboxes.

The checkboxes can go in the same table cell as the text field. In this case I have 10 checkboxes:

<input name="Checkbox1" id="Checkbox1{generate-id()}" type="checkbox" value="Value1" onclick="updatechoices()" />Option1<br />
<input name="Checkbox2" id="Checkbox2{generate-id()}" type="checkbox" value="Value2" onclick="updatechoices()" />Option2<br />
<input name="Checkbox3" id="Checkbox3{generate-id()}" type="checkbox" value="Value3" onclick="updatechoices()" />Option3<br />
<input name="Checkbox4" id="Checkbox4{generate-id()}" type="checkbox" value="Value4" onclick="updatechoices()" />Option4<br />
<input name="Checkbox5" id="Checkbox5{generate-id()}" type="checkbox" value="Value5" onclick="updatechoices()" />Option5<br />
<input name="Checkbox6" id="Checkbox6{generate-id()}" type="checkbox" value="Value6" onclick="updatechoices()" />Option6<br />
<input name="Checkbox7" id="Checkbox7{generate-id()}" type="checkbox" value="Value7" onclick="updatechoices()" />Option7<br />
<input name="Checkbox8" id="Checkbox8{generate-id()}" type="checkbox" value="Value8" onclick="updatechoices()" />Option8<br />
<input name="Checkbox9" id="Checkbox9{generate-id()}" type="checkbox" value="Value9" onclick="updatechoices()" />Option9<br />
<input name="Checkbox10" id="Checkbox10{generate-id()}" type="checkbox" value="Value10" onclick="updatechoices()" />Option10<br />
<br />


The following javascript is the first thing in the <asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server"> section.

<script type=text/javascript>

// this function will identify the text field that you are adding your choices to
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;
}

// put the checked items into the text box
function updatechoices() {
var choicelist = "";
var checkboxidprefix = "Checkbox"; //checkbox id prefix
var numberofchoices = 10; //change to reflect the number of checkboxes
var nameoftextbox = "Choice"; //change to reflect the name of the textarea
// get the values of the checked checkboxes, put them in a semicolon delimented string
for(var i = 1; i <= numberofchoices; i++) {
checkboxnumber = checkboxidprefix + i;
if (document.getElementById(checkboxnumber).checked == true) {
choicelist = choicelist + document.getElementById(checkboxnumber).value + "; ";
}
}
// trim whitespace off ending
while (choicelist.substring(choicelist.length-1,choicelist.length) == ' ') {
choicelist = choicelist.substring(0,choicelist.length-1);
}
// put the list of choices into the text box
var theSelect = getTagFromIdentifierAndTitle("textarea","",nameoftextbox);
document.getElementById(theSelect.id).value = choicelist;

}

// pull the text out of the text box and set the checked values on the checkboxes (for when page is loaded)
function SetCheckboxes () {
var checkboxidprefix = "Checkbox"; //checkbox id prefix
var numberofchoices = 10; //change to reflect the number of checkboxes
var nameoftextbox = "Choice"; //change to reflect the name of the textarea
var ChoiceField = getTagFromIdentifierAndTitle("textarea","",nameoftextbox);
var ChoiceValues = document.getElementById(ChoiceField.id).value;
//if only one choice is set, check that checkbox
if (ChoiceValues.indexOf(";") <=0) {
for(var i = 1; i <= numberofchoices; i++) {
checkboxnumber = "checkbox" + i;
if (document.getElementById(checkboxnumber).value == ChoiceValues) {
document.getElementById(checkboxnumber).checked = true;
}
}
} else { //else split up the text box info and check the appropriate boxes
ChoiceValues = ChoiceValues.replace(/; /g, ';');
var ChoiceValuesArray = ChoiceValues.split(';');
for (k=0;k<ChoiceValuesArray.length;k++) {
for(var i = 1; i <= numberofchoices; i++) {
checkboxnumber = checkboxidprefix + i;
if (document.getElementById(checkboxnumber).value == ChoiceValuesArray[k]) {
document.getElementById(checkboxnumber).checked = true;
}
}
}
}
}

// onload set the checkboxes to match the text box
_spBodyOnLoadFunctionNames.push("SetCheckboxes");
</script>