/**
* A prompt dialog box.
* <p>Part of the XUI module which, for now, has an undocumented API.
*/
export class Prompt extends Dialog {
static showPrompt(title, prompt,
columns=40, initialValue=null,
valueList=null, inputValueChecker=null,
reference=null) {
return Prompt.prompt({ title: title,
prompt: prompt,
columns: columns,
initialValue: initialValue,
valueList: valueList,
inputValueChecker: inputValueChecker },
reference);
}
static prompt(options, reference) {
return new Promise((resolve, reject) => {
let dialog = new Prompt(options, resolve);
dialog.open("center", reference);
});
}
constructor(options, resolve) {
const opts = Object.assign({
title: "???",
prompt: "???",
hint: null,
columns: 40,
initialValue: null,
valueList: null,
inputValueChecker: null
}, options);
super({ movable: true, title: opts.title, closeable: true,
template: Prompt.TEMPLATE,
buttons: [ { label: "Cancel", action: "cancelAction" },
{ label: "OK", action: "okAction",
default: true } ]});
this._resolve = resolve;
let pane = this.contentPane.firstElementChild;
let icon = pane.firstElementChild;
icon.textContent = StockIcon["question"];
let form = pane.lastElementChild;
let question = form.firstElementChild;
question.innerHTML = Prompt.textToHTML(opts.prompt);
this._input = question.nextElementSibling;
if (opts.columns < 10) {
opts.columns = 10;
}
this._input.size = opts.columns;
let hint = form.lastElementChild;
if (opts.hint) {
hint.innerHTML = Prompt.textToHTML(opts.hint);
} else {
hint.style.display = "none";
}
if (opts.initialValue !== null) {
this._input.value = opts.initialValue;
this.selectInputValue();
}
this._input.autocomplete = "off";
if (opts.valueList !== null && Array.isArray(opts.valueList) &&
opts.valueList.length > 0) {
let allValues = [];
for (let value of opts.valueList) {
value = value.toString().trim();
if (value.length > 0) {
allValues.push(value);
}
}
if (allValues.length > 0) {
// valueList is assumed to have been sorted by client code.
// (This may be easily done using valueList.sort().)
let datalistId = Util.uid();
Util.appendDatalist(datalistId, allValues, form);
this._input.setAttribute("list", datalistId);
}
}
this._checkInputValue = opts.inputValueChecker;
this._input.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
Util.consumeEvent(e);
this.okAction();
}
});
}
static textToHTML(text) {
if (text.startsWith("<html>")) {
text = text.substring(6);
} else {
text = Util.escapeHTML(text);
if (text.indexOf('\n') >= 0) {
text = text.replaceAll('\n', "<br>");
}
}
return text;
}
dialogClosed(result) {
// Close button clicked ==> null result, which is just fine.
this._resolve(result);
}
cancelAction() {
this.close(null);
}
okAction() {
let inputValue = this.getInputValue();
if (this._checkInputValue !== null) {
// checkInputValue may or may not accept null.
if (!this._checkInputValue(inputValue)) {
this.selectInputValue();
return;
}
}
this.close(inputValue);
}
// -----------------------------------
// Validation helpers
// -----------------------------------
getInputValue() {
let result = this._input.value;
if (result !== null && (result = result.trim()).length === 0) {
result = null;
}
return result;
}
selectInputValue() {
this._input.focus();
this._input.select();
}
}
Prompt.TEMPLATE = document.createElement("template");
Prompt.TEMPLATE.innerHTML = `
<div class="xui-prompt-pane">
<div class="xui-prompt-icon"></div>
<div class="xui-prompt-form">
<div class="xui-prompt-question"></div>
<input class="xui-prompt-input" type="text" spellcheck="false" />
<div class="xui-prompt-hint"></div>
</div>
</div>
`;