Home > Blockchain >  Why is my button updating only at the end of the "each" loop?
Why is my button updating only at the end of the "each" loop?

Time:11-23

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 runned. 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  name="UpdateRFID" id="UpdateRFID" value="Update" type="button" />

Update 1: No sure why I'm getting Down voted... I'm trying to get help.

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. Google didn't help me.

  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");
  }

Update #2 : 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 >SKU</p> <input  type="text" id="SKU" name="SKU" onclick="BoxSelect(this.id);" />
    <script type="text/javascript">
        $('#SKU').focus();
    </script>

    <br><input  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 ><input  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"  type="button" value="X" style="background-color:gray; color:black">';
                        $('#ScannedSKU > tbody:last-child').append('<tr  submitted="0" sku="'   sku   '"><td >'   delBtn   '</td><td >'   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);
}
?>

CodePudding user response:

Update #4 : SOLVED.

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!

 $("#UpdateRFID").click(function() {
    $('#UpdateRFID').prop("disabled", true).prop("value", "Recherche ...");
    setTimeout(UpdateRFID, 100);
  });

Note that setTimeout(UpdateRFID(), 100); dosent work. Not sure why.

CodePudding user response:

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.

$('#SKU').focus();

function SkuCount() {
  let skucount = $('#ScannedSKU').find('.skurow').length - 1;
  let stritem = 'item'   !!skucount ? 's' : '';
  let updateText = skucount == 0 ? '' : 'Total '   stritem   ': '   skucount;
  $('#qtsku').html(updateText);
}

$('#ScannedSKU').on('click', '.delButton', function() {
  let sku = $(this).closest("tr").find('.skudesc').text();
  let r = confirm('Effacer '   sku   ' ?');
  if (!!r) {
    $(this).closest("tr").remove();
  }
  SkuCount();
  $('#SKU').focus();
});

$(document.body).on('keypress', function(event) {
  let keycode = event.keyCode ? event.keyCode : event.which;
  if (keycode == '13') {
    const skuContainer = $('#ScannedSKU').find('.sku-container');
    const skuList = skuContainer.find('.skurow');
    let sku = this.value.trim(); //?????
    this.value = "";
    if (!!sku && !skuList.filter('[data-sku="'   sku   '"]').length) {
      let newtr = $('#newrows').find('.skurow').first().clone();
      newtr.data('sku', sku);
      newtr.find('skudesc').html(skudesc);
      skuContainer.append(newtr);
      $("#btnsubmit").prop("disabled", true);
      SkuCount();
    }
  }
});

function UpdateRFID() {
  $('#UpdateRFID').trigger("disable-me");
  alert('Start');
  const myPromise = new Promise((resolve, reject) => {
    $('.skurow[submitted="0"]')
      .each(function() {
        let sku = $(this).data('sku');
        const skuData = {
          "action": "GetDataFromTagID",
          "tagid": sku
        };
        $.ajax({
            url: 'class.action.php',
            type: 'post',
            dataType: 'JSON',
            data: skuData
          })
          .done(function(response) {
            console.log('ok');
          })
          .fail(function(response) {
            console.log(response.responseText);
          });
      });
    resolve("looperdone");
  });

  myPromise
    .then(function() {
      alert('Done');
    })
    .then(function() {
      $('#UpdateRFID').trigger("enable-me");
    });
}

// this was missing so this is just an empty function
function SubmitVE() {}
$('#btnsubmit').on('click', SubmitVE);

$("#UpdateRFID")
  .on('click', UpdateRFID)
  .on('enable-me', function() {
    $(this).prop("disabled", false).prop("value", "Mise a jour nom RFID");
  }).on('disable-me', function() {
    $(this).prop("disabled", true).prop("value", "Recherche ...");
  });

SkuCount();
.delButton {
  background-color: gray;
  color: black;
}

.element-container {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p >SKU</p>
<input  type="text" id="SKU" name="SKU" />
<input  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 class='sku-container'>
      <!-- updated by JavaScript -->
    </tbody>
  </table>
</div>
<div ><input  id="btnsubmit" type="button" value="Soumettre" disabled></div>

<div >
  <table id="newrows">
    <tbody>
      <tr  submitted="0" sku="">
        <td ><button name="delButton"  type="button">X</button></td>
        <td ></td>
      </tr>
      <tbody>
  </table>
</div>

  • Related