Two jQuery Ajax Calls in a coldfusion page - ajax

I am new to jQuery API documentation and hence wondering if the following scenario is possible:
So far, I have come across only one Ajax call in one coldfusion page.
Scenario:
I am sending a $.ajax call to a cfc to call a method in a CFC and returning the data back in JSON format. Basically the method I am calling here will be adding the data into the database.
I want to write another $.ajax call to call a method in a CFC, which will read the data which is saved by the above ajax call and display in JSON format on the Web Browser.
So, my questions is, can I go for multiple ajax call in a single coldfusion page as long as Iam doing this in sequential manner?
Sequential order must be the key, am I right?
Please clarify !!
Thanks

There's two ways to go about it really...
A jQuery AJAX call has a callback function to it, so you could simply get some JSON back from the initial submission and from that callback fire off the second request - that way you can be sure the first action has completed before you call the second.
var request = {
returnformat : 'json',
queryformat : 'column',
method: 'save_data',
data: /* data to pass to the save action here */
}
$.getJSON("path/to/your/service.cfc", request, function(response) {
var request = {
returnformat : 'json',
queryformat : 'column',
method: 'get_data'
}
$.getJSON("path/to/your/service.cfc", request, function(response) {
/* code to fire on response */
});
});
However I think a better way would be to make a single AJAX call and simply do both the submission save and the data response in one CFC method. Your CFC might look something like this:
<cffunction name="save_response" access="remote" output="false">
<cfset response = structNew()>
<cfset response.status = true>
<cftry>
<cfquery datasource="#datasource#">
INSERT...
</cfquery>
<cfquery datasource="#datasource#" name="get_data">
SELECT...
</cfquery>
<cfset response.data = get_data>
<cfcatch type="any">
<cfset response.status = false>
</cfcatch>
</cftry>
<cfreturn response>
</cffunction>

Related

CFML How to get status code from an ajax response

