Tuesday, June 11, 2013

Get sharepoint lookup Onchange Event or Selected Index Change Event

SharePoint Lookup type can allow user to pick up the items from existing List, when editing the item it will show as a dropdown box (<SELECT> Element  in HTML ). Sometimes we may want to fire the onchange event when the selected item changed.  This is easy by using JavaScript to bind the onchange event to the control. First we find out the Element by <SELECT> tag and then bind the onchange to it.

 <script type="text/javascript">
_spBodyOnLoadFunctionNames.push("PageOnLoad"); 
 function PageOnLoad() {
//find your lookupElement from the page.
     var lookupElement = GetElementByTypeAndTitle(‘SELECT’,’My Lookup Field’);
    if ( lookupElement != null)
lookupElement.onchange = function() { OnChanged() }; 
   } 
function OnChanged(){
      Alert( ‘selected item changed’);
}
   
function GetElementByTypeAndTitle(elementType, elementTitle) {
    //get the Element by tag name.
    var allElements = document.getElementsByTagName(elementType);

    for (var i = 0; i < allElements.length; i++) {
        //compare the Title.
        if (allElements [i].title == elementTitle)
            return allElements [i];
    }
    return null;
}
<Script>
Open SharePoint Designer and add above script to the page.
There is another way to add the script to the page without using SPD, go to the Edit page, on the Browser URL address bar, append ‘&toolpaneview=2’ at the end of the url and hit Enter.it will go to web part page design UI. So just add a ‘Content Editor WebPart’, click ‘Soruce Editor’ and paste above script into it.
Now try it out, every time when you select from Lookup column it should fire the onchange event. It’s pretty easy, right?

Everything seems working fine when the Lookup list not having too many items,actually less than 20 items. but when the lookup list have more than 20 items the above script will stop working without give you any warning( most of people will suffer this and try break their head to figure out what happen? me too).

This is because when lookup list items are more than 19, SharePoint try to give a more ‘user friendly’ contro.it allow user to input and search for items. This is good when lookup list have large number of items, but shouldn’t it give us warning ahead?
Now when you check the page source you will find out the lookup field it’s now rendered as <INPUT> Element but not <SELECT>, so you are failed to find the Element by <SELECT> tag, so whenever we need to bind onchange to the Look Up field, we need to handle thses 2 situation,items less than 20 or more.
<script type="text/javascript"> 
_spBodyOnLoadFunctionNames.push("PageOnLoad");  
 function PageOnLoad() {
//find your lookupElement from the page.
     var lookupElement = GetLookupField(’My Lookup Field’);
   
//because browser render Lookup field diferrent when items number below or more than 20.
    //so we bind diffrent event to the Lookup.
    if (lookupElement.length < 20)
        lookupElement.onchange = function() { OnChanged () };
    else //for more than 20 items
        lookupElement.onblur = function() { OnChanged () };
   }

function OnChanged(){
      Alert( ‘selected item changed’);
}
   
//this function is used to get Lookup dropdown element.
function GetLookupField(elementTitle) {
    //first we try to see if it’s being rendered as <select> tag. for items less then 20
    var lookupElement = GetElementByTypeAndTitle('SELECT', elementTitle); 
    //if more than 20 items, it will be render as <input>
    if (lookupElement == null)
        lookupElement = GetElementByTypeAndTitle('INPUT', elementTitle); 
    return lookupElement;
function GetElementByTypeAndTitle(elementType, elementTitle) {
    //get the Element by tag name.
    var allElements = document.getElementsByTagName(elementType); 
    for (var i = 0; i < allElements.length; i++) {
        //compare the Title.
        if (allElements [i].title == elementTitle)
            return allElements [i];
    }
    return null;
</script> 
The above script should now be able to handle select change no matter items number < 20 or not.

A small tips:
Modfiy the CORE.JS in MOSS HIVE\1033 a little bit to make above script works better.
Search this line:
var strHandler = "ondblclick=\"HandleOptDblClick()\" onkeydown=\"HandleOptKeyDown()\""; 
and modify it as onclick.
var strHandler = "onclick=\"HandleOptDblClick()\" onkeydown=\"HandleOptKeyDown()\"";
this will allow user to just click once to select item instead of double click.

Add the following 2 lines into function HandleOptDblClick() to ensure OnChange event fired.
function HandleOptDblClick()
{
      var opt=event.srcElement;
      var ctrl=document.getElementById(opt.ctrl);
      SetCtrlFromOpt(ctrl, opt);
      SetCtrlMatch(ctrl, opt);
      opt.style.display = "none";
//add this 2 lines here to fire blur event.
      ctrl.focus();
      ctrl.blur();
////////////
}

Thursday, June 6, 2013