I'm trying to get a return value from a custom confirmation box base on which button a user clicks. Not sure how to go about it asynchronously.
The template for the confirmation window is premade, and the confirmation_box()
assigns text to the specified elements.
If the user clicks yes, I want to return a value of 1/true, which would allow me to proceed with the next step. If no is clicked, the confirmation window will simply close and the code stop there.
async function confirmation_box(msg = 'Are you sure?', false_btn = 'No', true_btn = 'Yes') {
let confirmation_modal = document.getElementById('overlay');
let true_el = confirmation_modal.querySelector('.true_btn');
let false_el = confirmation_modal.querySelector('.false_btn');
// assign text to elements
confirmation_modal.querySelector('#confirmation_msg').textContent = msg;
true_el.textContent = true_btn;
false_el.textContent = false_btn;
confirmation_modal.classList.add('show');
true_el.addEventListener('click', await
function() {
confirmation_modal.classList.remove('show');
return 1;
});
false_el.addEventListener('click', await
function() {
confirmation_modal.classList.remove('show');
return 0;
});
}
async function delete_demo() {
let result = await confirmation_box('are you sure you want to delete this?');
console.log(`Confirmation result ${result}`);
if (result) {
document.getElementById('demo_text').remove();
}
}
body {
height: 100vh;
display: -ms-grid;
display: grid;
place-content: center;
}
#overlay {
top: 0;
left: 0;
opacity: 0;
width: 100%;
height: 100%;
display: -ms-grid;
display: grid;
position: fixed;
visibility: hidden;
place-content: center;
background: rgba(0, 0, 0, 0.5);
}
#overlay.show {
opacity: 1;
visibility: visible;
}
.modal {
padding: 10px;
background: #fff;
border: 1px solid #000;
}
<body>
<div class="container">
<p id='demo_text'>Demo text</p>
<button onclick='delete_demo()'>Delete Demo</button>
<div id="overlay">
<div class="modal">
<p id="confirmation_msg"></p>
<div>
<button class="false_btn"></button>
<button class="true_btn"></button>
</div>
</div>
</div>
</div>
</body>
You are nearly there.
The problem is that the confirmation_box
function doesn't return a Promise
, so your await confirmation_box
statement doesn't do the waiting that you expected it to do. The fixed code has three changes.
confirmation_box
returns a Promise
with all of the code inside the promise.
return 0
and return 1
were changed to resolve(0)
and resolve(1)
As Barmar said, don't use addEventListener
inside anything that might loop when you don't want multiple event listeners. I just changed it to an onclick
since it uses the resolve
function available inside the Promise
area.
Here's the fixed code:
async function confirmation_box(msg = 'Are you sure?', false_btn = 'No', true_btn = 'Yes') {
return new Promise(function(resolve){
let confirmation_modal = document.getElementById('overlay');
let true_el = confirmation_modal.querySelector('.true_btn');
let false_el = confirmation_modal.querySelector('.false_btn');
// assign text to elements
confirmation_modal.querySelector('#confirmation_msg').textContent = msg;
true_el.textContent = true_btn;
false_el.textContent = false_btn;
confirmation_modal.classList.add('show');
true_el.onclick = function() {
confirmation_modal.classList.remove('show');
resolve(1);
};
false_el.onclick = function() {
confirmation_modal.classList.remove('show');
resolve(0);
};
});
}
async function delete_demo() {
let result = await confirmation_box('are you sure you want to delete this?');
console.log(`Confirmation result ${result}`);
if (result) {
document.getElementById('demo_text').remove();
}
}
body {
height: 100vh;
display: -ms-grid;
display: grid;
place-content: center;
}
#overlay {
top: 0;
left: 0;
opacity: 0;
width: 100%;
height: 100%;
display: -ms-grid;
display: grid;
position: fixed;
visibility: hidden;
place-content: center;
background: rgba(0, 0, 0, 0.5);
}
#overlay.show {
opacity: 1;
visibility: visible;
}
.modal {
padding: 10px;
background: #fff;
border: 1px solid #000;
}
<body>
<div class="container">
<p id='demo_text'>Demo text</p>
<button onclick='delete_demo()'>Delete Demo</button>
<div id="overlay">
<div class="modal">
<p id="confirmation_msg"></p>
<div>
<button class="false_btn"></button>
<button class="true_btn"></button>
</div>
</div>
</div>
</div>
</body>