0

The page needs to be rendered before the prompt is called. In current implementation, prompt(...) interrupts DOM manipulation and hint is shown only after user clicks OK on prompt message box.

Although el.innerHTML = 'Please, reply to prompt'; is called before var res = prompt('Hello world');, the HTML element with id='hint' won't be updated until user hits OK on prompt message box.

<!DOCTYPE html>
<script type="text/javascript">
 function callNativeApp() {
 console.log('callNativeApp called');
 try {
 // Show hint message
 var el = document.getElementById('hint'); 
 el.innerHTML = 'Please, reply to prompt';
 // Call prompt 
 var res = prompt('Hello world');
 // Write result of prompt reply to html
 document.getElementById('prompt-call-output').innerHTML = res;
 } catch(err) {
 console.log('The native context does not exist yet');
 }
 }
</script>
<html>
 <head>
 </head>
 <body>
 <button onclick="callNativeApp()">Call native app</button>
 <p id="hint"></p>
 <p id="prompt-call-output"></p>
 </body>
</html>

How to change current code, so the page renders first. And only after that prompt is called()? E.g. Somehow force DOM tree to update(refresh) before prompt call?

Timeout solution for calling var res = prompt('Hello world'); like

setTimeout(function() {
 var res = prompt('Hello world');
 document.getElementById('prompt-call-output').innerHTML = res;
}, 100);

is not applicable as our current codebase relies on sequence of commands that goes after prompt(...) call.

Screen that shows that hint is not shown when prompt is called, even though text hint setting is called before calling prompt: enter image description here

And hint is only shown when prompt window is closed:

enter image description here

asked May 9, 2020 at 17:56

1 Answer 1

1

This is one of the issues regarding prompt, alert, and confirm messages, they block javascript execution since the browser waits for user interaction, also are considered bad UX implementation:

Dialog boxes are modal windows; they prevent the user from accessing the rest of the program's interface until the dialog box is closed. For this reason, you should not overuse any function that creates a dialog box (or modal window).

one of the solution to this is to implement your own prompts dialog, in this link from bluebird the address it using Promises with async dialogs:

function promptPromise(message) {
 var dialog = document.getElementById('dialog');
 var input = dialog.querySelector('input');
 var okButton = dialog.querySelector('button.ok');
 dialog.querySelector('.message').innerHTML = String(message);
 dialog.className = '';
 return new Promise(function(resolve, reject) {
 dialog.addEventListener('click', function handleButtonClicks(e) {
 if (e.target.tagName !== 'BUTTON') { return; }
 dialog.removeEventListener('click', handleButtonClicks);
 dialog.className = 'hidden';
 if (e.target === okButton) {
 resolve(input.value);
 } else {
 reject(new Error('User cancelled'));
 }
 });
 });
}
document.addEventListener('DOMContentLoaded', function() {
 var button = document.getElementById('action');
 var output = document.getElementById('prompt');
 button.addEventListener('click', function() {
 promptPromise('What is your name?').then(function(name) {
 output.innerHTML = '' + name;
 })
 .catch(function() {
 output.innerHTML = ' ̄\\_(ツ)_/ ̄';
 });
 });
});
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Async Dislogs Example</title>
 <script src="//cdn.jsdelivr.net/bluebird/3.0.5/bluebird.js"></script>
 <script type="text/javascript">
 document.addEventListener('DOMContentLoaded', function() {
 var time = document.getElementById('time-stamp');
 clockTick();
 setInterval(clockTick, 1000);
 function clockTick() {
 time.innerHTML = '' + new Date();
 }
 });
 </script>
 <style type="text/css">
 #dialog {
 width: 200px;
 margin: auto;
 border: thin solid black;
 padding: 10px;
 background: lightgreen;
 }
 .hidden {
 display: none;
 }
 </style>
</head>
<body>
 <p>The current time is <span id="time-stamp"></span>.</p>
 <p>Your name is <span id="prompt"></span>.</p>
 <button id="action">Set Name</button>
 <div id="dialog" class="hidden">
 <div class="message">foobar</div>
 <input type="text">
 <div>
 <button class="ok">Ok</button>
 <button class="cancel">Cancel</button>
 </div>
 </div>
</body>
</html>

For your code snippet the implementation would be something like this:

function promptPromise(message) {
 var dialog = document.getElementById('dialog');
 var input = dialog.querySelector('input');
 var okButton = dialog.querySelector('button.ok');
 dialog.querySelector('.message').innerHTML = String(message);
 dialog.className = '';
 return new Promise(function(resolve, reject) {
 dialog.addEventListener('click', function handleButtonClicks(e) {
 if (e.target.tagName !== 'BUTTON') { return; }
 dialog.removeEventListener('click', handleButtonClicks);
 dialog.className = 'hidden';
 if (e.target === okButton) {
 resolve(input.value);
 } else {
 reject(new Error('User cancelled'));
 }
 });
 });
}
document.addEventListener('DOMContentLoaded', function() {
 var button = document.getElementById('action');
 var output = document.getElementById('hint');
 var el = document.getElementById('hint'); 
 
 button.addEventListener('click', function() {
 el.innerHTML = 'Please, reply to prompt';
 promptPromise('Hello world').then(function(name) {
 document.getElementById('prompt-call-output').innerHTML = '' + name;
 })
 .catch(function() {
 output.innerHTML = ' ̄\\_(ツ)_/ ̄';
 });
 });
});
#dialog {
 width: 200px;
 margin: auto;
 border: thin solid black;
 padding: 10px;
 background: lightgreen;
}
.hidden {
 display: none;
}
<!DOCTYPE html>
<html>
 <head>
 </head>
 <body>
 <button id="action">Call native app</button>
 <p id="hint"></p>
 <p id="prompt-call-output"></p>
 <div id="dialog" class="hidden">
 <div class="message">foobar</div>
 <input type="text">
 <div>
 <button class="ok">Ok</button>
 <button class="cancel">Cancel</button>
 </div>
 </div>
 </body>
</html>

answered May 9, 2020 at 18:49
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.