Search code examples
jqueryajaxcoldfusioncfccffunction

Using AJAX to get data from a ColdFusion component page, and fill another dropdown with results


I know similar questions have been asked before and answered, but I'm having specific issues with my code. When the dropdown with id="SITE" is changed, I want the dropdown with id="YARD" to fill with yards from that site. Here is my component CFC code (in a page called AjaxFunctions.cfc):

<cfcomponent output="false">
<!---  Get YARDS dataset based on SITE  --->
    <cffunction name="getYards" access="remote" returntype="query" />
    <cfargument name="Site" type="string" required="true" /> 
    <cfquery name="rs_Yards" datasource="abc" username="notReal1" password="notReal2" >
        <!--- SQL code here --->
    </cfquery>
    <cfreturn rs_Yards />
    </cffunction>
 <cfcomponent>

And here is my receiving code in the head section of my calling page:

<script>
    $(document).ready(function() {
        $("#SITE").change(function() {
            alert( "SITE has changed." );// testing to see if jQuery works
            // empty YARD dropdown
            $("#YARD").empty();
            // perform ajax
            $.ajax({
                type: "GET",
                url: "AjaxFunctions.cfc",
                data: {
                    method: "getYards",
                    Site: $("#SITE").val()
                },
                datatype: "json",
                success: function(data) {
                    alert("We received the data."+data);
                    $.each(data, function () {
                        $("#YARD").append($("<option></option>").val(this['ITEMID']).html(this['ITEMDESC']));
                    }                   
                }
            });
        });
    });
</script>

Whey I try the code as is, absolutely nothing happens. When I comment out just these lines

$.each(data, function () {
    $("#YARD").append($("<option></option>").val(this['ITEMID']).html(this['ITEMDESC']));
} 

Then I get the notification "the SITE has changed" and the YARD dropdown empties, but the "We received the data..." alert looks like HTML code from an error page. I guess I can worry about updating the YARD dropdown later, right now I'm worried about just receiving the data from the query.


Solution

  • Big thanks to @Ageax for all his help. I wound up going a much simpler route. Here is my function:

    <cfcomponent output="false">
    <!---  Get YARDS dataset based on SITE  --->
        <cffunction name="getYards" access="remote" returntype="string" returnformat="plain" >
            <cfargument name="Site" type="string" required="true" /> 
            <cfquery name="rs_Yards" datasource="MyDatasource" >
                <!--- SQL code here --->
            </cfquery>
            <cfset myList = ValueList(rs_Yards.Yard)>   <!--- convert query results to list --->
            <cfreturn MyList />
        </cffunction>
    </cfcomponent>
    

    And here is my jQuery on the calling page:

    <!---  jQuery/AJAX to autofill dropdowns  --->
        <script>
        $(document).ready(function() {
            $("#SITE").change(function() {   // when the SITE dropdown changes 
                $("#YARD").empty();          // empty the YARD dropdown 
                $.ajax({
                    type: "GET",
                    url: "AjaxFunctions.cfc",
                    data: {
                        Site: $("#SITE").val(),
                        Method: "getYards"
                        },
                    dataType: "text",
                    success: function(data) {
                        var options = data.split(",");              // convert returned list to array 
                        var select = document.getElementById('YARD');
                        for(var i=0;i<options.length; i++)
                        {
                            var options2 = $.trim(options[i]);      // clean up label portion 
                            $("#YARD").append($("<option></option>").val(options[i]).text(options2));   // append options to YARD dropdown 
                        }
                    }
                });
            });
        });
        </script>
    

    Hope this helps someone else.