show html element before sending ajax sync request - javascript

I want to show <div> on click by submit before sending $.ajax()
my html
<div id="waiting_div"></div>
css
#waiting_div {
position: fixed;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, .8);
z-index: 999;
display: block;
}
js functions
jQuery(document).ready(function() {
jQuery("#waiting_div").hide();
});
function set_response_waiting() {
jQuery("#waiting_div").show();
}
function del_response_waiting() {
jQuery("#waiting_div").hide();
}
and main js
jQuery("#save_changed_prices").click(function(){
set_response_waiting(); <-- showing div here
var len = window.prices.length; //array with data for sending
var i = 0;
for (i = 0; i < len; i++) {
if (window.prices[i].price >= 0) {
jQuery.ajax({
type: 'POST',
url: ajaxurl,
data: {...... },
async: false
}).done(function (data) {
...
}).fail(function () {
...
}).always(function () {
...
});
}
}
del_response_waiting(); <-- hiding div
});
But set_response_waiting() function doesn't show me my "#waiting_div" before sending.
I need to redraw or update the DOM tree before sending. But how?
This don't work too..
jQuery.ajax({
type: 'POST',
url: ajaxurl,
data: {
'action': 'update_price',
'car_id': car_id,
'dep_city_id': window.prices[i].dep,
'arr_city_id': window.prices[i].arr,
'price': window.prices[i].price
},
beforeSend: set_response_waiting(),
async: false
})

Ajax is asynchronous as you are probably aware of, so in your function JS will go straight from set_response_waiting() to del_response_waiting(); AJAX is not performed 'in series here'; try:
jQuery("#save_changed_prices").click(function(){
var len = window.prices.length; //array with data for sending
var i = 0;
for (i = 0; i < len; i++) {
if (window.prices[i].price >= 0) {
jQuery.ajax({
type: 'POST',
url: ajaxurl,
data: {...... },
async: false
}).done(
function (data) {
del_response_waiting(); //<-- hiding div
...
}
).fail(function () {
...
}
).always(set_response_waiting()); //<-- showing div here
}
}
});

Use, Promise.
jQuery ajax is aync method. so your function show and immediately hide.
jQuery("#save_changed_prices").click(function(){
set_response_waiting(); <-- showing div here
var len = window.prices.length; //array with data for sending
var i = 0;
var deferreds = [];
for (i = 0; i < len; i++) {
if (window.prices[i].price >= 0) {
deferreds.push(
jQuery.ajax({
type: 'POST',
url: ajaxurl,
data: {...... },
async: false
}).done(
function (data) {
...
}
).fail(function () {
...
}
).always(function () { ...
});
);
}
}
// pending until all ajax requests done.
$.when.apply(null, deferreds).done(function() {
del_response_waiting(); <-- hiding div
});
});
--- EDIT
jQuery("#save_changed_prices").click(function(){
set_response_waiting(); <-- showing div here
var len = window.prices.length; //array with data for sending
var i = 0;
var deferreds = [];
for (i = 0; i < len; i++) {
var deferred = $.Deferred();
deferreds.push(deferred.promise());
if (window.prices[i].price >= 0) {
jQuery.ajax({
type: 'POST',
url: ajaxurl,
data: {...... },
async: false
}).done(
function (data) {
...
}
).fail(function () {
...
}
).always(function () {
deferred.resolve(); // Resolve here!
...
});
);
}
}
// pending until all ajax requests done.
$.when.apply(null, deferreds).done(function() {
del_response_waiting(); <-- hiding div
});
});
---- EDIT (last)
jQuery("#save_changed_prices").click(function(){
var send_price = function() {
var deferreds = [];
var len = window.prices.length; //array with data for sending
var i = 0;
for (i = 0; i < len; i++) {
if (window.prices[i].price >= 0) {
deferreds.push(
jQuery.ajax({
type: 'POST',
url: 'http://jsonplaceholder.typicode.com/posts',
data: { price : window.prices[i].price },
async: false
}).done(function (data) {
console.log('done', data);
}).fail(function () {
console.error(done, data);
}).always(function () {
})
);
}
}
$.when.apply(null, deferreds).done(function() {
del_response_waiting();
});
}
set_response_waiting();
setTimeout(send_price); // setTimeout for browser redraw screen!!
});
Check jsfiddle for working example. :)
https://jsfiddle.net/yourimiyi/rsu4vo3m/

