I'm having an issue with my update button and jquery ajax. Right now when I click on my update button, it saves whatever updated data to the database. My goal is I want to slide up a message if the update is successful. I was looking at ajax post and using the success event seems like it would work but I dont know how to incorporte it. How would I do this? Would it be something like this?
$(document).ready(function(){
$('#divSuccess').hide();
$('#btnUpdate').click( function() {
alert('button click');
$.ajax({
url: "test.aspx",
context: document.body,
success: function(){
$('#divSuccess').show("slide", { direction: "down" }, 3000);
$('#divSuccess').hide("slide", { direction: "down"}, 5000);
}
});
});
});
check out this question for an example on how to handle the success event. Hope this helps!
$("#targetDiv").load("page.php",$("#form").serializeArray(),function (response)
{
if (response == '0' && response != '')
alert('Request not sent to server !\n');
else if(response == '-1')
alert('Please write some more !\n');
else
{
alert("success! ");
}
}
);
i've echo ed 0 and -1 for failure and other for success
In the jquery post function, you can execute some callback function.
function (data, textStatus) {
// data could be xmlDoc, jsonObj, html, text, etc...
this; // the options for this ajax request
// textStatus can be one of:
// "timeout"
// "error"
// "notmodified"
// "success"
// "parsererror"
// NOTE: Apparently, only "success" is returned when you make
// an Ajax call in this way. Other errors silently fail.
// See above note about using $.ajax.
}
http://docs.jquery.com/Post
With at least jQuery 1.5, you've got deferred objects and new syntax for AJAX events (including success).
var $ajaxcall = $.ajax({
url : 'myurl.svc/somemethod',
data : '{ somedata : "sometext" }'
});
$ajaxcall.success(function() {
// do something on successful AJAX completion
});
Of course you can chain that as well, and call something along the lines of $.ajax().success() or something.
Just wrote a blog post on it myself, if you're interested in reading more.
Related
I am trying to make search function based on Ajax/Jquery.
My web app shows the data of service requests from the database. I want to make searchbar for my app as follows:
show all service request on the table initially.
If something is typed on the searchbar, it searches data and load those data to the table.
Finally if user deletes anyword from searchbar it will show all data as stated on No.1
I managed doing second and third function but I am having issues with the first one.
$(document).ready(function(){
$('#search_text').keyup(function(){
var txt = $(this).val();
if(txt != '') {
$.ajax({
url:"ajax/fetchRequests.php",
method:"post",
data:{search:txt},
dataType:"text",
success:function(data) {
$('#result').html(data);
}
});
}
else if(txt == '') {
$.get("ajax/readRequests.php", {}, function (data, status) {
$("#result").html(data);
});
}
});
});
Here is another script that i have worked on trying:
$(document).ready(function(){
var txt = $('#search_text').val();
if(txt != ''){
$.ajax({
url:"ajax/fetchRequests.php",
method:"post",
data:{search:txt},
dataType:"text",
success:function(data) {
$('#result').html(data);
}
});
}
else if(txt == '') {
$.get("ajax/readRequests.php", {}, function (data, status) {
$("#result").html(data);
});
}
});
All my features are working except for the search functions. Any tips or critics are welcome, thank you very much in advance.
I suggest you do two things, 1) use the suggested .on() and 2) use only one ajax function to simplify things. The idea is to funnel your calls through one function so that you know if something fails, it's not because you messed up the ajax part of the script:
// Create a generic ajax function so you can easily re-use it
function fetchResults($,path,method,data,func)
{
$.ajax({
url: path,
type: method,
data: data,
success:function(response) {
func(response);
}
});
}
// Create a simple function to return your proper path
function getDefaultPath(type)
{
return 'ajax/'+type+'Requests.php';
}
$(document).ready(function(){
// When the document is ready, run the read ajax
fetchResults($, getDefaultPath('read'), 'post', false, function(response) {
$('#result').html(response);
});
// On keyup
$(this).on('keyup','#search_text',function(){
// Get the value either way
var getText = $(this).val();
// If empty, use "read" else use "fetch"
var setPath = (!getText)? 'read' : 'fetch';
// Choose method, though I think post would be better to use in both instances...
var type = (!getText)? 'post' : 'get';
// Run the keyup function, this time with dynamic arguments
fetchResults($, getDefaultPath(setPath), type, { search: getText },function(response) {
$('#result').html(response);
});
});
});
To get initial results hook onto jQuery's document ready event.
var xhr;
var searchTypingTimer;
$(document).ready(function(){
// initial load of results
fetchResults([put your own params here]);
// apply on change event
$('#search_text').on('input', function() {
clearTimeout(typingTimer);
searchTypingTimer = setTimeout(fetchResults, 300);
});
});
function fetchResults($,path,method,data,func)
{
if (xhr && xhr.readyState != 4){
xhr.abort();
}
xhr = $.ajax({
url: path,
type: method,
data: data,
success:function(response) {
func(response);
}
});
}
As Rasclatt mentions you should use jQuery's on method to catch any changes.
Secondly I'd recommend disposing of previous requests when you make new ones, since if you are sending a new one on each character change then for one word many requests will be made. They won't necessarily arrive back in the order you send them. So for example as you type 'search term', the result for 'search ter' may arrive after and replace 'search term'. (welcome to async).
Thirdly since you will send many requests in quick succession I'd only call your fetchResults function after a short time out, so for example if a user types a five character word it doesn't fire until 300ms after the last character is typed. This will prevent 4 unnecessary requests that would just be ignored but put strain on your backend.
Im using the following function to call an ajax request, and fill certain corresponding divs with the response:
$( function() {
$(document).ready(function() {
var postData = "";
$.ajax( {
url : \'functions/ajax_api.php?\',
type : \'post\',
data : postData,
success : function( resp ) {
$(\'#id1\').html($(\'#id1\' , resp).html());
$(\'#id2\').html($(\'#id2\' , resp).html());
}
});
return false;
});
});
The function works fine. My question is how can I call it automatically every few seconds?
I tried using window.setTimeout(function, 3000) but I couldnt set it up correctly.
use setInterval(); instead of .setTimeout()
Let me help you a little bit with that
var interval , setItinterval; // just a variables you can change names
interval = function(){
// ajax code here
}
to run it .. use:
setItinterval = setInterval(interval , 3000);
to stop it .. use
clearInterval(setItinterval);
Make sure to read setInterval for more information.
For Complete answer and Last thing I want to say when using setInterval(); Its better to use visibilitychange to avoid server error , server load or something like that
document.addEventListener('visibilitychange',function(){
if(document.visibilityState == 'visible'){
// user view the page
}else{
// user not see the page
}
});
You can use setTimeout() or setInterval, but setInterval may result in multiple simultaneous ajax calls if those calls take too long to respond. That isn't a problem if you call setTimeout() in the ajax success callback.
To use setTimeout(), first wrap your ajax call in a function. You can then add a call to setTimeout() to the ajax success callback. You also need to call the function once to start of the looping.
$(function() {
function postData() {
var postData = "";
$.ajax({
url: 'functions/ajax_api.php?',
type: 'post',
data: postData,
success: function(resp) {
$('#id1').html($('#id1', resp).html());
$('#id2').html($('#id2', resp).html());
// Call postData again after 5 seconds.
setTimeout(function() { postData(); }, 5000);
}
});
}
// Call postDate the first time to start it off.
postData();
});
Note: With the call to setTimeout in the success callback, the cycle will break if an ajax call fails. You may want that, but if you want it to act more like setInterval, you can place the call to setTimeout in the complete callback.
Here's some example code that will do it (note that it runs the function when the document loads, and then starts the interval). You can always use clearInterval(refresh_interval) if you need to stop it.
var refresh_interval;
function update_content() {
$.ajax({
url : \'functions/ajax_api.php?\',
type : \'post\',
data : postData,
success : function( resp ) {
$(\'#id1\').html($(\'#id1\' , resp).html());
$(\'#id2\').html($(\'#id2\' , resp).html());
}
});
}
$(document).ready(function() {
update_content();
setInterval(update_content, 3000);
}
The relevant documentation for using intervals is here: https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval
Though you may want to look into Server Sent Events, it's probably a better solution for what you want.
Let's start from here - I have defined base setting for all future AJAX-requests, like this
$.ajaxSetup({
beforeSend : function(){
$("#ajax-loader").dialog({
modal : true
});
},
complete : function(){
$("#ajax-loader").dialog("hide");
}
});
Now, I have a form where my users can upload their bio and pictures. When a form is valid, then I allow to upload their pictures. It works this way:
$("#send").click(function(e){
e.preventDefault();
$.ajax({
data : $("#bio-form").serialize(),
url : "/validate.ajax",
success : function(response) {
// If AJAX-validator returns "1" then a form is valid
if (response == "1"){
// Now I start to upload photos, like
// this
var formData = new FormData(document.getElementById('upload-form'));
$.ajax({
processData : false,
contentType : false,
cache : false,
data : formData,
success : function(response) {
alert(response);
}
});
}
}
});
});
The problem
Once ajax-uploading starts, I expect a $("#ajax-loader") to be showed. On complete this should be closed automatically according to the settings I defined in $.ajaxSetup.
BUT...
It appears and disappears right after 1 sec on file uploading. I know that ajax request isn't completed, because I get successfuly message after 1-2 mins (that photos uploaded).
I tried to change async: false and it started to work as expected === a modal appears when uploading files to server and disappers when done:
data : formData,
async : false,
processData : false,
Question
Is it possble to do the same when async : true is set to its default mode(true)? I don't want a browser to be frozen when uploading in progress!
As you've discovered, Ajax is an asynchronous technology - meaning it runs on its own schedule
Making Ajax synchronous causes all sorts of problems (using async:false actually causes the browser to freeze whilst the request is performed)
There are several issues I'd mention you may want to fix:
Why Nested Ajax?
Nesting Ajax requests, in this current state of the web, is, in my opinion, bad practice. It generally means you've got something wrong with your system. Concurrent requests are fine - but nested I'd avoid like the plague
Ajax Callbacks
If you can get your Ajax requests down to a single entity, I'd look at using Ajax Callbacks to create your desired result
Ajax callbacks work by using Ajax as part of a function, where the success & error callbacks are handled by several differnt parts of your parent function. Here's an example:
function create_modal(o){
fetch_modal(o.ajax, function(data){
//do success stuff here
}, function(data){
//do error stuff here
});
}
function fetch_modal(link, success, error) {
$.ajax({
url: link,
success: function(data) { success(data); },
error: function(data) { error(data); }
});
}
The problem is ajaxSetup. You have to follow enable/disable method on uploading photo. Let me clearup the understanding. You want to show the loader to intimate the user that he/she has to wait until validation process finishes. Once the validation get success you are starting to upload file. While uploading file, you want to allow the user interact with page.
To achieve this you have to do as follows,
function ajaxSetup(mode) {
var options = {};
if (mode === "on") {
options = {
beforeSend : function() {
$("#ajax-loader").dialog({
modal : true
});
},
complete : function() {
$("#ajax-loader").dialog("hide");
}
};
} else {
options = {
beforeSend : function() {
},
complete : function() {
}
};
}
$.ajaxSetup(options);
}
And Make your ajax request as follows,
ajaxSetup("on");
$("#send").click(function(e) {
e.preventDefault();
$.ajax({
data : $("#bio-form").serialize(),
url : "/validate.ajax",
success : function(response) {
// If AJAX-validator returns "1" then a form is valid
if (response == "1") {
// Now I start to upload photos, like
// this
var formData = new FormData(document.getElementById('upload-form'));
ajaxSetup("off"); //Here second-time seem-less displaying of loader will be avoided.
$.ajax({
processData : false,
contentType : false,
cache : false,
data : formData,
success : function(response) {
alert(response);
}
});
ajaxSetup("on");
}
}
});
});
Note: I am not tested code. Please make sure, if any syntax or typo error.
I can't seem to get the .text() function to run properly in my function.
Every now and then, the page will display correctly but the majority of the time, the text does not change. The page starts with the <p> tag displaying 'Waiting', then the initial .text() in the beforeSend: works correctly and the text is changed to 'Processing request...', however from then on, the .text() function does not seem to work.
I have added in console.logs to see if the msg variable is being populated correctly and it is, but the .text() still isn't changing the <p> tag the second time around. It seems to be the same in all browsers.
This is my function:
function sendrequest(first, last, email) {
var request = $.ajax({
url:"/core/ajax/register.php",
type:"POST",
data: {uf:first,ul:last,ue:email},
beforeSend: function(){
forms.regFor.fadeOut(100, function(){
$('p#msg').text('Processing request...');
});
}
});
request.done(function(data){
var msg;
if (data == 1){
msg = "Thank you "+first+", your request has been sent.";
console.log('Registered successfully');
}else if (data == 2){
msg = "It appears that you have already signed up.";
console.log('Already signed up');
}else{
msg = "There has been an error.";
console.log('Error on submission');
}
console.log(msg);
$('p#msg').text(msg);
});
}
I've probably missed something very simple, just can't seem to see it at all, hopefully someone can.
Try removing the fadeOut in your beforeSend call.
In all likelyhood, the fadeOut isn't completing before the AJAX call does. So your AJAX done is triggered, then your fadeOut is completed and your fadeout callback takes place, destroying your AJAX done changes.
beforeSend: function(){
$('p#msg').text('Processing request...');
}
If you feel you must have the fadeOut, then put your AJAX call in the fadeOut callback.
forms.regFor.fadeOut(100, function(){
var request = $.ajax({
url:"/core/ajax/register.php",
type:"POST",
data: {uf:first,ul:last,ue:email},
beforeSend: function(){
$('p#msg').text('Processing request...');
}
});
request.done = // etc.
});
Is there a way to abort all Ajax requests globally without a handle on the request object?
The reason I ask is that we have quite a complex application where we are running a number of different Ajax requests in the background by using setTimeOut(). If the user clicks a certain button we need to halt all ongoing requests.
You need to call abort() method:
var request = $.ajax({
type: 'POST',
url: 'someurl',
success: function(result){..........}
});
After that you can abort the request:
request.abort();
This way you need to create a variable for your ajax request and then you can use the abort method on that to abort the request any time.
Also have a look at:
Aborting Ajax
You cannot abort all active Ajax requests if you are not tracking the handles to them.
But if you are tracking it, then yes you can do it, by looping through your handlers and calling .abort() on each one.
You can use this script:
// $.xhrPool and $.ajaxSetup are the solution
$.xhrPool = [];
$.xhrPool.abortAll = function() {
$(this).each(function(idx, jqXHR) {
jqXHR.abort();
});
$.xhrPool = [];
};
$.ajaxSetup({
beforeSend: function(jqXHR) {
$.xhrPool.push(jqXHR);
},
complete: function(jqXHR) {
var index = $.xhrPool.indexOf(jqXHR);
if (index > -1) {
$.xhrPool.splice(index, 1);
}
}
});
Check the result at http://jsfiddle.net/s4pbn/3/.
This answer to a related question is what worked for me:
https://stackoverflow.com/a/10701856/5114
Note the first line where the #grr says: "Using ajaxSetup is not correct"
You can adapt his answer to add your own function to window if you want to call it yourself rather than use window.onbeforeunload as they do.
// Most of this is copied from #grr verbatim:
(function($) {
var xhrPool = [];
$(document).ajaxSend(function(e, jqXHR, options){
xhrPool.push(jqXHR);
});
$(document).ajaxComplete(function(e, jqXHR, options) {
xhrPool = $.grep(xhrPool, function(x){return x!=jqXHR});
});
// I changed the name of the abort function here:
window.abortAllMyAjaxRequests = function() {
$.each(xhrPool, function(idx, jqXHR) {
jqXHR.abort();
});
};
})(jQuery);
Then you can call window.abortAllMyAjaxRequests(); to abort them all. Make sure you add a .fail(jqXHRFailCallback) to your ajax requests. The callback will get 'abort' as textStatus so you know what happened:
function jqXHRFailCallback(jqXHR, textStatus){
// textStatus === 'abort'
}