Coldfusion inserting db record and downloading file using Ajax - ajax

Im trying to create a button that when clicked inserts a record into the database and then downloads a file. I'm trying to do this via Ajax, the file download works but it isn't inserting the record in the db.
Trigger
<button type="button" class="btn btn-primary" onClick="downloadFile1()">Download</button>
Script
function downloadFile1(){
var file1 = 'https://example.com/files/myfile.zip';
$.ajax({
TYPE: "POST",
URL: "components.cfc?method=DownloadFile1",
data: {fileId : 3},
success: function() {
window.location = file1;
}
});
}
</script>
Components.cfc
<cfcomponent output="false">
<cffunction name="DownloadFile1" access="remote" returntype="string">
<cfcontent type="text/html">
<CFQUERY NAME="i">
INSERT into t_terms
(bid, fildid)
VALUES
(
<cfqueryparam value="#session.busid#" cfsqltype="CF_SQL_INTEGER">,
<cfqueryparam value="#url.fileID#" cfsqltype="CF_SQL_INTEGER">)
</CFQUERY>
</cffunction>
Could someone point out where I am going wrong?

Like Jack said above, since you're doing a POST and not a GET, instead of looking in the URL scope, try looking in the "FORM" scope.
<cfqueryparam value="#form.fileID#" cfsqltype="CF_SQL_INTEGER">
Or, you could just look for "fileID". If it is being passed in, your query will work. If not, it will throw an error.
<cfqueryparam value="#fileID#" cfsqltype="CF_SQL_INTEGER">

Related

AJAX shows different behaviors in an if/elseif-statement which is inside the success function [duplicate]

