This question already has an answer here:
JavaScript jQuery delay oninput
(1 answer)
Closed 3 years ago.
I would like to request some help in saving data from a "notepad" using Ajax. The notepad in my case is a simple textarea for which we can capture an onchange event.
HTML
<textarea id="notepad"></textarea>
jQuery
$('#notepad').on('change paste keyup', function(event) {
var formData = $(this).serialize();
$.ajax({
url: url,
type: 'POST',
data: formData,
success: function(data, status) {
console.log('Something worked');
},
error: function(xhr, desc, err) {
console.log('Something went wrong');
}
});
}
The above code works perfect for what I need to do. However, in practice I found that the above code is not perfect for this scenario, since a lot of content would go through this textarea having an ajax call for every keyup / change is a lot of Ajax and MySQL calls.
I wanted help in figuring out how I could somehow trigger the Ajax call only after the change in text is completed. My first instinct was to add a delay to the ajax call, but that would still mean many many ajax calls after a set number of time.
Is there any way for me to completely hold of Ajax calls until the very end? That is maybe 5 seconds after the user has finished adding content to the textarea?
Note: Adding a submit button is not an option sadly.
Try changing which events you're listening for via jQuery. 'change paste keyup' are all different events. Try taking 'keyup' out and leave the other two.
That's the simplest answer.
Another more complicated option is to add a timer that delays the ajax until a certain amount of time has passed.
$('#notepad').on('change paste keyup', function(event) {
var formData = $(this).serialize();
setTimeout(function(){
$.ajax({
url: url,
type: 'POST',
data: formData,
success: function(data, status) {
console.log('Something worked');
},
error: function(xhr, desc, err) {
console.log('Something went wrong');
}
});
}, 3000);
}
Two notes: I left the formData variable outside the timeout because "this" will not function the same inside an anonymous function. (Another option would be to save "this" to a different variable, then serialize your form data inside the timeout.)
var thisForm = $(this)
setTimeout(function(){
var formData = thisForm.serialize()
Finally, the "3000" is the time in MS after the event fires that the timeout will take to trigger.
Also--use const or let instead of var. (See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let)
Related
I have an ajax call on click of anchor tag in WordPress and I have not control over this. But before this ajax call I want to fire click event.
This click event is firing sometime but not every time. So I am not getting consistent results. Is there any way so that I can get correct results and get this click event fire before ajax call. I have tried putting my code in header and in footer as well.
Here is my code that i am using for click event.
jQuery(document).ready(function(){
jQuery("#addbtn").click(function(){
});
});
Any suggestion about this will be much appreciated.
you can use befor beforeSend
This event, which is triggered before an Ajax request is started, allows you to modify the XMLHttpRequest object (setting additional headers, if need be.)
source: https://api.jquery.com/Ajax_Events/
$.ajax({
type: 'POST',
url: url,
data: data,
beforeSend: function() {
/*using a loader while waiting or fire an event or execute a function */
},
success: function(data) {
//execute a function on request sucess
},
error: function(xhr) { // if error occured
alert("Error occured.please try again");
},
complete: function() {
//execute a function once the call completed
}
});
I hope this will help you slove the issue
I tried searching all over the Internet and found no simple answer, which I believe exists for two problems I'm having. My Jquery UI Autocomplete is below:
$('#moviename').autocomplete({
// URL is parsed by my framework
source:"<?=URL::route('MovieAutocomplete')?>",
minLength:2,
dataType:"json",
select:function(event,ui){
// set artist id
$('#movieid').val(ui.item.id);
$('#moviename').prop('disabled',true);
$('#moviedetails').prop('disabled',false);
$('#movieclear').html('Clear');
$('#moviehint').toggle();
}
});
This code works. However, I am looking at the performance. I have two questions:
My controller cancels the request if it sees a blank term. However, I would like to check this condition even before the request is sent. I have played with beforeSend, but it doesn't work somehow. Can someone help me accomplish this one?
I would also like to fire the AJAX request only when the user stops typing, say give it a time of 500ms to wait before it can send request to the server. Is there any easy way to do this? I am guessing "call autocomplete inside a keyup event which will be bound to the field I want". Please help me.
It would be great if someone can look into this one for me.
I recently have been working with the jQuery UI autocomplete. This is the logic I used & it works well.
onKeydownMethod: function(event) {
if ($(this).val().length >= App.autocompleteMinLength)
{
if ($(this).val().length >= YOUR_MIN_LENGTH) {
$('selector').autocomplete({
minLength: YOUR_MIN_LENGTH, // min number of chars before request is made.
delay: YOUR_DELAY, // mum of miliseconds to wait before making request.
source: function(request, callback) {
$.ajax({
type: 'get',
contentType: 'application/json',
url: 'YOUR_URL' + ANY_PARAMS,
dataType: 'json',
timeout: 50000
}).done(function(response) {
callback(response); // I used a callback to send data back to the parent function. Handle the response however you like here.
}).fail(function(error) {
switch (error.statusText)
{
case 'OK':
// handle response.
break;
default:
// handle response
break;
}
});
}
});
}
}
I've a jsp page with a form and some jquery code. Jquery code works perfectly, but if I return that page in a popup window by using an ajax call, the jquery code doesn't work any more.
I tried also to use delegation, that is:
$('select[name=myElementName]').on("change", function() {
// some code
});
or
$(document).on("change", 'select[name=myElementName]', function() {
// some code
});
instead of
$('select[name=myElementName]').change(function() {
// some code
});
Ajax call:
var preview = function () {
$.ajax({
type: "POST",
url: myAction.do,
data: "id=" + myid,
success: function (response) {
// some code
var x=window.open('', '_blank', 'titlebar=no,scrollbars=yes,menubar=no,height='+height+',width='+width+',resizable=yes,toolbar=no,location=no,location=0,status=no,left='+left+',top='+top+'');
x.document.open();
x.focus();
x.document.write(response);
return false;
},
error: function () {
return false;
},
});
};
EDIT
On Firefox 26.0 and Chrome 32.0.x, I resolved by using
x.document.close();
after
x.document.write(replace);
Instead, on IE, all the .js included scripts are ignored (for example the jquery-ui-1.9.1.js).
EDIT 2
I resolved with
<body onload="myload()">
and in my jsp I've myload() definition in which I call the scripts.
It is because you are creating new DOM structure but it doesn't have the event handlers attached. The easiest way is to run the event handler in the ajax callback:
$.ajax({
...
success: function (response) {
// some code
var x=window.open('', '_blank', 'titlebar=no,scrollbars=yes,menubar=no,height='+height+',width='+width+',resizable=yes,toolbar=no,location=no,location=0,status=no,left='+left+',top='+top+'');
x.document.open();
x.focus();
x.document.write(response);
// now, place the event handler here
$('select[name=myElementName]', x.document.body).change(function() {
// some code
});
}
});
Don't use document.write it completely overwrites whatever is on the page at the time of writing and leads to race conditions (e.g. the external scripts might have already been loaded, but they also might not, leading to unknown order of the write and script loads). Also, I believe documnt.write is putting serialized text into the document, not DOM objects so it may not trigger events.
Instead, you can open the new window and then manipulate the DOM objects there directly (assuming it's on the same server as your main page):
//Open a new window for the success info
var newWindow = window.open(newUrl);
//Now grab some element
var someItem = newWindow.document.getElementById( "someId");
//Manipulate dom either by "someItem.innerHTML" or "someItem.appendChild(...)"
If you are calling an AJAX server routine and putting the entire response w/o processing it on the client in to a new window, why not opening the window directly with the URL of that AJAX routine and skipping all stuff:
....
var x=window.open(myAction.do + "?id=" + myid,
'_blank',
'titlebar=no,scrollbars=yes,menubar=no,height='+height+',width='+width+',resizable=yes,toolbar=no,location=no,location=0,status=no,left='+left+',top='+top+'');
....
The only diff here is, that the request is a GET and not a POST request, but the data is just one id, which is acceptable, probably?
I had a similar problem in on of my projects. I solved it by writing a success method after the ajax call.
{
$.ajax({
type: "POST",
url: "/abc/",
data:{<data>},
async:false,
dataType:'json',
success: function(response)
{
success=1;
Id=response;
return;
}
});
if (success)
{
#your code here
var a='/xyz/?Id='+Id
window.open(a,'_blank');
window.location.href='/registration/'
}
return false;}
instead of using document.write, try fetching your success data(records arrived in success function) in a hidden DIV and clone it into your popup that should work
I have tried so many things, cannot figure this out, I am using this code, and I know that the start is working, because the script it connects to sticks some info in the db, but the callback never runs.
<script type="text/javascript">
$(document).ready(function() {
$(document.body).on('click', "#reply_submit", function() {
var formData = $('#reply').serialize();
$.post("newpost.php",formData, function(data){
alert("hi");
}, "json");
});
});
My form's id is "reply" and the button I am using to submit it is "reply-submit", just to make sure those things are clear.
It also doesn't work if I remove that last "json" thing btw.
If you read the docs for jQuery.post(), it says this about the callback:
success(data, textStatus, jqXHR)
A callback function that is executed if the request succeeds.
If it's not getting called, it means that request did not succeed. There is probably an error in newpost.php (sometime after the data insert, but before it would normally exit).
You can also catch error conditions by using the long-form jQuery.ajax() instead of the post shorthand:
$.ajax({
url: 'newpost.php',
data: formData,
type: 'post',
dataType: 'json',
success: function(data, textStatus, jqXHR) {
alert('success');
},
error: function(jqXHR, textStatus, errorThrown) {
alert('error!');
}
});
When you click, the form is also being submitted the standard way. Modify your click handler like this:
$(document).on('click', "#reply_submit", function(e) {
e.preventDefault(); // prevent the default submit event
var formData = $('#reply').serialize();
// ...
});
Although I think document.body should be a valid node to wrap in jQuery, I've also modified it to the more commonly used document.
On that note, if the form is never destroyed by an Ajax event or other DOM modification, you could bind to #reply instead of document (or body).
I'm simply assuming that you want to submit a form without reloading the whole page.
Based on that assumption, following code will serve the purpose.
$(document).ready(function(){
//on form submit event
$('form#reply').submit(function(){
$.post('newpost.php',$(this).serialize(),function(){
alert("Message or do something with the response data if you are expecting one");
});
//prevent default action
return false;
});
});
Please ignore the post if this is not the functionality you are looking for in your project.
I won't to write some values into database with ajax on submit event, after that I want to query the database (with ajax) once again to check for some response that will be written after the first ajax action. Last, if the response values are "ok" then I want to refresh the page, else I will make the query 2 secs latter till the response gets ok!
//Write into database form values on submit event
$('form').submit(function(){
$.post("submitForm.php", { "array": submitedArray});
//HOW to verify if submited values where well written into databse?
return false;
});
//ONLY after submit I want to query the database and based on the response values I will refresh the page every two seconds (if response values not good) or refresh only once (if values checked are good)
var refresh = setInterval(function(){
$.getJSON('someOtherScript.php', function(data){
$.each(data, function(index, value){
//Check values
});
});
}, 2000);
onComplete: function(){
setTimeout(function() {$("#ajaxResponse").fadeOut();}, 500);
}
Write this in your ajax function and that's it. It worked for me.
If I have this correctly, you are using ajax to submit the form and want to do the check on callback.
$.ajax({
url: '/path/to/file',
type: 'POST',
dataType: 'xml/html/script/json/jsonp',
data: {param1: 'value1'},
complete: function(xhr, textStatus) {
//called when complete
},
success: function(data, textStatus, xhr) {
//called when successful
// This is where you will do your get request to find the result you are looking for.
},
error: function(xhr, textStatus, errorThrown) {
//called when there is an error
}
});
Definitely don't use setInterval. setInterval will have that code execute EVERY 2 seconds, not just after 2 seconds. What you were looking for is setTimeout. But don't use that either.
have a look at
http://api.jquery.com/jQuery.post/
post can take a success parameter. This will let you run your 2nd bit of code only after the first completes.
Why not just have the initial submit code check the database write, if successful it returns a success code, otherwise it returns an error code. Either you trust ajax or you don't.