Solved

ajax/jquery/coldfusion not playing nicely

Posted on 2013-11-26
22
526 Views
Last Modified: 2013-12-03
I'm going to include:
The cFC code
The script containing the function that call calls a cfm template.
I keep getting errors when the form submits or the link is tapped.

to make sure it was working as expected i called the addDupe.cfm via cfinclude, no problem.
the ajax part is causing an error when i call from the main page, the one with the sweaters

can't I access that CFC ,.. i'm avoiding that one...

all help appreciated in advance
code.txt
0
Comment
Question by:ecpeel
  • 12
  • 8
  • 2
22 Comments
 
LVL 75

Expert Comment

by:Michel Plungjan
ID: 39682003
Dear ECPeel

To ask a good question you need the following

1. A description of the problem containing
  a.expected output
  b. actual output and/or exact error message

2. a contained example, for example jsfiddle.net

What are the errors
What does the CF look like if you call it from the location bar directly
Is it JSON, is the mime-type application/json

It gives errors "on the one with the sweaters" ??? What one with the sweaters? Can you give us an actual link?
0
 

Author Comment

by:ecpeel
ID: 39682296
and this is why we shouldn't stay up past 2 am for nights in a row and ask for help.
and to think i cleaned that up quite a bit. I'll answer what I can in respect for your taking the time to respond.

1. description: the success portion of the ajax fails.
a. expecting a number returned from the database after the insert (current pkid)
b. "errorThrown" is blank but jqXHR gives me [object][object]

2. I've never entered my own code into jsfiddle and if that's really required i shall. it would be a good learning exercise in the virtual ide world.
*I was of the mind that I had attached all of the code with the question. Apparently no so.

I'm not getting any errors other than the part of the logic that catches a failure after success:

The cf is using form data, fed to the component as an argumentCollection and there's oracle sequence in control of PKs that's hard to define outside of the session.
However, if i cfinclude the page that invokes the component,"addDupe.cfm", she's running just fine. The moment I do the ajax call not so.
l
Yes it's json.

the comment about the sweaters was the sandman gettin his way.

my jquery function:
<!--- for the duplication of a waiver --->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
	$.noConflict();
	jQuery( document ).ready(function( $ ) {
	  // Code that uses jQuery's $ can follow here.

		$(function doDupe(){

			$('#dupeButton').click(function(){
				$.ajax({
					type:'post',
					url: 'addDupeWaiver.cfm',
					//data:{argumentCollection: "#form#"},
					dataType: 'json',
		            success: function (resp, textStatus, jqXHR) {
		               alert('ok now');
		               return true;
		            },
		            error: function (jqXHR, textStatus, errorThrown)
		            {
		                alert('shit went wrong');
		                alert(jqXHR);
		                return false;
		            }
				});
			});
		});
	});

</script>

Open in new window

The addDupe.cfm which has the invocation
<cfinvoke component="#waiverComponent#" method="insertDuplicateWaiver" returnvariable="waiver_id" argumentCollection="#Form#" />
<cfoutput>#serializeJSON( waiver_id )#</cfoutput>

Open in new window