I have looked through all the similar posts out there but nothing seems to help. This is what I have
HTML:
<section>
<form id="contact-form" action="" method="post">
<fieldset>
<input id="name" name="name" placeholder="Name" type="text" />
<input id="email" name="email" placeholder="Email" type="text" />
<textarea id="comments" name="comments" placeholder="Message"></textarea>
<div class="12u">
Send Message
Clear Form
</div>
<ul id="response"></ul>
</fieldset>
</form>
</section>
JavaScript/jQuery:
function sendForm() {
var name = $('input#name').val();
var email = $('input#email').val();
var comments = $('textarea#comments').val();
var formData = 'name=' + name + '&email=' + email + '&comments=' + comments;
$.ajax({
type: 'post',
url: 'js/sendEmail.php',
data: formData,
success: function(results) {
$('ul#response').html(results);
}
}); // end ajax
}
What I am unable to do is prevent the page refresh when the #form-button-submit is pressed. I tried return false; I tried preventDefault() and every combination including return false; inside the onClick. I also tried using input type="button" and type="submit" instead and same result. I can't solve this and it is driving be nuts. If at all possible I would rather use the hyperlink due to some design things.
I would really appreciate your help on this.
Modify the function like this:
function sendForm(e){
e.preventDefault();
}
And as comment mentions, pass the event:
onclick = sendForm(event);
Update 2:
$('#form-button-submit').on('click', function(e){
e.preventDefault();
var name = $('input#name').val(),
email = $('input#email').val(),
comments = $('textarea#comments').val(),
formData = 'name=' + name + '&email=' + email + '&comments=' + comments;
$.ajax({
type: 'post',
url: 'js/sendEmail.php',
data: formData,
success: function(results) {
$('ul#response').html(results);
}
});
});
function sendForm(){
// all your code
return false;
}
I was also bit engaged in finding solution to this problem, and so far the best working method I found was this-
Try using XHR to send request to any url, instead of $.ajax()...I know it sounds bit weird but try it out!
Example-
<form method="POST" enctype="multipart/form-data" id="test-form">
var testForm = document.getElementById('test-form');
testForm.onsubmit = function(event) {
event.preventDefault();
var request = new XMLHttpRequest();
// POST to any url
request.open('POST', some_url, false);
var formData = new FormData(document.getElementById('test-form'));
request.send(formData);
This would send your data successfully ...without page reload.
Have you tried using
function sendForm(event){
event.preventDefault();
}
Simple and Complete working code
<script>
$(document).ready(function() {
$("#contact-form").submit(function() {
$("#loading").show().fadeIn('slow');
$("#response").hide().fadeOut('slow');
var frm = $('#contact-form');
$.ajax({
type: frm.attr('method'),
url: 'url.php',
data: frm.serialize(),
success: function (data) {
$('#response').html(data);
$("#loading").hide().fadeOut('slow');
$("#response").slideDown();
}, error: function(jqXHR, textStatus, errorThrown){
console.log(" The following error occured: "+ textStatus, errorThrown );
} });
return false;
});
});
</script>
#loading could be an image or something to be shown when the form is processing, to use the code simply create a form with ID contact-form
Another way to avoid the form from being submitted is to place the button outside of the form. I had existing code that was working and created a new page based on the working code and wrote the html like this:
<form id="getPatientsForm">
Enter URL for patient server
<br/><br/>
<input name="forwardToUrl" type="hidden" value="/WEB-INF/jsp/patient/patientList.jsp" />
<input name="patientRootUrl" size="100"></input>
<br/><br/>
<button onclick="javascript:postGetPatientsForm();">Connect to Server</button>
</form>
This form cause the undesirable redirect described above. Changing the html to what is shown below fixed the problem.
<form id="getPatientsForm">
Enter URL for patient server
<br/><br/>
<input name="forwardToUrl" type="hidden" value="/WEB-INF/jsp/patient/patientList.jsp" />
<input name="patientRootUrl" size="100"></input>
<br/><br/>
</form>
<button onclick="javascript:postGetPatientsForm();">Connect to Server</button>
I expect anyone to understand my idea very well as it's a very simple idea.
give your required form itself an id or you can get it by any other way you prefer.
in the form input "submit" call an onclick method from your javascript file.
in this method make a variable refer to your from id the addEventListener on it and make a preventDefault method on "submit" not on "click".
To clarify that see this:
// element refers to the form DOM after you got it in a variable called element for example:
element.addEventListener('submit', (e) => {
e.preventDefault();
// rest of your code goes here
});
The idea in brief is to deal with the form by submit event after dealing with submit button by click event.
Whatever is your needs inside this method, it will work now without refresh :)
Just be sure to deal with ajax in the right way and you will be done.
Of course it will work only with forms.
The way I approached this: I removed the entire form tag and placed all the form elements such as input, textarea tags inside a div and used one button to call a javascript function. Like this:
<div id="myform">
<textarea name="textarea" class="form-control">Hello World</textarea>
<button type="submit" class="btn btn-primary"
onclick="javascript:sendRequest()">Save
changes</button>
<div>
Javascript:
function sendRequest() {
$.ajax({
type: "POST",
url: "/some/url/edit/",
data: {
data: $("#myform textarea").val()
},
success: function (data, status, jqXHR) {
console.log(data);
if (data == 'success') {
$(`#mymodal`).modal('hide');
}
}
});
return true;
}
I thought why use a form when we are sending the actual request using AJAX. This approach may need extra effort to do things like resetting the form elements but it works for me.
Note:
The above answers are more elegant than this but my use case was a little different. My webpage had many forms and I didn't think registering event listeners to every submit button was a good way to go. So, I made each submit button call the sendRequest() function.

Set session variable with select box via Ajax with Coldfusion

I'm trying to set a coldfusion session variable when the value of a select box changes. However I get an error on an alert box saying "Object HTMLSelectElement" and doesnt change the session variable. Any help would be great.
Code:
Form.cfm
<cfset session.item1 = 0>
<cfselect name="item1" class="form-control" id="item1">
<option value="0">0</option>
<option value="10">10</option>
<option value="20">20</option>
<option value="30">30</option>
<option value="40">40</option>
<option value="50">50</option>
</cfselect>
Script
$('#item1').change( function() {
var item1Selected = $('#item1').val();
$.ajax({
url: '\components.cfc?method=getItem1', // You repeated "url:" in your url
data: {item1: item1Selected}, // added missing final comma
success: function(item1Selected) { alert(item1); }
});
});
Components.cfc
<cffunction name="getItem1" access="remote" returntype="any">
<cfargument name="item1" type="any" required="yes">
<cfset session.item1 = #argument.item1#>
<cfreturn />
</cffunction>
Change this:
<cfset session.item1 = #argument.item1#>
to this:
<cfset session.item1 = arguments.item1>
The correct scope is arguments, the plural of argument. Plus, you don't need the pound signs.
Not related to your question, but if you get your CF code to work using CF only, this sort of troubleshooting becomes a lot easier.
(Too long for comments)
In addition to Dan's comments about the error in the CFFunction, two other issues that may prevent the code from behaving as you expect:
Your success() function defines the response variable as item1Selected. By using alert(item1) you are actually displaying the <select> element, not the response from the ajax call.
The cffunction does not actually return anything, ie <cfreturn /> So even if you fix the variable name, the response will be undefined or blank. Returning a response is not required. However, if you did want to return some sort of data to success() you need to modify the function to return something (JSON, etcetera).