I am almost done making a web app with CFML but I have a question on handling errors. For example, a part of my web app can execute user entered SQL code. However if the SQL code the user provides isn't valid then it will not execute properly and I get an error like this:
https://devintranet.dep.gov/oogns/sharedComponents.cfc 500
Which makes sense. If it helps answering my question at all here is the information on the network tab:
All I want is to be able to catch when the status code returns 500 and be able to take action based on that. For example if I make a request that ends up having a status code of 500 then I can use JS alert to tell the user something went wrong.
Here is the function in sharedComponents.cfc:
<cffunction name="LoadAttribute" access="remote" returnformat="plain" returntype="string" >
<cftry>
<cfquery name ="AttributeQuery" datasource="RBDMS_UPDATE">
SELECT *
FROM dbo.OOGNS_Queries
WHERE UPPER(QueryName) = UPPER(<cfqueryparam cfsqltype="varchar" value="#form.default_ProfileName#" />)
</cfquery>
<cfcatch>
<cfoutput>
#cfcatch.Detail#<br />
#cfcatch.Message#<br />
#cfcatch.tagcontext[1].line#:#cfcatch.tagcontext[1].template#
</cfoutput>
</cfcatch>
</cftry>
<cfreturn AttributeQuery["#default_ColName#"][1] />
</cffunction>
And here is the ajax function that calls it:
$.ajax({
type: "POST",
url: "sharedComponents.cfc",
data: { method: "LoadAttribute",
default_ProfileName: ProfileName,
default_Entity: Entity,
default_ColName: ColName,
},
datatype: "json"
}).done(function(returnresult) {
There is actually a lot of code after that but I believe it to be irrelavent to what I'm trying to do. Literally if you can show me how to obtain the status code from the response header I think I'll be good.
There are two separate issues in your request.
Catch errors on server side
It can be that the requested column is not available in the AttributeQuery result. So you have to check for that before accessing it.
One way to do this is:
<cfreturn structKeyExists(AttributeQuery, default_ColName) ?
AttributeQuery[default_ColName] : "" />
Catch errors on client side
To catch HTTP errors you can use the error() function jQuery's ajax() function provides, as Miguel-F and AndreasRu mention in their comments.

dynamicly fill table using zpt and ajax as update

I'm creating a webproject in pyramid where I'd like to update a table every few secondes. I already decided to use ajax, but I'm stuck on something.
On the client side I'm using the following code:
function update()
{
var variable = 'variable ';
$.ajax({
type: "POST",
url: "/diagnose_voorstel_get_data/${DosierID}",
dataType: "text",
data: variable ,
success: function (msg) {
alert(JSON.stringify(msg));
},
error: function(){
alert(msg + 'error');
}
});
}
Pyramid side:
#view_config(route_name='diagnose_voorstel_get_data', xhr=True, renderer='string')
def diagnose_voorstel_get_data(request):
dosierid = request.matchdict['dosierid']
dosieridsplit = dosierid.split
Diagnoses = DBSession.query(Diagnose).filter(and_(Diagnose.code_arg == str(dosieridsplit[0]), Diagnose.year_registr == str(dosieridsplit[1]), Diagnose.period_registr == str(dosieridsplit[2]), Diagnose.staynum == str(dosieridsplit[3]), Diagnose.order_spec == str(dosieridsplit[4])))
return {'Diagnoses ' : Diagnoses }
Now I want to put this data inside a table with zpt using the tal:repeat statement.
I know how to use put this data in the table when the page loads, but I don't know how to combine this with ajax.
Can anny1 help me with this problem ? thanks in adance.
You can do just about anything with AJAX, what do you mean "there's no possibility"? Things become much cleaner once you clearly see what runs where and in what order - as Martijn Pieters points out, there's no ZPT in the browser and there's no AJAX on the server, so the title of the question does not make much sense.
Some of the options are:
clent sends an AJAX request, server does its server-side stuff, in the AJAX call success handler the client reloads the whole page using something like window.location.search='ts=' + some_timestamp_to_invalidate_cache. The whole page will reload with the new data - although it works almost exactly like a normal form submit, not much sense using AJAX like this at all.
client sends an AJAX request, server returns an HTML fragment rendered with ZPT which client then appends to some element on your page in the AJAX success handler:
function update()
{
var variable = 'variable ';
$.post("/diagnose_voorstel_get_data/${DosierID}")
.done(function (data) {'
$('#mytable tbody').append(data);
});
}
client sends an AJAX request, server returns a JSON object which you then render on the client using one of the client-side templating engines. This probably only make sense if you render your whole application on the client and the server provides all data as JSON.

ReturnFormat row when POSTing CFAJAX request

I'm struggling with the setQueryFormat() call to an AJAX-function in CF9. I have CFM-File that looks like so:
<div id="div1" onclick="callfkt1('POST');" style="cursor:pointer;">POST</div>
<div id="div2" onclick="callfkt1('GET');" style="cursor:pointer;">GET</div>
<script type="text/javascript">
function callfkt1(sHTTPMethod) {
var oTester001=new CTester001();
oTester001.setCallbackHandler(function(result) {
alert(JSON.stringify(result));
});
oTester001.setErrorHandler(function(err, msg) {
alert(err + ': ' + msg);
});
oTester001.setHTTPMethod(sHTTPMethod);
oTester001.setQueryFormat('column');
oTester001.fkt1();
}
</script>
Tester001.cfc contains the following:
<cfcomponent >
<cffunction name="fkt1" returntype="query" access="remote">
<cfquery name="local.queries.qry1" datasource="brdwr">
SELECT url_id, url
FROM urls
</cfquery>
<cfreturn local.queries.qry1>
</cffunction>
</cfcomponent>
When I call the JavaScript function With parameter 'GET' the result is returned in query format 'column' which means it contains a ROWCOUNT member that stores the number of records returned from the query. Using request method 'POST' the recordset is returned in format 'row' without ROWCOUNT member. Have you experienced this? Do you limit to GETing CFAJAX request?
Best.
You might try changing your CFC so that you explicitly declare how you want the JSON returned by using the serilizeJson function:
http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=Tags_a-b_3.html
As the second argument of the function, you can set serializeQueryByColumns to True, so that it will serialize the data as a WDDX query format, which is what the setQueryFormat("column") is supposed to do.
While not an answer, do know that when the row format is used, you still get the same data. It's in a different format, but you still get all the data. You just have to work with it differently.

calling a coldfusion function from another function via ajax rendering an error

Here's the deal: I am sending an ajax request to a coldfusion function, which then calls another function inside the same component. Here are the two functions:
<!--- test--->
<cffunction name="deleteMission" access="public" output="No" returntype="struct">
<cfscript>
var returnData = structNew();
structAppend(returnData, getTest());
returnData.test2 = "test2";
</cfscript>
<cfreturn returnData>
</cffunction>
<!--- test2 --->
<cffunction name="getTest" access="public" output="No" returntype="struct">
<cfscript>
var returnData = structNew();
returnData.testing = "TEST";
</cfscript>
<cfreturn returnData>
</cffunction>
Very simple, just returning 2 struct keys in this example. If I call the method test() regularly (ie, on page load via coldfusion), I get the expected results. However, if I call the method test() via AJAX, I receive the error "Variable getTest is undefined." If I remove the call to getTest(), I receive the single struct key back as expected. Anyone have any idea what is going on? I have a feeling it's something simple I've overlooked, but I need some more eyeballs on it at this point... I'm really scratching my head on this one. Thanks!
If you're accessing the component via AJAX, then the access attribute of your cffunction should be set to remote. E.g.
<cffunction name="deleteMission" access="remote" output="No" returntype="struct">
Change your getTest to access="private".
Also, Sometimes the StructAppend method does not take in parameters as "function call". So get the value into a variable first and then send that variable to deleteMission.
something like this...
var inpData = getTest();
structAppend(returnData, inpData);

How do I pass an onclick argument to a CFC to update the database through AJAX?

New to Ajax. Just trying to do a simple ajax/cfc vote yes/no app. Can’t get it to work
What I am trying to accomplish is a simple Vote "Yes or No" app where it shows the number of votes cast next to each link. For example:
Yes (882 votes)
No (163 votes).
When a visitor votes, the database should be updated with the vote and record the voter in a different table (so they can't vote again). Finally, a confirmation message is displayed with the new vote count:
You voted "Yes" (883 votes) or
You voted No (164 votes)
Now I had everything working but updating the database. I tried reworking the JavaScript (AJAX) to call a CFC by adding ($.ajax) and moving the response messages within the ajax part. However, now it’s not working at all. What did I do wrong?
Below is the new code I came up with. To keep this question simple, I am just showing the "No" Vote portion. Am I on the right track? This seem like it would be very simple.
Voting link
<A HREF="javascript:()" onclick="VoteNoID('#IdeaID#');">
<SPAN ID="VoteNoMessage">No</SPAN>
</A>
- <SPAN ID="NewNoCount">#NoCount#</SPAN>
Ajax
<script LANGUAGE="JavaScript">
function VoteNoID()
{
var VoteNoDescription = document.getElementById("VoteNoDescription").style.display='none';
$.ajax({
type: "POST",
url: "../CFC/VoteNo.cfc?method=VoteNoID",
data: recordata,
dataType: "html",
success: function(message) {
$('#VoteNoMessage').html("you voted No");
$('#NewNoCount').html("#NewCount#");
}
});
});
} `
<script>
VoteNo.cfc
<cffunction name="NoVote" access="remote" returntype="string"
<cfargument name="VoteNo" type="string" required="yes">
<CFQUERY NAME="NoCountCK" DATASOURCE="MyDSN">
SELECT *
FROM Ideas
WHERE IdeaID = #arguments.VoteNo#
</CFQUERY>
<CFSET NewCount=#NoCountCK.NoCount#+1>
<CFQUERY NAME="UpdateNoCount" DATASOURCE="MyDSN">
UPDATE Ideas
SET NoCount = #NewCount#
WHERE IdeaID = #arguments.VoteNo#
</CFQUERY>
<CFQUERY NAME="MemberVote" DATASOURCE="MyDSN">
INSERT INTO MemberVoteRecord(IdeaID,MemberID,DatePosted,YesNo)
VALUES(#arguments.VoteNo#,#COOKIE.Member_ID#,#NOW()#,N)
</CFQUERY>
<cfreturn NewCount>
</cffunction>
The success part of our .ajax() call is just setting the html to be the variable #newcount#. I'm not sure where that variable is being set initially, but if you would look at your raw html generated, you will see that the raw html contains a static number here. You need to set this as a javascript variable, not a ColdFusion variable.
So, try setting this variable to be message, which is the argument passed to your success call back. Message should be equal to whatever your CFC is returning. I.e. if you would call the CFC directly in the browser, this is what your browser would render.
success: function(message) {
$('#VoteNoMessage').html("you voted No");
$('#NewNoCount').html(**message**);
}
Also, you'll want to adjust your CFC function's return format to be "plain". .

Resources