Matt Dexter
Matt Dexter

Reputation: 248

Including an AJAX-retrieved select input in an HTML form with ColdFusion

I have AJAX that loads a drop-down menu of teams within a selected department, and then another with agents within that selected team. I'd like to be able to submit the form and use the agent selected in the last dropdown (#form.selectAgent#) to set a variable (#empHistoryRACF#) & run a query. I am able to see both of the dropdowns with AJAX-queried content as I fill out the form, but their values are not being submitted on post, although the submit button (non-AJAXed) is. Oddly, there is another section of my app that does the same thing with the same type of code, and it works fine. I tried commenting that section of the app out, but form.selectAgent is still not defined. I'm using ColdFusion 10 and the following code.

The HTML form:

<form action="index.cfm" method="post" name="empHist">
<td colspan="5">
    <h2>Employee History (#empHistoryRACF#)</h2>
</td>
<td colspan="2" style="text-align: center;">
    <select name="employeeHistory" id="empHist" onchange="getTeamsHist(this.value)">
        <option value=""></option>
        <cfset length = structCount(deptStruct)>
        <cfloop from="1" to="#length#" index="i">
            <option value="#deptStruct[i]['DEPT_NAME']#">#deptStruct[i]['DEPT_NAME']#</option>
        </cfloop>
    </select>
</td>
<td style="text-align: center;">
    <div id="getTeamsHist"></div>
</td>
<td style="text-align: center;">
    <div id="getAgentsHist"></div>
</td>
<td style="text-align: right;">
    <input type="submit" name="submitHist" value="View Employee">
</td>           
</form>

The AJAX for getTeamsHist and getAgentsHist:

function getTeamsHist(str) {
    var xmlhttp;

    if (str == "") {
        document.getElementById("getTeamsHist").innerHTML = "";
        return;
    }

    if (window.XMLHttpRequest) {
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    } else {// code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState==4 && xmlhttp.status==200) {
            document.getElementById("getTeamsHist").innerHTML = xmlhttp.responseText;
        }
    }

    xmlhttp.open("GET","ajax/get_teams_hist.cfm?ajaxDept=" + str, true);
    xmlhttp.send();
}

function getAgentsHist(str) {
    var xmlhttp;

    if (str == "") {
        document.getElementById("getAgentsHist").innerHTML = "";
        return;
    }

    if (window.XMLHttpRequest) {
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    } else {// code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState==4 && xmlhttp.status==200) {
            document.getElementById("getAgentsHist").innerHTML = xmlhttp.responseText;
        }
    }

    xmlhttp.open("GET","ajax/get_agents_hist.cfm?ajaxTeam=" + str, true);
    xmlhttp.send();
}

Here is get_teams_hist.cfm:

<cfoutput>
<cfloop query="agentQuery">
    <cfloop list="#agentQuery.columnList#" index="col">
        <cfset agentStruct[currentRow]['#col#'] = evaluate(#col#)>
    </cfloop>
</cfloop>

<select name="selectAgent" id="selectAgent">
    <option value=""></option>
    <cfset length = structCount(agentStruct)>
    <cfloop from="1" to="#length#" index="i">
        <option value="#agentStruct[i]['AGENT_UID']#">#agentStruct[i]['AGENT_UID']#</option>
    </cfloop>
</select>
</cfoutput>

And here's get_agents_hist.cfm:

<cfoutput>
<cfloop query="teamQuery">
    <cfloop list="#teamQuery.columnList#" index="col">
        <cfset teamStruct[currentRow]['#col#'] = evaluate(#col#)>
    </cfloop>
</cfloop>

<select name="selectTeam" id="selectTeam" onchange="getAgentsHist(this.value)">
    <option value=""></option>
    <cfset length = structCount(teamStruct)>
    <cfloop from="1" to="#length#" index="i">
        <option value="#teamStruct[i]['AGENT_TEAM']#">#teamStruct[i]['AGENT_TEAM']#</option>
    </cfloop>
</select>
</cfoutput>

And this is how I'm trying to use the content from the second select - it's showing that selectAgent is undefined. It is also not showing if I do cfdump var="#form#".

<cfif isDefined('form.submitHist')>
    <cfset empHistoryRACF = form.selectAgent>
<cfelse>
    <cfset empHistoryRACF = "">
</cfif>

Upvotes: 1

Views: 525

Answers (1)

Abram
Abram

Reputation: 804

First, the <form> tag isn't properly nested in the HTML document (shouldn't be between <tr> and <td>). This can sometimes cause problems - especially when working with AJAX loaded form elements and even more especially when accidentally looking at it in IE. Try moving your <form> outside of the <table> and see if the fields post.

Also, your get_agents_hist.cfm and get_agents_hist.cfm files seem to be converting a query to a struct just to loop over that struct and create <options>. This is way too much work. You should just use something like:

<select name="selectTeam" id="selectTeam" onchange="getAgentsHist(this.value)">
   <option value=""></option>
    <cfoutput query="teamQuery">
      <option value="#teamQuery.AGENT_TEAM#">#teamQuery.AGENT_TEAM#</option>
   </cfoutput>
</select>

As a side note, in almost all cases you don't need to use evaluate() in CFML. If you find yourself thinking you need it, chances are there is a better way to solve the problem.

Finally, you should probably change the ID's of the "getTeamsHist" and "getAgentsHist" divs as they may collide with the globally scoped JS functions of the same name.

Upvotes: 3

Related Questions