Initial Filtering

Apr 8, 2010 at 11:13 PM

Thank you for writing up this Javascript and sharing it!  It has proven quite useful and timely.

I had one issue though I am hoping someone might be able to help with.  When the form is loaded, all values in the child lookup are displayed.  Once you make a selection in the parent though, it all works correctly. 

Is there a way to force the child list to be properly sorted based on the parent's initial value?

 

Thanks.

Apr 14, 2010 at 7:53 AM

Try to add something like this in the content editor below all the other scripting. It calls the filter function once for each cascading dropdown.

<script language="javascript" defer>
for(j = 0; j < CascadingDropdowns.length; j++) {
	FilterChooicesForMyChild(CascadingDropdowns[j].parentLookup.Object);
}
</script>

Oct 26, 2010 at 12:39 PM

For me it worked when i did like this

// Function added By me to initiate lookup. This function is then called on page load after the method "addHandler"
function doFilter()
{

for(j = 0; j < CascadingDropdowns.length; j++) {
 FilterChooicesForMyChild(CascadingDropdowns[j].parentLookup.Object);
}

}
//Start the party after the DOM is loaded

_spBodyOnLoadFunctionNames.push('addHandler');
_spBodyOnLoadFunctionNames.push('doFilter'); // Added By me. Adding it after addHandler causes it to be called after addHandler

Nov 19, 2010 at 8:08 AM
Edited Nov 19, 2010 at 9:33 AM

Chefren77, your script isn't working for me.

ZealAnsari,
It is working for my second cascaded lookup (var ccd2), but not for the first (var ccd1).

Thanks for any responses.

Jan 10, 2011 at 8:08 AM
Edited Jan 10, 2011 at 8:09 AM
zealAnsari wrote:

For me it worked when i did like this

// Function added By me to initiate lookup. This function is then called on page load after the method "addHandler"
function doFilter()
{

for(j = 0; j < CascadingDropdowns.length; j++) {
 FilterChooicesForMyChild(CascadingDropdowns[j].parentLookup.Object);
}

}
//Start the party after the DOM is loaded

_spBodyOnLoadFunctionNames.push('addHandler');
_spBodyOnLoadFunctionNames.push('doFilter'); // Added By me. Adding it after addHandler causes it to be called after addHandler

zealAnsari,
your code won't reset correctly the child value once the item is edited. here is my update that should do that:

replace in the original spcd.js file:

 

_spBodyOnLoadFunctionNames.push('addHandler');

 

with:

 

function doFilter()
{
	// first let get the childs value that needs to be re-set
	var childValue = CascadingDropdowns[0].childLookup.Object.options[CascadingDropdowns[0].childLookup.Object.options.selectedIndex].text;
	
	//now let's apply the filter
	for(j = 0; j < CascadingDropdowns.length; j++) {
 	FilterChooicesForMyChild(CascadingDropdowns[j].parentLookup.Object);
	}
	// should be notified when the web service async call is done and not just 
	// wait 1 second.
	// if someone wants to refactor the code it would be great!
	window.setTimeout(function(){setChildValue(childValue)}, 1000);	

}
function setChildValue(childValue)
{
	//get the childs dropdown options
	var childOptions = CascadingDropdowns[0].childLookup.Object.options;
	
	//let cycle the dropdown's items to find our childValue
	var isfound = false;
	for(i = 0; i < childOptions.length; i++) {
		if(childOptions[i].text == childValue) {
			//alert(childOptions[i].text + ' ==' + childValue);
			CascadingDropdowns[0].childLookup.Object.selectedIndex = i;
			isfound = true;
			break;
		}
		else{
			//alert(childOptions[i].text + ' !=' + childValue);
		}
	}
	// let's see if we found it..
	if (isfound == false) {
		CascadingDropdowns[0].childLookup.Object.selectedIndex = 0;
	}
}



//Start the party after the DOM is loaded
_spBodyOnLoadFunctionNames.push('addHandler');
_spBodyOnLoadFunctionNames.push('doFilter');

 

i would also report this as an issue, in hope the original project will include this fix

Jul 20, 2012 at 9:26 PM
Edited Jul 20, 2012 at 9:26 PM

@myro Your code too gives me an error with "'selectedIndex' is null or not an object" with your 

  var childValue = CascadingDropdowns[0].childLookup.Object.options[CascadingDropdowns[0].childLookup.Object.options.selectedIndex].text;

This happens on new items and edited items.

Do you have any ideas on why this would be?

Aug 12, 2013 at 6:45 PM
Incidentally, I modified the code to handle this specific issue and the issues reported with the fixes above. This is working for me:

First off, modify the FilterChooicesForMyChild method to allow for a custom callback as shown below:
function FilterChooicesForMyChild(triggerObject, callback) {
    if(!setupComplete) return; //security in IE not to trigger filter on load
    for(i = 0; i < CascadingDropdowns.length; i++) {
        if(CascadingDropdowns[i].parentLookup.Object == triggerObject || CascadingDropdowns[i].parentLookup.Opthid == triggerObject) {
            var CascadingDropdown = CascadingDropdowns[i];
            var wssSvc = new WssSvcCall();
            wssSvc.soapQuery = getQuery2Run(CascadingDropdown);
            wssSvc.url = wssSvcUrl;
            wssSvc.returnFunctionName = function() { 
                filterChildLookup(CascadingDropdown); 
                if(callback != null)callback();
            }
            wssSvc.Submit();
        }
    }
}
Then allow for the possibility that the child drop down may not have a value selected as shown below. This also allows for the possibility that the child Object may not actually be a drop down (SharePoint sometimes handles this as a hidden field with JavaScript rendered drop downs)

function doFilter() {
    // first let get the childs value that needs to be re-set
    var childValue = null;

    if (CascadingDropdowns[0].childLookup.isDropDown) {
        var childSelectedIndex = CascadingDropdowns[0].childLookup.Object.options.selectedIndex
        if (childSelectedIndex) childValue = CascadingDropdowns[0].childLookup.Object.options[childSelectedIndex].text;
    }
    else
        childValue = CascadingDropdowns[0].childLookup.Object.value;

    //now let's apply the filter
    for (j = 0; j < CascadingDropdowns.length; j++) {
        FilterChooicesForMyChild(CascadingDropdowns[j].parentLookup.Object, function () {
            if (childValue) setChildValue(childValue);
        });
    }
}
function setChildValue(childValue) {
    if (CascadingDropdowns[0].childLookup.isDropDown) {
        //get the childs dropdown options
        var childOptions = CascadingDropdowns[0].childLookup.Object.options;

        //let cycle the dropdown's items to find our childValue
        var isfound = false;
        for (i = 0; i < childOptions.length; i++) {
            if (childOptions[i].text == childValue) {
                //alert(childOptions[i].text + ' ==' + childValue);
                CascadingDropdowns[0].childLookup.Object.selectedIndex = i;
                isfound = true;
                break;
            }
            else {
                //alert(childOptions[i].text + ' !=' + childValue);
            }
        }
        // let's see if we found it..
        if (isfound == false) {
            CascadingDropdowns[0].childLookup.Object.selectedIndex = 0;
        }
    }
    else {
        CascadingDropdowns[0].childLookup.Object.value = childValue;
    }
}



//Start the party after the DOM is loaded
_spBodyOnLoadFunctionNames.push('addHandler');
_spBodyOnLoadFunctionNames.push('doFilter');
Hope this helps!