Like rsn said in first answer it happens but you can't solve it this way.
Here I set 2sec timeouts so you can see how it happens (I changed your code a bit just for testing purpose):
jQuery("#save_changed_prices").click(function() {
$('#waiting_div').show();
setTimeout(function(){
jQuery.ajax({
type: 'POST'
}).done(
function(data) {
$('#waiting_div').html('show after ajax submit');
setTimeout(function(){
$('#waiting_div').hide();
}, 2000);
}
).fail(function() {}).always(function() {});
}, 2000);
});
You can check example of it here https://jsfiddle.net/1e4xscn8/2/

Related

Ajax is not aborting when stop button is clicked

I have this code, and when the stop button is clicked, I need to stop the ajax, but for some reason ajax is not aborting.
var started = false;
$(document).ready(function () {
$('#start').click(function () {
var count = $("#names").val();
var line = count.split("\n");
started = true;
line.forEach(function(value, index) {
setTimeout(
var ajaxCall = $.ajax({
url: url,
type: 'GET',
data: someData,
success: function(result) {
//some works here
}
});
$('#stop').click(function () {
ajaxCall.abort(); //abort Ajax
$('#check').attr('disabled', false);
$('#stop').attr('disabled', 'disabled');
})
}, 2000 * index);
});
});
});

Error : Uncaught TypeError: this.source is not a function

I tried to create Autocomplete using jQuery Ajax. Basically, I want to make autocomplete search with dynamic field added. But while I type in the input field then it gave me this error.
JS Code
$(document).ready(function() {
var arrayReturn = []
$.ajax({
url: "/suppliers",
async: true,
dataType: 'json',
success: function(data) {
for (var i = 0; i < data.length; i++) {
var id = (data[i].id).toString();
arrayReturn.push({'value' : data[i].name, 'data' : id})
}
printSupplier(arrayReturn);
}
});
function printSupplier(suppliers) {
$('#purchase_item_search').autocomplete({
lookup: suppliers,
onSelect: function (result) {
$('#autocom-box').html(result.value);
}
});
}
});
Problem Solved.
$(document).ready(function() {
$("#purchase_item_search").on('keyup', function() {
var arrayReturn = []
$.ajax({
url: "/suppliers",
dataType: 'json',
success: function(data) {
// console.log(data['suppliers'].length);
for (var i = 0; i < data['suppliers'].length; i++) {
var id = (data['suppliers'][i].id).toString();
arrayReturn.push({
'value': data['suppliers'][i].name,
'data': id
})
}
printSupplier(arrayReturn);
}
});
function printSupplier(options) {
$('#purchase_item_search').autocomplete({
source: options,
onSelect: function(result) {
// $('#autocom-box').html(result.value);
console.log(result);
}
});
}
});
});

Only one alert for multiple execution in Ajax

