Wednesday, December 9, 2009

Connected Lookup field in Sharepoint using Content Editor Webpart and Javascript

Several times we are required to develop some connected lookup columns like Country-State-City. I have also come across similar requirement and that is also without writing any server side code and without third party controls.

To meet this requirement I have created two lists,

1. Country and State Mapping list.




2. Second List where I want to display State based on the selected Country from Drop Down.


while creating this list I have created Country column as Lookup Column to the List1 with Country [LinkTitle] Column and State Column as Choice (or you can create lookup column on list1 with State field].

After creating this basic environment ready, now its time to write Javascript in content editor webpart using XMLHTTP object.
  1. Open List2 -> Click on New and it will open NewForm.aspx page.
  2. In the address bar add "?PageView=Shared&ToolPaneView=2" after NewForm.aspx and your URL will look like NewForm.aspx?PageView=Shared&ToolPaneView=2.
  3. This will open NewForm.aspx in Edit mode, and now add Content Editor Web Part to the page.
  4. Open the Source Editor of the Content Editor Web Part and add the below code. I have included the comments within functions.
<script type="text/javascript">
 
    _spBodyOnLoadFunctionNames.push("PageOnLoad");
 
 
    function PageOnLoad() {
        // This function will add onchange event to the 
        //Country DropDown field and call OnChanged function.
        var lookupElement = GetElementByTypeAndTitle('SELECT''Country');
        if (lookupElement != null) {
            lookupElement.onchange = function () { 
            OnChanged(lookupElement.options[lookupElement.selectedIndex].text)};
        }
    }
 
    function OnChanged(FilterValue) {
        // siteName - the root / and possibly sub site you are working on
        // lookupListName - the guid for the list you want to use as lookup
        // lookupViewName - the guid for the view filtering the content of the list
        // NOTE: TO DERIVE THE GUID FOR THE LIST NAME AND VIEW NAME
        // Open the List -> Settings -> List Settings -> Click on "All Items" view,
        // From the URL you can get the ListName GUID and ListView GUID.
        // textField - the field you want to show to the user
        // valueField - this is most of the time the internal ID field
        // FilterField - the field you want to be a filter
        // FilterValue - the filter's value
 
 
        var siteName = "http://sharepointsite/";
        var lookupListName = "{0FC682A9-1872-46D9-B8E3-E32A9E92EF74}";
        var lookupViewName = "{927FACB3-5CAF-48AE-9EFF-6578B9919AF8}";
        var FilterField = "LinkTitle";
        var textField = "ows_State";
        var valueField = "ows_State";
 
        var filterElement = GetElementByTypeAndTitle('SELECT''State');
        filterElement.innerHTML = "";
        var reqstring = siteName + "/_vti_bin/owssvr.dll?CS=109&XMLDATA=1&RowLimit=0&List=" 
        + lookupListName + "&View=" + lookupViewName;
 
        if (FilterValue != "")
            reqstring = reqstring + "&FilterField1=" + escape(FilterField) + "&FilterValue1=" 
            + escape(FilterValue);
 
 
        var req = new ActiveXObject("MSXML2.XMLHTTP");
        req.open("GET", reqstring, false);
        req.send();
 
        // -- loading response in XML Document
        var doc = new ActiveXObject("MSXML2.DOMDocument");
        doc.loadXML(req.responseText);
 
        var data = doc.documentElement.childNodes(1);
 
 
        for (i = 0; i < data.childNodes.length; i++) {
            var optionText = data.childNodes(i).attributes.getNamedItem(textField).value;
            var optionValue = data.childNodes(i).attributes.getNamedItem(valueField).value;
 
            var opt = document.createElement("OPTION");
            filterElement.options.add(opt);
            opt.innerText = optionText;
            opt.value = optionValue;
        }
    }
 
    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>