I’m trying to figure why/how can I make the button text update before the "each" loop, so I can provide feedback to the users while it’s running… but it only seems to update after the "each" has completed.
In my example, the button will go "Updating please wait…" after the each has run. So if it take 10s, the button stay enable and with the text "Update" (original value). I want it to be disable and display "Updating please wait …" while the Loop (each) is running.
Got an idea why?
$("#UpdateRFID").click(function() {
$('#UpdateRFID').prop("disabled", true).prop("value", "Updating please wait...");
UpdateRFID();
//$('#UpdateRFID').prop("disabled", false).prop("value", "Update");
});
function UpdateRFID() {
$('.skurow[submitted="0"]').each(function() {
sku = $(this).attr('sku');
$.ajax({
url: 'class.action.php',
type: 'post',
async: false,
dataType: 'JSON',
data: {
"action": "GetDataFromTagID",
"tagid": sku
},
success: function(response) {
console.log('ok');
},
error: function(response) {
console.log(response.responseText);
}
});
});
}
Button :
<input class="MenuButton" name="UpdateRFID" id="UpdateRFID" value="Update" type="button" />
Here’s another test I did. In this Example, when I click the button, I get an alert "Start", then it wait for about 3 secondes (sleep in the PHP Code for testing), then I get the alert "Done", then the button is disable and change to "Recherche …". I’m not sure why… I want it to be disable before the "each" start.
function UpdateRFID() {
$("#UpdateRFID").prop("disabled", true).prop("value", "Recherche ...");
alert("Start");
$('.skurow[submitted="0"]').each(function () {
sku = $(this).attr("sku");
$.ajax({
url: "class.action.php",
type: "post",
async: false,
dataType: "JSON",
data: {
action: "GetDataFromTagID",
tagid: sku,
},
success: function (response) {
console.log("ok");
},
error: function (response) {
console.log(response.responseText);
},
});
});
alert("Done");
//$('#UpdateRFID').prop("disabled", false).prop("value", "Mise a jour nom RFID");
}
Here’s the full code standalone code to reproduce the problem:
jQuery is 2.2.1
PHP is 5.4 (but I don’t think it’s relevant)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="includes/jquery.min.js"></script>
<title>Document</title>
</head>
<body>
<p class="ScanText">SKU</p> <input class="FullSizeBox" type="text" id="SKU" name="SKU" onclick="BoxSelect(this.id);" />
<script type="text/javascript">
$('#SKU').focus();
</script>
<br><input class="MenuButton" name="UpdateRFID" id="UpdateRFID" value="Mise a jour nom RFID" type="button" />
<div id="qtsku" style="margin-left:5px">-</div>
<div id="divSKUScanned">
<table id="ScannedSKU">
<thead>
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<!-- updated by JavaScript -->
</tbody>
</table>
</div>
<div class="ScanSubmit"><input class="MenuButton" id="btnsubmit" type="button" value="Soumettre" onclick="SubmitVE();" disabled></div>
<script>
function SkuCount() {
skucount = $('#ScannedSKU tr').length - 1;
stritem = 'item';
if (skucount > 1) {
stritem = 'items';
}
$('#qtsku').html('Total ' + stritem + ': ' + skucount);
if (skucount == 0) {
$('#qtsku').html('');
}
}
SkuCount();
$(document.body).on('click', '.delButton', function() {
sku = $(this).closest("tr").find('.skudesc').text();
r = confirm('Effacer ' + sku + ' ?');
if (r == true) {
$(this).closest("tr").remove();
}
SkuCount();
$('#SKU').focus(); //TODO: That Focus dosent work...
});
$('#SKU').keypress(function(event) {
keycode = (event.keyCode ? event.keyCode : event.which);
if (keycode == '13') {
sku = this.value;
sku.trim();
this.value = "";
if (sku != "") {
if (!($('.skurow[sku="' + sku + '"').length)) {
delBtn = '<input name="delButton" id="delButton" class="delButton" type="button" value="X" style="background-color:gray; color:black">';
$('#ScannedSKU > tbody:last-child').append('<tr class="skurow" submitted="0" sku="' + sku + '"><td class="delbtn">' + delBtn + '</td><td class="skudesc">' + sku + '</td></tr>');
$("#btnsubmit").prop("disabled", true);
SkuCount();
}
}
}
});
$("#UpdateRFID").click(function() {
UpdateRFID();
});
function UpdateRFID() {
$('#UpdateRFID').prop("disabled", true).prop("value", "Recherche ...");
alert('Start');
$('.skurow[submitted="0"]').each(function() {
sku = $(this).attr('sku');
$.ajax({
url: 'class.action.php',
type: 'post',
async: false,
dataType: 'JSON',
data: {
"action": "GetDataFromTagID",
"tagid": sku
},
success: function(response) {
console.log('ok');
},
error: function(response) {
console.log(response.responseText);
}
});
});
alert('Done');
//$('#UpdateRFID').prop("disabled", false).prop("value", "Mise a jour nom RFID");
}
</script>
</body>
</html>
and this is the php page section for class.action.php
<?php
if ($_POST["action"] == "GetDataFromTagID") {
sleep(3);
}
?>
3
Answers
Update #4 : Patched This is working, but the final solution is in the Update #5.
Thanks to @freedomn-m , I only added a little timeout and it fixed it. Wish I could do "update the button then do this", but if it's working like this, I'm OK with it!
Note that
setTimeout(UpdateRFID(), 100);
dosent work. Not sure why.What you have may work; or may not over time.
What you should do is use a
Promise
and after all the loop and ajax is done you can resolve that.This is not a tested solution nor is this super solid. I did add a few things like how to enable and disable the button based on a custom event trigger, how to wrap the Promise in the function
UpdateRFID
etc.I removed
onclick="BoxSelect(this.id);"
because seeing a click on a text input is just weird and it did not exist in the code; And, you can add a click handler in the JavaScript code (better) with$('#SKU').on('click',function(){BoxSelect(this.id);});
I do see a lot of other things I would probably change but just the Promise is what you need to focus on here.
Update #5 : SOLVED
This is how my final code is. I manage to use the function
$.when
to run all my ajax request and then do actions. Now my button update correctly and I also manage to get ride of theasync: false
that is way better. My page update evertime an "ajax" call is resolved and at the end of all ajax call (done or fail), I re-enable the button.Thanks for all the help here. Helped me to go into the right direction! 🙂