I am working rails application.i need to get status of the each selected device.I am able to achieve this but after executing i am putting alert "Successfully created execution record".For every mac selection it is showing alert message.I need to give one alert in end of execution.I am calling display_result in call_endpoint method.Since it is an Ajax call,it is giving alert for every execution.i don't how to limit to single alert for this.
function display_result() {
$('#http_status').html("");
$('#http_status').append(result["response"].status);
if (result["response"].status == "404") {
console.log("HTTP 404");
$('#response_div').addClass("bs-callout-warning");
} else if (result["response"].status == "520") {
console.log("HTTP 502");
$('#response_div').addClass("bs-callout-danger");
} else {
console.log("HTTP 200");
$('#response_div').addClass("bs-callout-success");
if (result["response"].status == "200") {
// $('.loader').show();
$('#cover-spin').show();
$.ajax({
method: "GET",
dataType: "text",
url: "create_execution",
data: {
http_status: result["response"].status,
mac_address: mac,
},
success: function (execution_record_id) {
$('#cover-spin').hide();
alert('Successfully created execution record");
}
});
}
function call_endpoint() {
var values = new Array();
webpa = $('#Device-PA').is(":visible");
rpil = $('#Device-SN').is(":visible");
groupselect = $('#Group-Select').is(":visible");
parameter_name = $('#tr_object').val();
if (webpa) {
$.each($("input[name='checkBox[]']:checked").closest("td").next("td"), function () {
values.push($(this).text().trim())
});
m = values.length
} else {
$.each($("input[name='checkBox[]']:checked").closest("td").next("td"), function () {
values.push($(this).text().trim())
});
m = values.length
}
serialnumber = $('#pa_serialnumber').val();
oid = $('#sn_serialnumber').val();
protocol = {
pa: pa,
sn: sn,
}
if (pa) {
for (var i = 0; i < m; i++) {
(function () {
var macAdd = values[i];
$.ajax({
method: "GET",
url: "get_object",
dataType: "json",
data: {
parameter: parameter_name,
mac: macAdd,
protocol: protocol,
serialnumber: serialnumber,
},
success: function (result) {
console.log(result);
NProgress.done();
console.log("result for webpa");
display_result();
},
statusCode: {
404: function () {
console.log("Call failed");
}
}
});
})();
}
}
Below is changed code..
Copy below code as it is.
function display_result(total,current) {
$('#http_status').html("");
$('#http_status').append(result["response"].status);
if (result["response"].status == "404") {
console.log("HTTP 404");
$('#response_div').addClass("bs-callout-warning");
} else if (result["response"].status == "520") {
console.log("HTTP 502");
$('#response_div').addClass("bs-callout-danger");
} else {
console.log("HTTP 200");
$('#response_div').addClass("bs-callout-success");
if (result["response"].status == "200") {
// $('.loader').show();
$('#cover-spin').show();
$.ajax({
method: "GET",
dataType: "text",
url: "create_execution",
data: {
http_status: result["response"].status,
mac_address: mac,
},
success: function (execution_record_id) {
$('#cover-spin').hide();
if(total == current)
{
alert('Successfully created execution record");
}
}
});
}
}
}
function call_endpoint() {
var values = new Array();
webpa = $('#Device-PA').is(":visible");
rpil = $('#Device-SN').is(":visible");
groupselect = $('#Group-Select').is(":visible");
parameter_name = $('#tr_object').val();
if (webpa) {
$.each($("input[name='checkBox[]']:checked").closest("td").next("td"), function () {
values.push($(this).text().trim())
});
m = values.length
} else {
$.each($("input[name='checkBox[]']:checked").closest("td").next("td"), function () {
values.push($(this).text().trim())
});
m = values.length
}
serialnumber = $('#pa_serialnumber').val();
oid = $('#sn_serialnumber').val();
protocol = {
pa: pa,
sn: sn,
}
if (pa) {
for (var i = 1; i <= m; i++) {
(function () {
var macAdd = values[i];
$.ajax({
method: "GET",
url: "get_object",
dataType: "json",
data: {
parameter: parameter_name,
mac: macAdd,
protocol: protocol,
serialnumber: serialnumber,
},
success: function (result) {
console.log(result);
NProgress.done();
console.log("result for webpa");
display_result(m,i);
},
statusCode: {
404: function () {
console.log("Call failed");
}
}
});
})();
}
}
}
result and mac is not defined in display_result function. result appears intended to be the resulting value of jQuery promise object returned from $.ajax(). Am not certain what mac is indented to be.
You can substitute $.when() and $.map() for for loop, return a jQuery promise object from call_endpoint(), include error handling, chain .then() to call_endpoint() call to execute alert() once.
function call_endpoint() {
return $.when.apply($, $.map(values, function(macAdd) {
return $.ajax().then(display_result)
}))
}
callEnpoint()
.then(function() {
alert('Successfully created execution record');
}, function(jqxhr, textStatus, errorThrown) {
console.error(errorThrown)
});
function display_result(reuslt) {
..
if (if (result["response"].status == "200")) {
return $.ajax() // remove `alert()` from `success`
}
return;
}

How to wait untill for (append) finished and then show result javascirpt / jquery

I have a function that renders 5 images, and pagination. This function used ajax for getting data.
It works well, but when I using the pagination, I can see the process of 'creating' HTML.
I want to add a loading.gif, until all the HTML finished loading, and show all the results
function getImages(init, buttonPaging) {
var data = {};
if (init) {
data["int"] = "1";
} else {
data["int"] = $(buttonPaging).text();
}
$.ajax({
type: "POST",
url: '#Url.Action("GetImages", "Image")',
data: JSON.stringify(data),
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val());
},
contentType: "application/json",
dataType: "json",
success: function (data) {
if (data.success) {
$('#imgList').children().remove();
for (var i = 0; i < data.imageList.length; i++) {
(function (img) {
$('#imgList').append(drawList(img, data.baseUrl));
})(data.imageList[i]);
}
$('#pagingList').children().remove();
for (var i = 0; i < data.pagingInfo.totalPages; i++) {
(function (paging) {
var isCurrentPage = false,
index = i;
index++;
if (paging.currentPage == index) {
isCurrentPage = true;
}
$('#pagingList').append(drawPaging(index, isCurrentPage));
})(data.pagingInfo);
}
} else {
errors += data.error;
}
},
error: function () {
errors += 'Please contact with administrator - img list at edit product';
alert(errors);
}
});
}
I saw tutorials about promises and callbacks, but I'm not good at it and I don't know how to rewrite my code for those. Is there another way to solve the issue ?
solution: It may come in handy for other:
function hideLoader() { setTimeout(function () { $('.loader-sm').hide(); }, 750); }
function showLoader() { $('.loader-sm').show(); }
function hideList() { $('#imgList').hide(); }
function showList() { setTimeout(function () { $('#imgList').show(200); }, 750); }
success: function () {
if (data.success) {
//do something
} else {
showList();
hideLoader();
}
},
error: function () {
showList();
hideLoader();
},
complete: function () {
showList();
hideLoader();
}
have a class for show loading image icon and place it in the block itself and hide it once completed. have a look at the below sample. it may helpful to you.
beforeSend: function() {
$('#imgList').addClass('loading');
},
success: function(data) {
$("#imgList").removeClass('loading');
},
error: function(xhr) { // if error occured
$("#imgList").removeClass('loading');
},
complete: function() {
$("#imgList").removeClass('loading');
}
otherwise you can have a loader div block show the block on beforesend() and hide it in success / complete.
You can do like this i am not sure about but it will help you
function getImages(init, buttonPaging) {
var data = {};
if (init) {
data["int"] = "1";
} else {
data["int"] = $(buttonPaging).text();
}
let promise = new Promise(function(resolve, reject) {
//add your code for add loading.gif
$.ajax({
type: "POST",
url: '#Url.Action("GetImages", "Image")',
data: JSON.stringify(data),
beforeSend: function (xhr) { xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val()); },
contentType: "application/json",
dataType: "json",
success: function (data) {
if (data.success) {
$('#imgList').children().remove();
for (var i = 0; i < data.imageList.length; i++) {
(function (img) {
$('#imgList').append(drawList(img, data.baseUrl));
})(data.imageList[i]);
}
$('#pagingList').children().remove();
for (var i = 0; i < data.pagingInfo.totalPages; i++) {
(function (paging) {
var isCurrentPage = false,
index = i;
index++;
if (paging.currentPage == index) { isCurrentPage = true; }
$('#pagingList').append(drawPaging(index, isCurrentPage));
})(data.pagingInfo);
}
resolve();
} else {
errors += data.error;
resolve();
}
},
error: function () {
errors += 'Please contact with administrator - img list at edit product';
alert(errors);
resolve();
}
});
}
promise.then(
result => alert("done"), // remove loading.gif
);
}

Jquery Deferred + Ajax

Can anyone tell me why this will not update the data object in the AJAX? If I have multiple features in the geojson, it tends to only save one of the features records when looping through all the geojson features. So if geojsonFeatures has 3 records, 3 records will be pushed into ajaxDeferred but the data will be the same for all three records.
data: {
id: updatedLayerGeojsonId,
table: updatedLayerGeojsonTable,
geom: updatedLayerGeojsonGeometry
}
var geojsonFeatures = geojson.features;
var ajaxDeferred = [];
for(var a = 0; a < geojsonFeatures.length; a++){
updatedLayerGeojson = geojsonFeatures[a].geometry;
updatedLayerGeojson.crs = {
"type": "name",
"properties": {
"name": "epsg:4326"
}
};
updatedLayerGeojsonGeometry = JSON.stringify(updatedLayerGeojson);
updatedLayerGeojsonId = geojsonFeatures[a].properties.gid;
updatedLayerGeojsonTable = geojsonFeatures[a].properties.layer_table;
ajaxDeferred.push(
$.ajax({
url: window.location.origin + '/csrfToken',
success: function(response) {
$.ajax({
url: '/maplayers/saveEditedLayerRecord',
type:"post",
data: {
id: updatedLayerGeojsonId,
table: updatedLayerGeojsonTable,
geom: updatedLayerGeojsonGeometry
},
beforeSend: function(xhr, settings){
xhr.setRequestHeader('X-CSRF-Token', response._csrf);
},
success: function(data){
if(data){
numberOfEditedLayersCompleted++;
if(numberOfEditedLayers == numberOfEditedLayersCompleted){
removeLayers();
editableLayers.clearLayers();
editedLayer = false;
numberOfEditedLayers = 0;
numberOfEditedLayersCompleted = 0;
}
}
},
cache: false
});
}
})
);

Categories

Resources