How to create a .cfc file using Ajax?

I'm trying to create a ColdFusion component(.cfc) file and use Ajax to pass my query. Am I doing this correctly and can I use Ajax in ColdFusion 7?
Added from edit comment of OP
I have updated this once again and just as I stated above my button click works and my component works but, the call to the component does nothing. Can someone take a look at it one more time to see what the problem could be. I feel like I'm so close. Also, how do I retrieve the returned value?
Added from edit comment of OP
I updated the code but, I'm still not getting anything. Can someone please, please help me understand what I'm missing?
The following is in form.cfm:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
function validateFunding(){
$('#Finalize').click(function(){
$.ajax({
type:"get",
url: "awardTotals.cfc?method=searchAward",
data: {total: $("totals").val(), codeNum: $("CodeNum").val(), testYear: $("TestYear").val, selType: $("selType").val, selJuris: $("selJuris").val},
success: function(data) {
if (isTotals == true) { alert('There is a match');} else { alert('This does not match);}
}
});
});
}
This is my awardTotal.cfc.
<cfcomponent>
<cffunction name="searchAward" access="remote" returntype="any">
<cfargument name="Total" type="numeric" required="true">
<cfargument name="CodeNum" type="string" required="true">
<cfargument name="TestYear" type="numeric" required="true">
<cfargument name="SelType" type="numeric" required="true">
<cfargument name="SelJuris" type="numeric" required="true">
<cfset var searchAwards = "">
<cfquery name="searchAwards" datasource="Test">
SELECT g.Code1 + g.Code2 + g.Code3 + g.Code4 AS GrandTotal
FROM Codes g
WHERE g.CodeNumber = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.CodeNum#">
AND g.TestYear = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.TestYear#">
AND g.SelType = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.SelType#">
AND g.Jurisdiction = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.SelJuris#">
</cfquery>
<cfscript>
if(arguments.Totals = searchAwards.GrandTotal){
return true;
} else {
return false;
}
</cfscript>
</cffunction>
</cfcomponent>
You are passing in grandTotal and your method is looking for awardTotals. you are returning an empty string and looking for a boolean. Try this :
function ValidateFunding(awardTotals){
$.ajax({
url: 'awardTotals.cfc',
data: {method: 'searchAward', awardTotals: numberToPass},
success: function(data) {
if (isTotals == true) { alert('There is a match');} else { alert('This does not match);}
}
});
}
Then
<cfcomponent>
<cffunction name="myFunction" access="public" returntype="Query">
<cfargument name="awardTotals" type="string" required="true">
<cfset var searchAward = queryNew()>
<cfquery name="searchAward" datasource="Test">
SELECT g.Code1 + g.Code2 + g.Code3 + g.Code4 AS GrandTotal
FROM Codes g
WHERE g.CodeNumber = <cfqueryparam cfsqltype="cf_sql_varchar" value="#form.CodeNum#">
AND g.TestYear = <cfqueryparam cfsqltype="cf_sql_varchar" value="#form.TestYear#">
AND g.SelType = <cfqueryparam cfsqltype="cf_sql_varchar" value="#form.SelType#">
AND g.Jurisdiction = <cfqueryparam cfsqltype="cf_sql_varchar" value="#form.SelJuris#">
</cfquery>
<cfscript>
if(arguments.awardTotals eq searchAward.grandTotal){
return true;
} else {
return false;
}
</cffunction>
</cfcomponent>
And #billy Cravens is correct. You can't use cfajaxproxy but jquery ajax will work.
cfajaxproxy was introduced in ColdFusion 8, so it's unavailable on CF7.
However, you can call the CFC in your jQuery ajax() call by appending the method and the parameters to the URL: awardTotal.cfc?method=myFunction&awardTotals=#awardTotals#
You'll of course have to use access="remote" and return output that JavaScript can handle (again on CF7 your options are a bit limited, as functions like serializeJson() were added in CF8 as well)
(see Invoke ColdFusion function using AJAX)

<CFContent type=text/x-javascript> and Ajax

I am using Ajax on a CFC file. I can't get the result from the function that I am calling from Ajax. I set a debug message (Alert()), but can't see it. Any suggestion?
function getDelegateChartAcct(LocFund){
alert("#Arguments.PIUniversalID#");
alert($F("DelegateFund"));
new Ajax.Request( "?method=displayDelegateChartAcct",
{
parameters : {
PIUniversalID: "#Arguments.PIUniversalID#",
PILocFund: $F("DelegateFund")
},
method : "post"
}
);
}
<cffunction name="displayDelegateChartAcct" access="remote" output="true"
returntype="void">
<CFArgument name="PIUniversalID" type="string" required="true" />
<CFArgument name="LocFund" required="true" type="String" />
<CFSET var chartacctlist = runChartAcctDelegationQuery
(#Arguments.PIUniversalID#, #Arguments.LocFund#)>
<CFContent type="text/x-javascript">
alert(“Hi”);
// delegateChartAcctList();
// $("DelegateChartAcct").
// <CFOutput query="chartacctlist">
// $("DelegateChartAcct").insert( new Element(
"option", { value : "#JSStringFormat( chart_acct )#", selected :
// "selected" } ).update( "#JSStringFormat( chart_acct )#" ) );
// </CFOutput>
</cffunction>
Thanks,
Kefang
You are not returning anything from the CFC (and you can't run JavaScript inside the function you are calling remotely, either).
You have 2 ways you can handle this:
Load the form (or element) you want by making a remote call to a .cfm file that builds the form (or element) you want. You can use $("{place form will be displayed}").load("{url to .cfm page}) and jQuery will make an HTTP request adn load the result in the DOM element that matches the selector.
Change your CFC to return the query and populate the select box on the client side using JavsScript. (This is what I would do)
Your code would look like this:
<cffunction name="displayDelegateChartAcct" access="remote" output="true" returntype="query">
<cfargument name="PIUniversalID" type="string" required="true" />
<cafrgument name="LocFund" required="true" type="String" />
<cfset var chartacctlist = runChartAcctDelegationQuery (#Arguments.PIUniversalID#, #Arguments.LocFund#)>
<cfreturn chartacctlist />
</cfcomponent>
You could then use the following to load that data (looks like Prototype based on the syntax):
new Ajax.Request( "?method=displayDelegateChartAcct&returnFormat=json",
{
parameters : {
PIUniversalID: "#Arguments.PIUniversalID#",
PILocFund: $F("DelegateFund")
},
method : "post",
onSuccess: function(response) {
// code in here will populate select
}
}
);
The 'returnFormat=json' tells ColdFusion to return the results as JSON.
You would just need a JS handler to take that data and use it to populate the SELECT box.

How do I pass an argument to a CFC through AJAX?

I'm using the following scrip to call a CFC function:
function loadQuery() {
$.get('QueryData.cfc',{},function(GetMyData){
$("#content").html(GetMyData)
})
return false
}
$(document).ready(function() {
$("#loadLink").click(loadQuery)
});
This is my HTML:
Load It
<div id="content"></div>
I am calling the following CFC:
<cffunction name="GetMyData" access="public" returntype="query">
<cfargument name="RecordID" type="string" required="yes">
<cfset var RecordData = "">
<cfquery name="RecordData" datasource="MyDSN">
SELECT
foo.RecordID,
foo.RecordName
FROM
foo
WHERE
foo.RecordID = #ARGUMENTS.RecordID# ;
</cfquery>
<cfreturn RecordData>
Problem one is when I call the CFC, the CFC page shows up; the CFC description comes up (after asking for the Admin pass). I don't want to load QueryData.cfc; I want to execute the function inside QueryData.cfc.
The second issue is I can't figure out the syntax for passing an argument to the CFC method.
You can do something similar with the $.get method, but I usually do something like this:
$(document).ready(function() {
$("#loadLink").click(function(e) {
e.preventDefault();
var recordata = $(this).attr("href").substring(1); //trim '?' char
$.ajax({
type: "GET",
url: "QueryData.cfc?method=GetMyData",
data: recordata,
dataType: "html",
success: function(message) {
$("#content").html(message);
}
});
});
});
Where the data for the record ID is stored somewhere in the DOM like so:
Load Data
<div id="content"></div>
Also, not sure how it behaves with access="public" - it might still work - but it should probably be access="remote" on your function.
For what you're doing, would you like to try <cfdiv> or <cfajaxproxy>? It's much easier.
But to answer your question, the GET url should be XXX.cfc?method=whatever&param=xyz
edit: btw your function should have access="remote", and it's not a good idea to return Query object, unless you're using <cfgrid>.

Resources