And lastly a portion of the cfc (I'll be attempting to duplicate at home so all of info isn't required
	<cffunction name="insertDuplicateWaiver" access="remote" returnformat="JSON" output="false">

		<cfargument name="waiver_id" type="numeric" default="0">
		<cfargument name="waiver_pid" type="numeric" default="0">

		<cfif arguments.waiver_id eq 0>
			<cftry>
				<cfquery datasource="#application.dsn#" name="WaiverInsert">
				INSERT INTO WA_WAIVER
					(waiver_id,
					waiver_pid,
					py,
					py2
				VALUES
					(SEQ_Whatever.NEXTVAL,
					#arguments.waiver_pid#,
					#arguments.py#,
					'#arguments.py2#'
                                         )
				</cfquery>
				<cfcatch type="any">
<!--- 					<cfoutput>
			            <!--- The diagnostic message from ColdFusion. --->
			            <p>#cfcatch.message#</p>
			            <p>Caught an exception, type = #CFCATCH.TYPE#</p>
			            <p>The contents of the tag stack are:</p>
			            <cfdump var="#cfcatch.tagcontext#">
        			</cfoutput> --->
				</cfcatch>
				</cftry>
				<cfquery name="ins" datasource="#application.dsn#">
					select	SEQ_WA_WAIVER.currval as waiver_id
					from	dual
				</cfquery>
				<cfset myWaiverid=ins.waiver_id>
			</cfif>
		<cfreturn myWaiverid>
	</cffunction>

Open in new window


Hope this helps you to help me!
shoot, the button...
			<cfif  variables.doesExist gt 0 and variables.errMsg neq "" >
				<form name="formDuplicate" action=""  method="post">
					<input type="hidden" name = "errMsg" value="">
					<input type="hidden" name = "action" value="">
					<input type="hidden" name = "doesExist" value="0">
					<input type="hidden" name = "doRunCheck" value="0">
					<input type="hidden" name="waiver_id" value="#form.waiver_id#">
					<label FOR="dupeButton" style="hidden">&nbsp;</label>
					<input type="submit" id="dupeButton" value="Click here if you are sure you would like to duplicate this waiver ">
				</form>
			</cfif>

Open in new window

the hidden stuff is just to pass back required vars to the template.

thanks again.
0
 
LVL 75

Expert Comment

by:Michel Plungjan
ID: 39682877
Hi again.

I took the liberty to edit your question and wrap the code in [ code ] ...  [/ code ] tags (which you can do by highlighting code and hit the Code button in the editor.


Please change the alert to

window.console && console.log(jqXHR);

Hit F12 and click script console in IE, or console in Chrome and more will be revealed
0
 
LVL 1

Assisted Solution

by:websauce
websauce earned 150 total points
ID: 39683023
I think you can call the CFC directly from jquery with no CFM inbetween?

 
I think you can call the CFC differently.
This example takes makes cascading drop downs on a form.

note the ajax call and the cfc being directly called.
pass in the id of what you are duplicating, to a part in the CFC that dupes the info,
and returns back an ok.
??

//js snippet


$("#specID").change(function()
			{
			if($(this).val() != '')
			{
			$.ajax({
			type: "POST",
			url: "./dropdown.cfc?method=SelectedSubCats",
			data: ({
			catID: $(this).val()
			}),
			dataType: "json",
			
			//on success, stuff the result from the cfc into the success function
			success: function(dataToParse){
				var r = dataToParse;
			//reset dependent select box
			$('#subSpecID option').remove();
			//build a variable 'options' that is the list of subcats.
			var options= '';
			 for (var i = 0; i < r.DATA.length; i++) {
				options += '<option value="' + r.DATA[i][0] + '">' + r.DATA[i][1] + '</option>';
				  }
				  $("select#subSpecID").html(options);
			
				}
			});
			
			}
			});
			//end catlist Change

Open in new window


                  

CFC
<cffunction access="remote" name="SelectedSubCats" output="false" returntype="query" returnformat="json">
<cfargument name="catID" required="yes" type="numeric" default="-23" />
<cfquery name="SelectedSubCats" datasource="xxxxx" >
SELECT id,subspecies FROM subspecies
WHERE topSPECID = #Arguments.catID#
ORDER BY subspecies
</cfquery>
<cfreturn SelectedSubCats>
</cffunction>

Open in new window


****
that might help once you get the console output as mplungjan suggested.

maybe its not what you want at all ...
0
 
LVL 75

Accepted Solution

by:
Michel Plungjan earned 350 total points
ID: 39683049
Ok, I had a time to read your post

Several issues

You need to attach the ajax to the submit event but do so in the load event
You also need to stop the form submission since you want to stay on the page
You need to do something in the success event with the data I assume

Give the form an ID

<form id="formDuplicate" action=""  method="post">

Then do

$(function() { // on load
  $("#formDuplicate").on("submit",function(e) {
    e.preventDefault(); // do NOT submit
    // post the form contents to the url you gave
    $.post("addDupeWaiver.cfm",$(this).serialize())
      .done(function(data) {
       // not sure what you want with the data
       window.console&&console.log(data);
    });
});

Open in new window

0
 

Author Comment

by:ecpeel
ID: 39684353
Firstly, let me say thanks to you guys for getting back with me and bearing with me as I solicit your aide while causing extra work on your behalves to  sort through my muck and spin what could be a negative experience into a positive and edifying one.

websauce:
I'm working in a new environment on a new machine and with a lot of unknowns in the setup. I don't have any CF admin rights. So I am completely blind to the cfmappings.

Instantiating a component and assignment with cfset and createObject work fine until you get to the jQuery/Ajax functions which is why I had difficulty calling the cfc directly in the AJAX call. I've done that before and removed the need for the cfm page but due to the mapping requirements of the cfc directory and the level of effort to get that modification I chose/choose to exhaust the options of using the cfm as a type of proxy.

mplungjan: Thanks for reminding me of the

Open in new window

tags. I could not recall how to do that and I have been pressed by time and needs to catch trains to provide you with properly formatted code and intelligently structured questions.

Even the mysteriously competing and still as of yet unknown library that forced me to use the no conflict suggests there's a lot in the environment I have a lot to become aware of.

AND console.log hasn't functioned as expected ex: testing with console.log('test');-- bupkiss, which is why I've been forced to use alert().

What I do know looking at the pages I have to edit... no one is doing ajax calls so far. At least not in the application I am  modifying.

Currently: mimicking my work setup and I will incorporate your suggestions. At the very least we should be able to trap some errors.

can't thank you guys enough. be back at you soon.
0
 
LVL 75

Expert Comment

by:Michel Plungjan
ID: 39684763
console.log does not work in IE when the console is not open

Hence the

 window.console&&console.log("message");
0
 

Author Comment

by:ecpeel
ID: 39685669
hey guys, the console was working. I'm using chrome. My eyes weren't catching the log messages at first since so many were showing up.

other issues turned out to be my form submission. the errors were coldfusion based and I was thinking they couldn't be until I isolated the parts of the cf error messages that screamed missing form vars.


Here's where I am. form is working submitting but preventing the page from refreshing after the submit as it must.

<script>
	$.noConflict();
	jQuery( document ).ready(function( $ ) {
		$(function () {
			  $("#formDuplicate").on("submit",function(e) {
				e.preventDefault(); // do NOT submit
				// post the form contents to the cfm because we cannot call the cfc directly and serialize the json reponse
				$.post("addDupeWaiver.cfm",$(this).serialize())
				  .done(function(data) {
				   //nothing to return
				  console.log(data);
				});
			});
		});
	});
</script>

Open in new window

0
 

Author Comment

by:ecpeel
ID: 39685706
got it.
<script>
      $.noConflict();
      jQuery( document ).ready(function( $ ) {
            $(function () {
                    $("#formDuplicate").on("submit",function(e) {
                        e.preventDefault(); // do NOT submit
                        // post the form contents to the cfm because we cannot call the cfc directly
                        $.post("addDupeWaiver.cfm",$(this).serialize())
                          .done(function(data) {
                           //nothing to return
                           $("#formDuplicate").unbind('submit').submit();
                        });
                  });
            });
      });
</script>
0
 

Author Comment

by:ecpeel
ID: 39685707
Thank both of you guys so much!!
0
 
LVL 75

Expert Comment

by:Michel Plungjan
ID: 39685748
You are not sending the data twice now? Once with Ajax and once with normal submit? Perhaps you do not even WANT ajax in this situation
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 1

Expert Comment

by:websauce
ID: 39688789
Perhaps my comment muddied the water.

@ecpeel

I don't think you need to know the mappings to run a CFC.
Note the relative path on the call:

url: "./dropdown.cfc?method=SelectedSubCats"

----

like mplumgjan said, make sure you're not sending data twice.
it looks like your last example does that.

you don't need the onsubmit if you're using the post/ajax inside.
take the results of from the ajax and write it out to a container using .html() for the status.
0
 

Author Comment

by:ecpeel
ID: 39690622
You are not sending the data twice now? Once with Ajax and once with normal submit? Perhaps you do not even WANT ajax in this situation

@ mplungjan

Some of the data submitted by this form is important to the cfc.
the rest is important to the template that submits the form.

So I guess in essence, yes, I do want to submit twice (or rather to two different locations at once). There is no conflict. I did forget to utilize the return from the ajax call. That's being solved now.

@websauce: url:
"./dropdown.cfc?method=SelectedSubCats"
Thank you.
0
 

Author Comment

by:ecpeel
ID: 39691129
@ mplungjan
this style of making the call using .done(data) is new for me.
after reading it seems the preferred method but setting the result to a global variable isn't working for me.

example:
<script>
	var new_waiverid = 0;
	$.noConflict();
	jQuery( document ).ready(function( $ ) {

		$(function () {
			  $("#formDuplicate").on("submit",function(e) {
				e.preventDefault(); // do NOT submit
				// post the form contents to the cfm because we cannot call the cfc directly
				//we can serialize the json reponse here as well
				async: false,
				$.post("addDupeWaiver.cfm",$(this).serialize())
				  .done(function(data) {
				   //return new waiver id
				  //new_waiverid = data;
				   //allow the form to submit
				  $("#formDuplicate").unbind('submit').submit();
					new_waiverid = data; 
					console.log(new_waiverid); //variable has the result
				});
			});
		});
		alert(new_waiverid);//now its back to zero
	});
</script>

Open in new window

0
 
LVL 75

Expert Comment

by:Michel Plungjan
ID: 39691706
1) you have a $(function() { too many
2) it is not back to 0. Since Ajax is asynchronous, the statement where you alert is executed before the post returns. That is the nature of the beast.

Ps: what is with the no conflict? Do you run other frameworks than jquery on the page? If not, drop all this extra code
0
 

Author Comment

by:ecpeel
ID: 39693105
mr;lungjan:
yes there is another framework running so I needed to do that. not in charge of that.

i can't get the callback out of this and i wonder if it's got something to do with the current code.
current code is:
<script>
var new_waiverid = 0;
	$.noConflict();
	jQuery( document ).ready(function( $ ) {
		$(function () {
			$("#formDuplicate").on("submit",function(e) {
				e.preventDefault(); // do NOT submit
					$.ajax({
					type: "POST",
					cache: false,
					  url: 'addDupeWaiver.cfm',
					  async: false,
					  data: $(this).serialize(),
					  success: function(data) {
					    x = data; alert(x);
					   	$("#formDuplicate").unbind('submit').submit();
					  }

				 });

			});
		});
	});
</script>

Open in new window

0
 

Author Comment

by:ecpeel
ID: 39693252
i'll ask the postback question in a different request.
thanks
0
 
LVL 75

Expert Comment

by:Michel Plungjan
ID: 39693290
Please remove $(function(){ and the matching });
0
 

Author Comment

by:ecpeel
ID: 39693809
done.
still getting the syntax error though. pasting here:
<script>
var new_waiverid = 0;
	$.noConflict();
	jQuery( document ).ready(function( $ ) {

		$("#formDuplicate").on("submit",function(e) {
			e.preventDefault(); // do NOT submit
				$.ajax({
				type: "POST",
				cache: false,
				  url: 'addDupeWaiver.cfm',
				  async: false,
				  data: $(this).serialize(),
				  success: function(data) {
				   handelRequest(data),
				   	$("#formDuplicate").unbind('submit').submit();
				  }

			 });

		    function handelRequest(data) {
		        onComplete(data); //get correct value, works fine
		    }

		    function onComplete(new_waiverid){
		    	var window[x] = new_waiverid;
		        alert(window.x);

		    }
			 //return data;
		});

	}) //doc ready
</script>

Open in new window

0
 

Author Comment

by:ecpeel
ID: 39694034
updated code: The function actually returns the response (data).
but below, the variable new_waiverid is back at zero.
adding window scope seems to mess things up.

and you'll see i removed the function and the no conflict. when i updated the jquery.min... that seemed to remove the conflict or someone removed the conflicting library unbeknownst to me.

<script>
var new_waiverid = 0;
    function onComplete(x){
    	new_waiverid = x;
		alert(new_waiverid);
    }
	jQuery( document ).ready(function( $ ) {
			$("#formDuplicate").on("submit",function(e) {
				e.preventDefault(); // do NOT submit
					$.ajax({
					type: "POST",
					cache: false,
					  url: 'addDupeWaiver.cfm',
					  async: false,
					  data: $(this).serialize(),
					  success: function(data) {
					    handelRequest(data),
					   	$("#formDuplicate").unbind('submit').submit();
					  }

				 }); // end ajax call
				 	function handelRequest(data) {
			        onComplete(data); //get correct value, works fine
			    }

			})
	})

</script>

//here the variable is back to 0

<script>alert(new_waiverid);</script>

Open in new window

0
 
LVL 75

Expert Comment

by:Michel Plungjan
ID: 39694588
Again the alert is executed sometime other than where the Ajax gets the value. You CANNOT access the value except in functions called in the success
0
 

Author Comment

by:ecpeel
ID: 39694799
you are correct. I moved this part to a new question. afterall you guys answered the first question it's only fair.

it's here: New question

Hopefully I can continue to benefit from your expertise there.

thanks again!
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

There are a couple ways to attach a JavaScript function to dynamically created elements. You can make a new script for each element as it’s created or you can use delegation. Delegation allows a single script that is added at page creation to mat…
I found this questions asking how to do this in many different forums, so I will describe here how to implement a solution using PHP and AJAX. The logical flow for the problem should be: Write an event handler for the first drop down box to get …
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now