I am new to using cfajaxproxy, I am trying to have select a number of check boxes then loop through all of the checked checkboxes and save the results in a database using cfajaxproxy and jQuery.
The markup is generated by looping through a query but here is a sample of an area that is giving me problems:
<span id="1569_2627_text">I certify that the employee has been trained in the use of the following
equipment (please check all that apply):</span><br />
<input type="hidden" name="2627_max_length" id="2627_max_length" value="">
<input type="hidden" name="2627_min_value" id="2627_min_value" value="">
<input type="hidden" name="2627_max_value" id="2627_max_value" value="">
<input type="hidden" name="2627_regex_format" id="2627_regex_format" value="">
<input type="hidden" name="2627_system_type" id="2627_system_type" value="">
<input type="hidden" name="2627_app_type_version" id="2627_app_type_version" value="1569">
<input type="hidden" name="2627_question_type" id="2627_question_type" value="CM">
<label>
<input class="questionChoice" type="checkbox" name="2627"
value="8509" data-app_type_version="1569">
<span>Face Shield<span>
</label><br />
<label>
<input class="questionChoice" type="checkbox" name="2627"
value="8510" data-app_type_version="1569">
<span>Neoprene Gloves<span>
</label><br />
<label>
<input class="questionChoice" type="checkbox" name="2627"
value="8511" data-app_type_version="1569">
<span>Apron<span>
</label><br />
<label>
<input class="questionChoice" type="checkbox" name="2627"
value="8512" data-app_type_version="1569">
<span>Boots<span>
</label><br />
<label>
<input class="questionChoice" type="checkbox" name="2627"
value="8513" data-app_type_version="1569">
<span>Wizard Glove<span>
</label><br />
<label>
<input class="questionChoice" type="checkbox" name="2627"
value="8514" data-app_type_version="1569">
<span>Insulated Mitt<span>
</label><br />
<label>
<input class="questionChoice" type="checkbox" name="2627"
value="8515" data-app_type_version="1569">
<span>Insulated Glove<span>
</label><br />
<button class="add_answer" value="2627" data-app_type_version="1569" disabled>Add answer</button>
Here is my cfajax proxy tag:
<cfajaxproxy cfc="#APPLICATION.cfMapping#.Agency.Agency"
jsclassname="agency_object">
Here is the function it should run on each checked box:
function saveResponses(question_no, answerValue){
var myagOBJ = new agency_object();
myagOBJ.setHTTPMethod('POST');
myagOBJ.setCallbackHandler(function(result) {
numOfCalls++;
alert(result+ ", call number: "+ numOfCalls);
});
myagOBJ.setErrorHandler(null);
myagOBJ.store_prepopulated_response(
agency_id = #SESSION.agency_object.get_id()#,
jQuery("select##site").val(),
question_no,
answerValue
);
}
And here is the jQuery code that loops through each checked box:
$("div##" + div + " [name=" + question_no + "]:checked").each(function() {
answerText = $(this).next().text();
answerValue = $(this).val();
identifier = question_no + "_" + answerValue;
if(answers["q_" + identifier] === undefined) {
formAppend();
answers["q_" + identifier] = answerValue;
alert("From Checkbox");
saveResponses(question_no, answerValue);
$("div##saved_answers table").append(
"<tr id=\"" + identifier + "\"><td><strong>" + formName +
"</strong><br>" + questionText + "</td><td>" + answerText +
"<br><button data-app_type_version=\"" + div +
"\"class=\"remove\" value=\"" + identifier +
"\">Remove</button></td></tr>"
);
}
});
The method of the cfc that it is calling is:
<cffunction name="store_prepopulated_response" access="remote" returntype="string" verifyclient="true">
<cfargument name="agency_id" type="numeric" required="true">
<cfargument name="site_id" type="numeric" required="true">
<cfargument name="question_no" type="numeric" required="true">
<cfargument name="response" type="string" required="true">
<cfreturn "Agency id: #agency_id#, Site ID: #site_id#, Question No: #question_no#, Resonse: #response#">
</cffunction>
I am still just testing things to make sure it works hence a lot of the functions are actually doing anything except returning test results.
When I run this code it is calling the cfc just fine and returning the results however it is calling it way too many times.
For instance if I check three boxes it will call the cfc method 7 times, if I check two boxes it will call the cfc method 5 times. I check all 7 boxes the cfc method gets called 19 times.
My first thought is maybe the cfc is being called the correct amount of times however the callbackhandler is getting called to much because each instance is going to call its response handler when a result gets returned, so I created a global instance of the agency_object and just calling the method every time however I got the same results.
Does anybody know why this might happen?
*(Edit) I just added a count to the actual cfc with a call count as well and it actually is calling the cfc method too many times.
"Because the callbackhandler doesn't know which specific response it should handle all of them handle all responses"
That's how callback handlers work. They should handle all of the responses. The problem is that you're creating multiple callback handlers that all do the same thing; and each response is sent to each handler.
By setting the handler from within your saveResponses
function using a JavaScript anonymous function (passing function(){...}
as a method argument) you are appending additional callback handlers for that class. That might make sense if you were creating and destroying the object for every request, but as was discussed in the comments of your post, you're better off creating one instance. With that approach you should set the callback handler outside of this function as well.
To illustrate what's happening, let's look at what happens when you check 3 boxes and run saveResponses
:
saveResponses(...){
//...
myagOBJ.setCallbackHandler(function(result) {
numOfCalls++;
alert(result+ ", call number: "+ numOfCalls);
});
//...
}
The appending of handlers explains 3 checkboxes -> 7 calls.
saveResponse
is called multiple times because of the .each()
method; it loops over each item returned by the jQuery selector in rapid succession, running your each-handler function once for each.
That only adds up to 6 calls, so something is still not right, but you can see how this would quickly become a huge problem. The 7th probably comes in because of the asynchronous nature of the ajax requests. What's really happening is probably more like:
saveResponses
called
saveResponses
called
saveResponses
called
Lesson: Declare/assign the handler outside of the caller (near where the class is instantiated makes the most sense).
If you really want to learn about JavaScript -- and you should -- pick up a copy of JavaScript: The Good Parts. It's very short, but extremely well written and makes complex concepts easier to understand. Some of it may not make much sense at your current skill level, but focus on what's within reach at first (e.g. anonymous functions) and then after you really grok those, move on to the harder things like modules.