Friday, July 20, 2012

Two Lookup field with more than 20 items not sohowing its dropdown when using jQuery tabs on the form and Single Click Problem

In Sharepoint 2010 working with Jquery Tabs,i found an issue with SharePoint Lookup Columns containing 20 or more items. Many of you might have already noticed that the Lookup dropdown control renders differently and If we click for dropdown on lookup at any tab all will be fine, but on another tab it wont show up anymore.

Problem:
Whenever, we click on that image it displays us with a drop-down containing all the values, but the funniest part is you can select a particular item either by double click or by selecting it once and clicking it else where on the page or by tabbing system of the keyboard. But I want it work like a normal drop-down selection in other words just with a single click and also the control should be closer to other controls from usability perspective.

Solution Steps:
We can overcome above problem by making few changes to the SharePoint CORE.js file which is available in layouts folder.bu we can not change that file directly because it will cause other other application as well.So is there any way ? Yes, we choose to override the function which causes this problem in just one page or the required pages. In order to achieve the above functionality we have to follow few steps:

So, modify master page :
1. Look for SharePoint:ScriptLink language="javascript" name="core.js" and Modify to OnDemand="False" Defer="False". as shown below.
<SharePoint:ScriptLink language="javascript" name="core.js" Defer="false" runat="server"/>

2.Look for the function “FilterChoice” in CORE.JS file.Copy this function and paste it in HTML Form Webpart in your page(NewForm.aspx or EditForm.aspx ) where you want this functionality to reflect.

Note:-Changes made in filter choice Marked in Green below.
 i) Below change fixes vertical position problem of lookup dropdown select control.
       x = offSet.left,
      y = offSet.top + 15,

Before adding above x and y value to filter choice function.

After adding above x and y value to filter choice function.




ii) Below will resolve double click problem with single click.
   var strHandler = " onclick=\"HandleOptDblClick()\" onkeydown=\"HandleOptKeyDown()\"";


3.Look for the function("function EnsureSelectElement") and override it as well.Copy this function and paste it in HTML Form Webpart in your page(NewForm.aspx or EditForm.aspx ) where you want this functionality to reflect.

After following above three steps you will able to see below result screen.



Finally Copy below Code as it is and paste it HTML Form Webpart in your page( NewForm.aspx or EditForm.aspx ) and see the reulst as you can see in above screen.

<script type="text/javascript">
        function FilterChoice(opt, ctrl, strVal, filterVal) {

            if (typeof (opt) != "undefined") {
                var i,
                    cOpt = 0,
                    bSelected = false,
                    strHtml = "",
                    strId = opt.id,
                    strName = opt.name,
                    strMatch = "",
                    strMatchVal = "",
                    strOpts = ctrl.choices,
                    rgopt = strOpts.split("|"),
                    offSet = $(ctrl).position(),
                   
x = offSet.left,
                    y = offSet.top + 15,
                   
                    strHidden = ctrl.optHid,
                    iMac = rgopt.length - 1,
                    iMatch = -1,
                    unlimitedLength = false,
                    strSelectedLower = "";
                if (opt != null && opt.selectedIndex >= 0) {
                    bSelected = true;
                    strSelectedLower = opt.options[opt.selectedIndex].innerText;
                }
                for (i = 0; i < rgopt.length; i = i + 2) {
                    var strOpt = rgopt[i];
                    while (i < iMac - 1 && rgopt[i + 1].length == 0) {
                        strOpt = strOpt + "|";
                        i++;
                        if (i < iMac - 1) {
                            strOpt = strOpt + rgopt[i + 1];
                        }
                        i++;
                    }
                    var strValue = rgopt[i + 1];
                    var strLowerOpt = strOpt.toLocaleLowerCase();
                    var strLowerVal = strVal.toLocaleLowerCase();
                    if (filterVal.length != 0)
                        bSelected = true;
                    if (strLowerOpt.indexOf(strLowerVal) == 0) {
                        var strLowerFilterVal = filterVal.toLocaleLowerCase();
                        if ((strLowerFilterVal.length != 0) && (strLowerOpt.indexOf(strLowerFilterVal) == 0) && (strMatch.length == 0))
                            bSelected = false;
                        if (strLowerOpt.length > 20) {
                            unlimitedLength = true;
                        }
                        if (!bSelected || strLowerOpt == strSelectedLower) {
                            strHtml += "<option selected value=\"" + strValue + "\">" + STSHtmlEncode(strOpt) + "</option>";
                            bSelected = true;
                            strMatch = strOpt;
                            strMatchVal = strValue;
                            iMatch = i;
                        }
                        else {
                            strHtml += "<option value=\"" + strValue + "\">" + STSHtmlEncode(strOpt) + "</option>";
                        }
                        cOpt++;
                    }
                }
                var strHandler = " onclick=\"HandleOptDblClick()\" onkeydown=\"HandleOptKeyDown()\"";               

                var strOptHtml = "";
                if (unlimitedLength) {
                    strOptHtml = "<select tabIndex=\"-1\" ctrl=\"" + ctrl.id + "\" name=\"" + strName + "\" id=\"" + strId + "\"" + strHandler;
                }
                else {
                    strOptHtml = "<select class=\"ms-lookuptypeindropdown\" tabIndex=\"-1\" ctrl=\"" + ctrl.id + "\" name=\"" + strName + "\" id=\"" + strId + "\"" + strHandler;
                }
                if (cOpt == 0) {
                    strOptHtml += " style=\"display:none;position:absolute;z-index:2;left:" + x + "px;top:" + y + "px\" onfocusout=\"OptLoseFocus(this)\"></select>";
                }
                else {
                    strOptHtml += " style=\"position:absolute;z-index:2;left:" + x + "px;top:" + y + "px\"" + " size=\"" + (cOpt <= 8 ? cOpt : 8) + "\"" + (cOpt == 1 ? "multiple=\"true\"" : "") + " onfocusout=\"OptLoseFocus(this)\">" + strHtml + "</select>";
                }
                opt.outerHTML = strOptHtml;
                var hid = document.getElementById(strHidden);
                if (iMatch != 0 || rgopt[1] != "0")
                    hid.value = strMatchVal;
                else
                    hid.value = "0";
                if (iMatch != 0 || rgopt[1] != "0")
                    return strMatch;
                else return "";
            }
        }


        _spBodyOnLoadFunctionNames.push("FilterChoice");      
        function EnsureSelectElement(ctrl, strId) {
            $("#" + strId).remove();
            var select = document.getElementById(strId);
            if (select == null) {
                select = document.createElement("SELECT");
                ctrl.parentNode.appendChild(select);
                select.outerHTML = "<select id=\"" + strId + "\" ctrl=\"" + ctrl.id + "\" class=\"ms-lookuptypeindropdown\" name=\"" + strId + "\" style=\"display:none\" onfocusout=\"OptLoseFocus(this)\"></select>";
                FilterChoice(select, ctrl, ctrl.value, "");
            }
            return document.getElementById(strId); ;
        }
    </script>

Feel free to post your comments.

Thanks for visiting my blog !!!

1 comment: