Skip to content
ChrisDunk edited this page Jul 15, 2014 · 6 revisions

Select2 dependent selects with Coldfusion.

I have managed to get dependent selects working with ColdFusion CFC with the following code. I don’t think it is perfect but it is working. I have taken parts of this code from other posts, lots of other posts, so I am not claiming it all as my own:

Example CFC function to get location by area, you will also need the other functions to get the values for other dropdowns

`<cffunction name="getLocationsArray" access="remote" output="no">

    <cfargument name="id_area" type="string" required="true">
    <!--- this can be sent to get a single location when using ajax --->
    <cfargument name="id_location" type="string" required="false" default="0">
    <!--- this can be sent to search/filter results when using ajax --->
    <cfargument name="search_term" type="string" required="false" default="">
    <!--- specify the return_format --->
    <cfargument name="return_format" type="string" required="false" default="">
    
    <cfif not isValid("integer", arguments.id_area)>
        <cfset arguments.id_area = 0>
    </cfif>

<!--- Get data --->
<cfquery name="getLocationsArrayRet" datasource="semseo">
SELECT
l.id_location, l.location
FROM
locations l
WHERE
<cfif arguments.id_area GT 0>
    l.id_area = <cfqueryparam cfsqltype="cf_sql_integer" maxlength="15" value="#arguments.id_area#" />
<cfelse>
    l.id_location = <cfqueryparam cfsqltype="cf_sql_integer" maxlength="15" value="#arguments.id_location#" />
</cfif>
   
<!--- search for text when using ajax --->
<cfif arguments.search_term NEQ "">
    AND MATCH(l.location )
    AGAINST(<cfqueryparam cfsqltype="cf_sql_varchar" maxlength="50" value="*#trim(arguments.search_term)#*"> IN BOOLEAN MODE)
</cfif>
        
<!--- to get a blank row in the query and the cfselect--->
UNION
SELECT 0, ' ...'

ORDER BY location

</cfquery>


<!---
    Format the data :
Select2 format is done here rather than on every page where required.
Also have the option of sending back data as an array if other plugins are used.
--->
<cfif arguments.return_format EQ "select2">
    <cfset var result = structNew()>
    <cfset var locations = arrayNew(1)>
    <cfset var elem = "">
    
    <cfloop query="getLocationsArrayRet" startRow="1" endRow="#getLocationsArrayRet.RecordCount#">
	<cfset elem = structNew()>
            <cfset elem["id"] = getLocationsArrayRet.id_location>
            <cfset elem["text"] = getLocationsArrayRet.location>
            <cfset arrayAppend(locations, elem)>
    </cfloop>

        <!--- package the results into a structure --->
        <cfset result["total"] = getLocationsArrayRet.recordCount>
        <cfset result["locations"] = locations>
        
        <cfset getLocationsArrayRet = result>
    
    <cfelseif arguments.return_format EQ "array">
    
    	<cfset var result=ArrayNew(1)>
    	<!--- Convert results to array --->
        <cfloop index="i" from="1" to="#getLocationsArrayRet.RecordCount#">
            <cfset result[i][1]=getLocationsArrayRet.id_location[i]>
            <cfset result[i][2]=jsStringFormat(getLocationsArrayRet.location[i])>
        </cfloop>
        <cfset getLocationsArrayRet = result>
    
    </cfif>


    <!--- And return it --->
    <cfreturn getLocationsArrayRet>
</cffunction>
`

Add the Select2 files: <link href="/jQuery/select2/select2.css" rel="stylesheet"/> <script type="text/javascript" src="/jQuery/select2/select2.min.js"></script>

This is in the $(document).ready(function(){

`// run this on page load to create the select boxes
$(function () {
    // Place names dropdowns
    $('select#cSearch_id_country').select2({minimumResultsForSearch: 20}).change();
    $("select#cSearch_id_estate, select#cSearch_id_area, select#cSearch_id_location ").select2();
});


$('select#cSearch_id_country').change(function() {
var id_country = $('select#cSearch_id_country').val();
if( id_country > 0 ){
		$.ajax({
		type: 'POST',
		url: "/cfc/placeNames.cfc",
		dataType: 'json',
		data: {
			method: "getEstatesArray",
			returnFormat: "json",
			return_format: "select2",
			id_country: id_country
		},
		success: function(result){/*no action on success, its done in the next part*/}
	}).done(function(result){               `
		var list_html = '';
		var selected_var = '<cfoutput>#SESSION.cSearch_id_estate#</cfoutput>';
		$.each(result.estates, function(i, item) {
			list_html += '<option value='+result.estates[i].id+'>'+result.estates[i].text+'</option>';
		});
		$('select#cSearch_id_estate').html(list_html);//replace <select2 with new options
		if ( selected_var > 0 ){// set selected value
			$('select#cSearch_id_estate').select2().select2('val',selected_var );
		}
		$('select#cSearch_id_estate').select2().select2({minimumResultsForSearch: 20});
		$('select#cSearch_id_estate').trigger("change");// this will run $('select#cSearch_id_estate').change(function() and populate list with selected value.
	})// END done
	} else {
		$('select#cSearch_id_estate').trigger("change");
	}
	
});

    
$('select#cSearch_id_estate').change(function() {
	var id_estate = $('select#cSearch_id_estate').val();
	$("select#cSearch_id_area").select2("val", 0);// clear current selection
	$('select#cSearch_id_area').html('');// clear any current list
	if( id_estate > 0 ){
		$.ajax({
		type: 'POST',
		url: "/cfc/placeNames.cfc",
		dataType: 'json',
		data: {
			method: "getAreasArray",
			returnFormat: "json",
			return_format: "select2",
			CRM_only: true,
			recOwner: <cfoutput>#REQUEST.recOwner#</cfoutput>,
			id_estate: id_estate
		},
		success: function(result){/*no action on success, its done in the next part*/}
		}).done(function(result){
			// TypeError: a is undefined = there is an error in the CFC or the returned data format
			var list_html = '';
			var selected_var = '<cfoutput>#SESSION.cSearch_id_area#</cfoutput>';
			$.each(result.areas, function(i, item) {
				list_html += '<option value='+result.areas[i].id+'>'+result.areas[i].text+'</option>';
			});
			$('select#cSearch_id_area').html(list_html);//replace <select2 with new options
			if ( selected_var > 0 ){// set selected value
				`$('select#cSearch_id_area').select2().select2('val',selected_var);
			}
			$('select#cSearch_id_area').trigger("change");
		})// END done
	} else {
		$('select#cSearch_id_area').trigger("change");
	}
});// END ajax

$('select#cSearch_id_area').change(function() {
	var id_area = $('select#cSearch_id_area').val();
	$("select#cSearch_id_location").select2().select2("val", "");
	$('select#cSearch_id_location').html('');
	if( id_area > 0 ){
		$.ajax({
		type: 'POST',
		url: "/cfc/placeNames.cfc",
		dataType: 'json',
		data: {
			method: "getLocationsArray",
			returnFormat: "json",
			return_format: "select2",
			anotherVar: "my var"
			id_area: id_area
		},
		success: function(result){/*no action on success, its done in the next part*/}
		}).done(function(result){
			var list_html = '';
			var selected_var = '<cfoutput>#SESSION.cSearch_id_location#</cfoutput>';
			$.each(result.locations, function(i, item) {
				list_html += '<option value='+result.locations[i].id+'>'+result.locations[i].text+'</option>';
			});
			$('select#cSearch_id_location').html(list_html);//replace <select2 with new options
			if ( selected_var > 0 ){// set selected value
				$('select#cSearch_id_location').select2().select2('val',selected_var);
			}
		})
	}
});
'

These are the form select boxes:

'<select name="cSearch_id_country" class="dropdown" id="cSearch_id_country">
    
<option value="0" 
<cfif SESSION.cSearch_id_country EQ 0 OR SESSION.cSearch_id_country EQ "">selected="selected"</cfif>>...</option>

    <cfoutput query="countries”>
        <option value="#countries .id_country#"
        	<cfif SESSION.cSearch_id_country EQ countries.id_country>selected="selected"</cfif>># countries .country#
        </option>
    </cfoutput>
    
</select>

<select name="cSearch_id_estate" class="dropdown" id="cSearch_id_estate">
<option value="0" >...</option>
</select>

<select name="cSearch_id_area" class="dropdown" id="cSearch_id_area">
<option value="0" >...</option>
</select>

<select name="cSearch_id_location" class="dropdown" id="cSearch_id_location">
<option value="0" >...</option>
</select>

Ajax: need to use this on the form:

    '<input type="hidden" 
 name="cSearch_id_estate" 
 id="cSearch_id_estate" 
 value="<cfoutput>#SESSION.cSearch_id_estate#</cfoutput>" />'

jQuery: There is an slight issue with this code... you must make sure $('#cSearch_id_country').val() is getting the selected or changed value from that dropdown. Maybe someone can post an update.

 '$('#cSearch_id_estate').select2({

ajax: {
	url: "/cfc/placeNames.cfc?method=getEstatesArray&returnFormat=json&return_format=select2&CRM_only=true&recOwner=<cfoutput>#REQUEST.recOwner#</cfoutput>&id_country=" + $('#cSearch_id_country').val(),
	dataType: 'json',
	quietMillis: 1000,
	data: function (term) {//search term 
		return {search_term: term};
	},
	results: function (result) {return { results: result.estates };}// END results
},// END ajax
initSelection: function(element, callback) {
	var id = $(element).val();// this is the current value of the select list, maybe set from a SESSION
	//alert(id);
	if (id!=="") {
		 $.ajax("/cfc/placeNames.cfc", {
			data: {
				method: "getEstatesArray",
				returnFormat: "json",
				return_format: "select2",
				CRM_only: true,
				recOwner: <cfoutput>#REQUEST.recOwner#</cfoutput>,
				id_estate: id
			},
			dataType: "json"
		}).done(function(result){callback( result.estates[0] );});
	}
}
});'
Clone this wiki locally