feat: the panel's own confirm and prompt dialogs everywhere; the assistant's field is one line with a square send button
This commit is contained in:
1 parent
3f113ce8d6
commit
1f930e5aea
13 files changed
+104
-41
No files matched your search
@@ -0,0 +1,53 @@
|
||||
// The panel's own question and input dialogs in place of the browser's
|
||||
// confirm() and prompt(): UI.confirm(text, {ok, danger}) and
|
||||
// UI.prompt(text, value) answer with promises. A form with data-confirm asks
|
||||
// first and is sent only on «да».
|
||||
(function () {
|
||||
'use strict';
|
||||
let dlg = null;
|
||||
function make() {
|
||||
dlg = document.createElement('dialog');
|
||||
dlg.className = 'uidlg';
|
||||
dlg.innerHTML = '<form method="dialog"><p class="ui-text"></p><input class="ui-input" autocomplete="off" spellcheck="false">' +
|
||||
'<div class="row end"><button type="button" class="btn ghost ui-no">Отмена</button><button type="submit" class="ui-yes">OK</button></div></form>';
|
||||
document.body.appendChild(dlg);
|
||||
}
|
||||
function ask(text, o) {
|
||||
if (!dlg) make();
|
||||
if (dlg.open) dlg.close('');
|
||||
const input = dlg.querySelector('.ui-input'), yes = dlg.querySelector('.ui-yes');
|
||||
dlg.querySelector('.ui-text').textContent = text;
|
||||
input.hidden = !o.input;
|
||||
input.value = o.value || '';
|
||||
yes.textContent = o.ok || 'OK';
|
||||
yes.className = 'ui-yes' + (o.danger ? ' btn danger' : '');
|
||||
return new Promise(done => {
|
||||
const end = v => { dlg.onclose = null; done(v); };
|
||||
dlg.querySelector('.ui-no').onclick = () => dlg.close('');
|
||||
dlg.querySelector('form').onsubmit = ev => { ev.preventDefault(); dlg.close('ok'); };
|
||||
dlg.onclose = () => end(dlg.returnValue === 'ok' ? (o.input ? input.value : true) : (o.input ? null : false));
|
||||
dlg.returnValue = '';
|
||||
dlg.showModal();
|
||||
if (o.input) { input.focus(); input.select(); } else yes.focus();
|
||||
});
|
||||
}
|
||||
const UI = {
|
||||
confirm: (text, o) => ask(text, Object.assign({ok: 'Да'}, o)),
|
||||
prompt: (text, value) => ask(text, {input: true, value, ok: 'OK'})
|
||||
};
|
||||
window.UI = UI;
|
||||
// Forms that ask first: data-confirm, and data-danger for a red «да».
|
||||
document.addEventListener('submit', ev => {
|
||||
const f = ev.target;
|
||||
if (!f.dataset || !f.dataset.confirm) return;
|
||||
if (f.dataset.confirmed) { delete f.dataset.confirmed; return; }
|
||||
ev.preventDefault();
|
||||
ev.stopImmediatePropagation();
|
||||
const by = ev.submitter;
|
||||
UI.confirm(f.dataset.confirm, {ok: f.dataset.ok || 'Да', danger: 'danger' in f.dataset}).then(ok => {
|
||||
if (!ok) return;
|
||||
f.dataset.confirmed = '1';
|
||||
f.requestSubmit(by && f.contains(by) ? by : undefined);
|
||||
});
|
||||
}, true);
|
||||
})();
|
||||
Reference in new issue
Block a user