Home > front end >  How do I convert JavaScript confirm to HTML5 button actions?
How do I convert JavaScript confirm to HTML5 button actions?

Time:07-01

I have the following code:

if(changedStatus()){
    var mAns = confirm("You have changed your status. This will alter your estate plan and may cause you to lose some data. Are you sure that you want to do this?");
    if(!mAns) return false; 
}

This works great with the default JS confirm pop-up, but I would like to implement the same action with HTML5 buttons instead:

<div id="cres_statusmssg">
  <p>Changing your status will alter your estate plan and may cause you to lose some data. Do you want to proceed?</p>
   <button id="cres_yes">Yes</button>
   <button id="cres_cancel">Cancel</button>

I have applied click events to both buttons, but I can't get them to work. Any ideas?

CodePudding user response:

You'll need to understand how to write for asynchrony, since there is no other way to achieve what you want to do. The built-in confirm (and prompt, alert etc) effectively pause JS execution until the user has interacted with the pop-up

Writing nicer pop-ups, you don't have that luxury. You'll need to use callbacks to achieve a working solution

I'd recommend using Promises - which are just glorified callbacks anyway, with the added advantage of being able to be used with async/await - this has the advantage of making the code look more like the code you're used to if you haven't done much asynchronous coding

function statusmssgDialog() {
  const dlg = document.getElementById('cres_statusmssg');
  dlg.showModal();
  return new Promise((resolve, reject) => {
    const clk = function(e) {
      resolve(this.dataset.value === 'true');
      dlg.close();
    };
    dlg.querySelectorAll('button').forEach(btn =>
      btn.addEventListener('click', clk, { once: true})
    );
  });
}



// usage - it's easier if the function where you
//    call statusmssgDialog is `async`
//    but you can also use Promise.then/.catch of course
//
async function fn() {
  if( true /*changedStatus()*/){
    const mAns = await statusmssgDialog();
    console.log(`user action is ${mAns}`);
    if(!mAns) return mAns;
  }
  console.log('doing more things here when yes is clicked or chengedStatus is false?');
}



// asynchrony is like a virus, 
// anything that calls an asynchronous function and needs the result
// needs to be written to account for asynchrony
// here, I use .then/.catch instead of async/await
// because await isn't an option at the top-level of code
// unless it's the top-level of a module script in modern browsers 
fn().then(r => {
  if (r === false) {
    console.log('cancel was clicked');
    return;
  }
  console.log('yes was clicked');
});
.modal-dialog {
  border-radius: 9px;
  box-shadow: 0 0 1em rgb(127 127 127 / 0.8);
  width: 30rem;
  max-width: 90%;
}

.modal-dialog::backdrop {
  background: rgb(0 0 0 / 0.4);
  backdrop-filter: blur(1px);
}
body {
  background-color: hsl(240 100% 95%);
}
<dialog id="cres_statusmssg" >
  <div>
    <p>Changing your status will alter your estate plan and may cause you to lose some data. Do you want to proceed?</p>
    <button id="cres_yes" data-value="true">Yes</button>
    <button id="cres_cancel" data-value="false">Cancel</button>
  </div>
</dialog>

<div>
  <p>Dummy page text</p>
<div>

In the above, the dialog promise always resolves, but there is an alternative, to reject if cancel is pressed

function statusmssgDialog() {
  const dlg = document.getElementById('cres_statusmssg');
  dlg.showModal();
  return new Promise((resolve, reject) => {
    const clk = function(e) {
      dlg.close();
      if (this.dataset.value !== 'true') {
        return reject('cancel pressed');
      }
      resolve('yes pressed');
    };
    dlg.querySelectorAll('button').forEach(btn =>
      btn.addEventListener('click', clk, { once: true})
    );
  });
}

async function fn() {
  if( true /*changedStatus()*/) {
    try {
      const mAns = await statusmssgDialog();
      console.log(`yes pressed`);
    } catch(e) {
      console.log('cancel was pressed');
      throw e; // pass the cancel "error" to the caller
    }
  }
  console.log('doing more things here when yes is clicked or chengedStatus is false?');
}

fn().then(r => {
  console.log('yes was clicked');
}).catch(e => {
  console.log(`user action was ${e}`);
});
.modal-dialog {
  border-radius: 9px;
  box-shadow: 0 0 1em rgb(127 127 127 / 0.8);
  width: 30rem;
  max-width: 90%;
}

.modal-dialog::backdrop {
  background: rgb(0 0 0 / 0.4);
  backdrop-filter: blur(1px);
}
body {
  background-color: hsl(240 100% 95%);
}
<dialog id="cres_statusmssg" >
  <div>
    <p>Changing your status will alter your estate plan and may cause you to lose some data. Do you want to proceed?</p>
    <button id="cres_yes" data-value="true">Yes</button>
    <button id="cres_cancel" data-value="false">Cancel</button>
  </div>
</dialog>

<div>
  <p>Dummy page text</p>
<div>

CodePudding user response:

Try to use Bootstrap Modal

Using Twitter bootstrap modal instead of confirm dialog

Or jquery ui

How to implement "confirmation" dialog in Jquery UI dialog?

  • Related