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.
Related
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.
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>
I have a drop down list that list different options to the user. I need the list to populate a text area based on what the user selects. I have the data already in my database and I want to be able to run a query based the user's selection from the drop down list.
This is how my select tag looks like right now:
<select name="procedure" onChange="">
<option value="">Select Procedure</option>
<cfloop query="procedures">
<option value="#procedureId#">#procedureName#</option>
</cfloop>
</select>
And this is my text area:
<textarea name="procedureDescription" cols="80" rows="6">#the query output will go here#</textarea><br />
Is there a way to use onSelectChange function to control a server side query with Ajax?
I hope my thoughts are clear, if you need more info please ask.
Yes, unless I misunderstand, you should be able to do this using an Ajax request. The onchange method should look something like this:
function handleProcedureChange()
{
var selectedVal = $(this).val();
var url; // TODO set procedure URL here, using selectedVal as needed
$.get(url, function(procedureResult) {
$("#procedureDescription").text(procedureResult);
});
}
Then you'd need to set up the server-side method to run the procedure and return the result as plain text.
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);
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". .