Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pause function execution until another function returns

I am wanting to replace Magento's implementation of the alert() and confirm() dialog boxes. While the alert() replacement was trivial, I am unsure of how to handle the confirm() dialog. Is there a way to prevent JavaScript from continuing until a function is returned? Will this require looping that could crash a browser?

So for example, I need to replace code like this:

<form action="" method="POST">
   <input type="submit" onclick="return confirm('Are you sure?');" value="Delete">
</form>

with...

<form action="" method="POST">
   <input type="submit" onclick="return myCustomConfirm('Are you sure?');" value="Delete">
</form>

Or other scenarios such as:

<script>
   var delete = confirm('Are you sure?');
   if (delete) {
       doSomething();
   }
</script>

with...

<script>
   var delete = myCustomConfirm('Are you sure?');
   if (delete) {
       doSomething();
   }
</script>

In both scenarios, myCustomConfirm() will open a Bootstrap modal where the user must click "Okay", "Cancel", or close the modal. The value returns true if "Okay" and false if otherwise.

I don't want to do callbacks as that will cause more refactoring than desirable. Is this possible to do in another way?

Thanks!

like image 268
Kerry Ritter Avatar asked Jul 01 '26 08:07

Kerry Ritter


2 Answers

It is not possible. You cannot write a JavaScript function that blocks execution, gathers user input and returns a value based on user input. The only way to block execution and wait for user input is to use confirm.

You have to refactor your code to use callbacks if you want to use custom dialogs.

See Emulate Javascript 'alert' blocking nature

like image 114
Juan Mendes Avatar answered Jul 02 '26 23:07

Juan Mendes


You can do something similar to this using async/await which is part of ES7.

async function stepTwo()
{
  return new Promise((resolve) =>
  {
    let stop = false;
    $('input[type=checkbox]').one('change', (event) =>
    {
      // Will only stop the loop when the checkbox is checked
      if (event.target.checked === true)
      {
        stop = true;
      }
    });
    loop();

    // Continues looping until stop is set to true (i.e. input has been done)
    function loop()
    {
      if (stop === true)
      {
        resolve();
        return;
      }

      // Keeps checking if stop is true
      setTimeout(loop, 100);
    }
  });
}

async function stepOne()
{
  $('div').text('Waiting for input..');
  // Waits for promise returned from stepTwo() to resolve
  await stepTwo();
  $('div').text('Input checked!');
}

// Starts the async function (any lines below this continue execution)
stepOne();

Fiddle: https://jsfiddle.net/1rvn5bfp/7/

like image 27
Jeremy Smith Avatar answered Jul 02 '26 21:07

Jeremy Smith



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!