I've been trying to execute an AJAX call inside an event handler function for about a day, trying lot of when(), then() and done() stuff and also to set async: false but I am still ending up with undefined errors. My code looks like this:
$('#id').on('itemMoved', function (event) {
console.log(event);
$.ajax({
type: "POST",
url: "create.php",
data: event
});
});
I need to pass the event object to create.php to do some server-side stuff. As console.log(event) is printing the object correctly, I guess the reason is the asynchronous behaviour of ajax - but have still no idea how to solve it.
Edit: First of all, sorry for not making it complete. Lack of knowledge makes it more difficult to decide what is relevant.
itemMoved is an event of jQuery UI Widget jxqkanban. It is triggered when a Kanbanitem is dragged and holds information about old and new column and itemdata (Documentation). I think AJAX is running before the objects content is completely resolved, causing
Uncaught TypeError: Cannot read property 'target' of undefined.
Thanks for your time.
Just been having a play in js fiddle link here.
https://jsfiddle.net/WillCodeForBeer/29kqpo58/1/
$("#click").click(function(event){
console.log(event)
data = {};
data.timestamp = event.timeStamp
$.post('/echo/js/?js=hello%20world!', { data : data } );
});
I'm not sure what error you are getting but when I tried to only send the event data I was getting a type error. After some reading, it turns out you cannot be sent the event object as
it contains HTML as it will reference the event target.
I would suggest something similar to the above code and extract the data you need out of the event object into another data object and post that.
NB. The post does not complete due to the url being a fake url. The triggering event is also different but the concept is the same.
let me know how you get on.
Here there is fiddle that maybe can be useful to you:
Fiddle
$('#id').on('click', function (event) {
$.post( "https://httpbin.org/post", event).
done(function( data ) {
console.log( "Data Loaded: " + data );
$( "#results" ).append( "Origin: "+ data.origin );
});
});
In Ajax, and in javascript, in general, is essential the concept of callback.
So in the example above the function inside done is executed only when the server responds.
Related
Im using Woocommece in a WordPress website and some of the plugins installed make requests to an API to check and validate a vat field.
Id like to use .ajaxSuccess() to tap into the ajax response thats returned so I can check to see if part of it contains some data and do something on screen.
So far Ive got this.
jQuery(document).ready(function(){
var event = 'updated_checkout'
jQuery(document).ajaxSuccess(function(event){
console.log('success');
})
})
So the console spits out success. Great. But Im stuck as how I would move forward with this. I dont know how to get the XHR option or get he response in a variable.
Any help would be appreciated.
To get the response from the request in the $.ajaxSuccess() handler, retrieve the responseText property from the jqXHR object passed to the handler function in the second argument:
jQuery(document).ready(function($) {
var event = 'updated_checkout'
$(document).ajaxSuccess(function(e, xhr) {
console.log(xhr.responseText);
});
});
I several HTML elements that initiate ajax when clicked. How can I check which element was clicked inside the ajaxComplete event?
I tried event.target but it returns the entire document.
$( document ).ajaxComplete(function( event, xhr, settings ) {
if ( settings.url.indexOf("somelink/hello") > -1) {
console.log("return here element that initiated ajax")
}
});
Note: The tricky part - I don't have access to the ajax request that is sent on click. I can't configure the code that makes the request. I can only check when the ajax is complete.
I first need to run the ajaxComplete event then check which element initiated ajax because I need to add some html to that element. For this reason I'm trying to check in the ajaxComplete event.
The $.ajaxComplete() handler is not an object-specific handler; you attach it to the document to be notified whenever any AJAX request completes. From the jQuery docs:
If you must differentiate between the requests, use the parameters passed to the handler. Each time an ajaxComplete handler is executed, it is passed the event object, the XMLHttpRequest object, and the settings object that was used in the creation of the request.
So, since settings is a plain Object, you can extend it with a property that will then be passed to the handler, as you can see below with requestingObjectId. DEMO
var onComplete = function(event, jqXHR, ajaxOptions) {
alert("Requested with " + ajaxOptions.requestingObjectId);
};
var makeRequest = function() {
var id = $(this).attr('id');
$.ajax({
url: '/path/to/server',
data: { foo: 1 },
requestingObjectId: id
});
};
$('button').click(makeRequest);
$(document).ajaxComplete(onComplete);
Best and easiest way is to store the element in a global variable when you send the ajax call. Set it to the event.target.activeElement. Then in your ajaxComplete you can just access that var to change CSS etc.
Upon further consideration, if you use my solution you would have to limit it to one ajax request at a time. Otherwise a new ajax request would overwrite variable if the initial ajax request hadn't completed yet. I'd take Palpatime's answer.
An jQuery AjaxRequests is NOT send by an control itself. It is send by the code that the developer wrotes as event function onto this Dom element.
Means the best thing you can get is the callee of $.ajax() by overwriting and wrapping it. And only if the callee is not written in strict mode.
I would prefer to read the documentation of that framework who is building your controls or if it is built by another company/guy contact them.
As the element is not the direct caller of the $.ajax, I see no other way.
I'm experiencing some extremely weird behavior with Ajax. Or maybe it's normal. I wouldn't know. I'm quite new to playing around with Ajax.
My problem is that I am making a few Ajax calls(two using $.post() and one using the standard $ajax() call), and they seem to return the data fine, but the code inside the success function only works in a very peculiar way.
I have noticed that some things work if placed first in line to be executed; but why is that? It really doesn't make any sense to me. In this case I would like the span with the id link_span to be updated dynamically, as my Ajax calls link and unlink devices from each other.
(the correct_classes function counts how many links have been linked and adds it to the link_counter variable that I've made global with the window object).
But as the span only wants to update if the corresponding code is placed on top, it's kinda useless.
Another problem is also that .ajaxComplete() and other such event handlers don't always get called. For example, I attempted to show and hide a loader gif by using .ajaxComplete() to close it when ajax stop. But this only works with one of my calls which is the standard $.ajax call.
I'm really confused.
Any help would be great, and please ask me to clarify if there's something I haven't made clear enough.
Here is a small snippet of what I'm talking about:
$.post( "<?php echo base_url(); ?>connections/ajax_link", datax).done(function( resp,status ) {
$("#loader_overlay").css('display','none');
display_confirmbox();
resp=JSON.parse(resp);
var str = resp['parent_selector'];
var arr = mystr.toString().split("||");
correct_classes(arr[1], resp);
$( '#link_span' ).text( '( ' + window.link_counter + ' ) links found' ); //this doesnt work unless its on top
});
Update
It seems that the problem is caused by correct_classes();
the array from the ajax call gets passed to the function in which jQuery complains about something, and causes the rest of the ajax code to halt. Yet everything inside correct_classes() gets executed. The error in question is this:
TypeError: invalid 'in' operand e
specifically what is causing the problem seems to be this(i commented everything else out and this is:
$.each( val, function( i, value ) {
var mystr = value;
}
I really cant figure out why it complains about this code when it seems to work.
i'm not sure to have understand your problem.... but if you use 3 async ajax call ($.post or $.ajax is indifferent $.post is a contract syntax to call $.ajax({type:"post"})) you need to wait the full loading of all calls for use their response.
so.. if one of your call evalue window.link_counter you need to wait his response before call the code you have post.
For wait the complete load you may nast the call inside the success function of the prev call.
for you knowlage there is an attribute of $.post() dataType if you set it to "json" you not need to parse the response because Jquery do it for you, this code is useless:
resp=JSON.parse(resp);
and, the method .done() is calling whether the call is successful if it fails, $.post() has a success function callback. Use it, it's better, and use .fail() to catch call error.
See documentation about $.post(): here
however... the element who have this id #link_span is generated by one of ajax call?
Im running into a problem where i have an ajax driven page that is drawn when a user selects something from a simple drop down:
<select id = "selectdepartment">
<option id = "default">Select an option...</option>
....
</select>
and the remainder of the page is drawn using the jquery .change() :
$('#selectdepartment').change(function(){
});
Which then runs some ajax to php script. everything works great, the problem is when i submit a form that was drawn with ajax (using $_SERVER['PHP_SELF'];), the data gets submited, the page reloads, and the page is cleared but the select box is still left where it was. The user has to move to a different option then back to the one the selected originally to re-fire the .change(). that sucks.
I could fix this by passing a php variable in all of my forms, then checking to see the variable set on every page load and if it is draw the page parts then, but this would lead to pretty messy code and it's less than desirable.
There has to be a way to do this with the jquery library, though my knowledge of the javascript language in general is not what i would like it to be. If anyone has any helpful hints please share, dont do it for me though, i wont learn that way :)
edit: code with .trigger
$('#selectdepartment').change(function(){
var department = $('#selectdepartment').val();
var day = $('#data').data('day');
var month = $('#data').data('month');
var year = $('#data').data('year');
//alert (department);
if(department === "Select an option..."){
$('.hiddenuntildepartmentisselected').css({"display":"none"});
}
else{
$('.hiddenuntildepartmentisselected').css({"display":"block"});
}
showpoints(department);
drawpointstable(department, day, month, year);
displaytheuseresforselecteddepartment(department, '');
$('#sendthedepartment').val(''+department+'');
$('#hiddendepartmentidforaddinganewpoint').val(''+department+'');
}).trigger('change');//end run functions
You can use the .trigger() function to immediately trigger the change event handler when the page has loaded:
$('#selectdepartment').change(function() {
// code here
}).trigger('change');
Or if you need to call it elsewhere via JavaScript/jQuery:
$('#selectdepartment').trigger('change'); // or just .change() as a shorthand
Updated
Your button for the form could make use of the onClick attribute, which would invoke a method to parse the form fields and post the data to your php script via .ajax().
In the success event method you then check any flags you need to and modify the element as you desire if needed.
Basic example:
Inside of .ajax():
...
url: 'xxx.xxx.xxx',
async: true,
type: 'POST',
dataType: 'html',
data: JSON.stringify( form_fields ),
beforeSend: function()
{
// Pre send stuff, like starting a loading gif
},
success: function( data, textStatus, xhr )
{
// Be sure you load the page with the content first
$( '#containing-div' ).html( data );
// Do your check here, and modify your element if needed here
if( flagtocheck === 'xxx' )
{
// Modify the element in question...
}
// I call a custom method termed `.ctrls()` here that makes any
// adjustments to the DOM once its loaded/updated.
},
error: function( xhr, textStatus, errorThrown )
{
}
Of course, you'll want to set flagtocheck appropriately in your case.
Hope that helps!
Note regarding edit
This post was edited to be a little more descriptive and more easily understood. Since the person asking the question is already using the .ajax() method, the success event method is the ideal place for doing what the person asking the question is requesting. It is 1 less method invocation to directly modify the element there than using it to call .trigger() or .change() which then also directly modifies the element.
How can I fix the script below so that it will work EVERY TIME! Sometimes it works and sometimes it doesn't. Pro JQuery explains what causes this, but it doesn't talk about how to fix it. I am almost positive it has to do with the ajax ready state but I have no clue how to write it. The web shows about 99 different ways to write ajax and JQuery, its a bit overwhelming.
My goal is to create an HTML shell that can be filled with text from server based text files. For example: Let's say there is a text file on the server named AG and its contents is PF: PF-01, PF-02, PF-03, etc.. I want to pull this information and populate the HTML DOM before it is seen by the user. A was ##!#$*& golden with PHP, then found out my host has fopen() shut off. So here I am.
Thanks for you help.
JS - plantSeed.js
var pageExecute = {
fileContents:"Null",
pagePrefix:"Null",
slides:"Null",
init:function () {
$.ajax({
url: "./seeds/Ag.txt",
success: function (data){
pageExecute.fileContents = data;
}
});
}
};
HTML - HEAD
<script type="text/javascript">
pageExecute.init();
</script>
HTML - BODY
<script type="text/javascript"> alert(pageExecute.fileContents); </script>
Try this:
var pageExecute = {
fileContents:"Null",
pagePrefix:"Null",
slides:"Null",
init: function () {
$.ajax({
url: "./seeds/Ag.txt",
async: false,
success: function (data){
pageExecute.fileContents = data;
}
});
}
};
Try this:
HTML:
<div id="target"></div>
JavaScript:
$(function(){
$( "#target" ).load( "pathToYourFile" );
});
In my example, the div will be filled with the file contents. Take a look at jQuery .load() function.
The "pathToYourFile" cand be any resource that contains the data you want to be loaded. Take a look at the load method documentation for more information about how to use it.
Edit: Other examples to get the value to be manipulated
Using $.get() function:
$(function(){
$.get( "pathToYourFile", function( data ) {
var resourceContent = data; // can be a global variable too...
// process the content...
});
});
Using $.ajax() function:
$(function(){
$.ajax({
url: "pathToYourFile",
async: false, // asynchronous request? (synchronous requests are discouraged...)
cache: false, // with this, you can force the browser to not make cache of the retrieved data
dataType: "text", // jQuery will infer this, but you can set explicitly
success: function( data, textStatus, jqXHR ) {
var resourceContent = data; // can be a global variable too...
// process the content...
}
});
});
It is important to note that:
$(function(){
// code...
});
Is the same as:
$(document).ready(function(){
// code
});
And normally you need to use this syntax, since you would want that the DOM is ready to execute your JavaScript code.
Here's your issue:
You've got a script tag in the body, which is asking for the AJAX data.
Even if you were asking it to write the data to your shell, and not just spout it...
...that's your #1 issue.
Here's why:
AJAX is asynchronous.
Okay, we know that already, but what does that mean?
Well, it means that it's going to go to the server and ask for the file.
The server is going to go looking, and send it back. Then your computer is going to download the contents. When the contents are 100% downloaded, they'll be available to use.
...thing is...
Your program isn't waiting for that to happen.
It's telling the server to take its time, and in the meantime it's going to keep doing what it's doing, and it's not going to think about the contents again, until it gets a call from the server.
Well, browsers are really freakin' fast when it comes to rendering HTML.
Servers are really freakin' fast at serving static (plain-text/img/css/js) files, too.
So now you're in a race.
Which will happen first?
Will the server call back with the text, or will the browser hit the script tag that asks for the file contents?
Whichever one wins on that refresh is the one that will happen.
So how do you get around that?
Callbacks.
Callbacks are a different way of thinking.
In JavaScript, you perform a callback by giving the AJAX call a function to use, when the download is complete.
It'd be like calling somebody from a work-line, and saying: dial THIS extension to reach me, when you have an answer for me.
In jQuery, you'll use a parameter called "success" in the AJAX call.
Make success : function (data) { doSomething(data); } a part of that object that you're passing into the AJAX call.
When the file downloads, as soon as it downloads, jQuery will pass the results into the success function you gave it, which will do whatever it's made to do, or call whatever functions it was made to call.
Give it a try. It sure beats racing to see which downloads first.
I recommend not to use url: "./seeds/Ag.txt",, to target a file directly. Instead, use a server side script llike PHP to open the file and return the data, either in plane format or in JSON format.
You may find a tutorial to open files here: http://www.tizag.com/phpT/fileread.php