Our client wants to use a MultipleSelection List Box in the custom list form (designed by InfoPath), but he wantto limit number of the choices, the user only can select one or two choices,then the question comes out, there isn’t any out box function for InfoPath andSharePoint to only allow user select number of choices, so we need to writesome code to implement this requirement.
If I write code in C# to implement this function, we need to deploy the dll to GACof every SharePoint EF and App server, client don’t like that since securityreason.
Atlast I decide to use JavaScript to implement this requirement, but it is noteasy to do, I have tired some ways before I found the correct way:
1. My first try is use Query toadd event in the document ready function:
$(document).ready(function () { checkboxes = $("input[type='checkbox']"); if (checkboxes.length != 0) { checkboxes.each( function () { var oldAttributeValue = $(this)[0].attributes["onClick"].nodeValue; var newAttributeValue = "return CheckedCheckBox(this) && (MultiSelectListBoxCollection.OnClick(this, event)); "; if (oldAttributeValue != newAttributeValue) $(this)[0].setAttribute("onClick", newAttributeValue); }); }); function CheckedCheckBox(checkBox, event) { if (checkBox.checked) { var checkedCount = 0; checkboxes = $("input[type='checkbox']"); checkboxes.each( function () { if ($(this)[0].checked) checkedCount++; }); if (checkedCount >= 3) { alert("Only can select one option"); checkBox.click(); return false; } } return true; }
But it can’t get the check box in the document ready function,the length ofcheckboxes always 0, that maycause by the check box control is load by Ajax.
2. The second way I tried is, add timer to add event:
$(document).ready(function () { timeout = setTimeout('timeout_trigger()', 1000); }); function timeout_trigger() { checkboxes = $("input[type='checkbox']"); // alert(checkboxes.length); if (checkboxes.length != 0) { checkboxes.each( function () { var oldAttributeValue = $(this)[0].attributes["onClick"].nodeValue; var newAttributeValue = "return CheckedCheckBox(this) && (MultiSelectListBoxCollection.OnClick(this, event)); "; if (oldAttributeValue != newAttributeValue) $(this)[0].setAttribute("onClick", newAttributeValue); }); if (timeout) { clearTimeout(timeout); timeout = null; } } } function CheckedCheckBox(checkBox, event) { if (checkBox.checked) { var checkedCount = 0; checkboxes = $("input[type='checkbox']"); checkboxes.each( function () { if ($(this)[0].checked) checkedCount++; }); if (checkedCount >= 3) { alert("Only can select one option"); checkBox.click(); return false; } } return true; }
That script doesn’t work either, since thecontrol refresh after the user do click one of the checkbox, it change the onClickto original value
3. The third approach I tried is using theDOMSubtreeModified
$(document).ready(function () { if (document.addEventListener){ document.addEventListener('DOMSubtreeModified', timeout_trigger); } else if (document.attachEvent){ document.attachEvent('DOMSubtreeModified', timeout_trigger); } }); function timeout_trigger() { checkboxes = $("input[type='checkbox']"); // alert(checkboxes.length); if (checkboxes.length != 0) { checkboxes.each( function () { var oldAttributeValue = $(this)[0].attributes["onClick"].nodeValue; var newAttributeValue = "return CheckedCheckBox(this) && (MultiSelectListBoxCollection.OnClick(this, event)); "; if (oldAttributeValue != newAttributeValue) $(this)[0].setAttribute("onClick", newAttributeValue); }); if (timeout) { clearTimeout(timeout); timeout = null; } } } function CheckedCheckBox(checkBox, event) { if (checkBox.checked) { var checkedCount = 0; checkboxes = $("input[type='checkbox']"); checkboxes.each( function () { if ($(this)[0].checked) checkedCount++; }); if (checkedCount >= 3) { alert("Only can select one option"); checkBox.click(); return false; } } return true }
It doesn’t work either.
4. The last one is the correctsolution to overwrite the original onlick event method for Multiple Selection List BoxMultiSelectListBoxCollection.OnClick
var checkboxes; var timeout; var oldFunction; $(document).ready(function () { oldFunction = MultiSelectListBoxCollection.OnClick; MultiSelectListBoxCollection.OnClick = CheckedCheckBox; }); function CheckedCheckBox(checkBox, event) { if(checkBox.checked) { var checkedCount = 0; checkboxes = $("input[type='checkbox']"); checkboxes.each( function(){ if($(this)[0].checked) checkedCount ++; }); if(checkedCount >= 3) { alert("Only can select one option"); checkBox.click(); return false; } } return oldFunction(checkBox, event); }