[Wrong forum! Please ignore this.] Extension of window.prompt to allow other types of common inputs (<select>, date, color, password, range, file, ...)

I often find myself wanting a quick modal to accept some input, but I don't want to include a big dependency, or manually code up something. And I'm obviously not alone here: I see window.prompt and window.confirm used quite often on the web - even in large applications.

I'm a huge fan of having "simple things be simple, and complex things be possible", as the saying goes, and in the case where I just want to quickly grab some user input, I think it should be as simple as prompt(...).

An async version of this is obviously pretty easy to "polyfill". Here's a very rough sketch:

async function prompt2(message, opts) {
  let ctn = document.createElement("div");
  let type = opts.type;
  let input;
  if(type == "select") {
    input = `<select style="width:100%;height:100%;background:white;color:inherit;font:inherit;box-sizing:border-box;">${opts.options.map(o => `<option value="${o.value}">${o.content}</option>`).join("")}</select>`;
  } else if(type == "buttons") {
    input = opts.buttons.map(o => `<button style="height:100%;margin-right:0.5rem;font:inherit;box-sizing:border-box;" data-value="${o.value}">${o.content}</button>`).join("");
  } else {
    input = `<input style="width:100%;height:100%;background:white;color:inherit;font:inherit;box-sizing:border-box;" type="${opts.type}">`;
  }
  ctn.innerHTML = `
    <div style="background:rgba(0,0,0,0.2); position:fixed; top:0; left:0; right:0; bottom:0; z-index:9999999; display:flex; justify-content:center; color:black; font-family: sans-serif;">
      <div style="width:400px; background:white; height: min-content; padding:1rem; border:1px solid #eaeaea; border-radius:3px; box-shadow: 0px 1px 10px 3px rgba(0,0,0,0.24); margin-top:0.5rem;">
        <div style="opacity:0.6;">${window.location.hostname} says:</div>
        <div style="margin:1rem 0;">${message}</div>
        <div style="display:flex; height:2.3rem;">
          <div style="flex-grow:1; padding-right:0.5rem;">${input}</div>
          ${type !== "buttons" ? `<button style="font:inherit;box-sizing:border-box;">Submit</button>` : ""}
        </div>
      </div>
    </div>
  `;
   document.body.appendChild(ctn);
   let value = await new Promise((resolve) => {
    if(type !== "buttons") {
      ctn.querySelector("button").onclick = () => {
        if(type == "file") {
          resolve(ctn.querySelector("input").files);
        } else {
          resolve(ctn.querySelector("input,select").value);
        }
      }
     } else {
        ctn.querySelectorAll("button").forEach(b => {
          b.onclick = () => resolve(b.dataset.value);
        });
     }
   });
   ctn.remove();
   return value;
}

Usage:

let name = await prompt2("Please type your name:", {type:"text"});
let pw = await prompt2("Please type your password:", {type:"password"});
let date = await prompt2("Please choose a date:", {type:"date"});
let files = await prompt2("Please choose a file:", {type:"file"});
let choice = await prompt2("Please choose an option:", {type:"select", options:[{content:"Thing 1", value:"1"}, {content:"Thing 2", value:"2"}]});
let choice = await prompt2("Please choose an option:", {type:"buttons", buttons:[{content:"Thing 1", value:"1"}, {content:"Thing 2", value:"2"}]});

Example of type:"date":

image

Obviously window.prompt can't be made async, and the second param of window.prompt is already used for the default value, so perhaps it would be better to start over with a new function. Although it would be great to have a sync version of this API too - so that we don't have to sprinkle async throughout a codebase that was completely sync up until that point.

I wonder if it would be safe enough to use the second param of window.prompt? I doubt anyone is actually passing an object to the second parameter on purpose, so that they can have [object Object] as the default value. And then a window.promptAsync could be added which has the same UI, but returns a promise. But I'm really just thinking out loud here.

Does anyone have any thoughts here? Have there been attempts to do bring something like this through TC39 before? (TC39 is the appropriate body to standardize something like this, right? Or is TC39 aimed more at lower-level language details?)

Thanks!

You're probably looking for the obsoleted showModalDialog or more recent showModal methods.

But either way, this is out of scope for the ECMAScript language specification, as it would be a browser-only feature. No, TC39 is not the appropriate body to standardise this. You're looking for the WHATWG or WICG.

TC39 is for the language; window is part of web browsers. You’ll want the HTML spec for this one.

Ah, thanks! Sorry about that. I'll head over to the WICG discourse.