modal: Add ability to show multiple input fields for confirm modal
This commit is contained in:
parent
78b1a5c42a
commit
16c58a966a
@ -31,6 +31,7 @@ Soon we'll deprecate the latter, so prepare now.
|
||||
[discover_connection_methods](https://conversejs.org/docs/html/configuration.html#discover-connection-methods) now has a default value of `true`).
|
||||
- [show_send_button](https://conversejs.org/docs/html/configuration.html#show-send-button) now has a default value of `true`.
|
||||
- New configuration setting [muc_hats_from_vcard](https://conversejs.org/docs/html/configuration.html#muc-hats-from-vcard).
|
||||
- The [api.confirm](https://conversejs.org/docs/html/api/-_converse.api.html#.confirm) method now accepts a list of fields and returns the filled in list upon confirmation.
|
||||
|
||||
## 6.0.0 (2020-01-09)
|
||||
|
||||
|
@ -115,23 +115,26 @@ export const Confirm = BootstrapModal.extend({
|
||||
}
|
||||
},
|
||||
|
||||
onConfimation (ev) {
|
||||
ev.preventDefault();
|
||||
this.confirmation.resolve(true);
|
||||
this.modal.hide();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
export const Prompt = Confirm.extend({
|
||||
toHTML () {
|
||||
return tpl_prompt(this.model.toJSON());
|
||||
},
|
||||
|
||||
onConfimation (ev) {
|
||||
ev.preventDefault();
|
||||
const form_data = new FormData(ev.target);
|
||||
this.confirmation.resolve(form_data.get('reason'));
|
||||
const fields = (this.model.get('fields') || [])
|
||||
.map(field => {
|
||||
const value = form_data.get(field.name).trim();
|
||||
field.value = value;
|
||||
if (field.challenge) {
|
||||
field.challenge_failed = (value !== field.challenge);
|
||||
}
|
||||
return field;
|
||||
});
|
||||
|
||||
if (fields.filter(c => c.challenge_failed).length) {
|
||||
this.model.set('fields', fields);
|
||||
// Setting an array doesn't trigger a change event
|
||||
this.model.trigger('change');
|
||||
return;
|
||||
}
|
||||
this.confirmation.resolve(fields);
|
||||
this.modal.hide();
|
||||
}
|
||||
});
|
||||
@ -165,7 +168,7 @@ converse.plugins.add('converse-modal', {
|
||||
|
||||
/************************ BEGIN API ************************/
|
||||
// We extend the default converse.js API to add methods specific to MUC chat rooms.
|
||||
let alert, prompt, confirm;
|
||||
let alert;
|
||||
|
||||
Object.assign(_converse.api, {
|
||||
/**
|
||||
@ -173,33 +176,30 @@ converse.plugins.add('converse-modal', {
|
||||
* @method _converse.api.confirm
|
||||
* @param { String } title - The header text for the confirmation dialog
|
||||
* @param { (String[]|String) } messages - The text to show to the user
|
||||
* @returns { Promise } A promise which resolves with true or false
|
||||
* @param { Array<Field> } fields - An object representing a fields presented to the user.
|
||||
* @property { String } Field.label - The form label for the input field.
|
||||
* @property { String } Field.name - The name for the input field.
|
||||
* @property { String } [Field.challenge] - A challenge value that must be provided by the user.
|
||||
* @property { String } [Field.placeholder] - The placeholder for the input field.
|
||||
* @property { Boolean} [Field.required] - Whether the field is required or not
|
||||
* @returns { Promise<Array|false> } A promise which resolves with an array of
|
||||
* filled in fields or `false` if the confirm dialog was closed or canceled.
|
||||
*/
|
||||
async confirm (title, messages=[]) {
|
||||
async confirm (title, messages=[], fields=[]) {
|
||||
if (isString(messages)) {
|
||||
messages = [messages];
|
||||
}
|
||||
if (confirm === undefined) {
|
||||
const model = new Model({
|
||||
'title': title,
|
||||
'messages': messages,
|
||||
'type': 'confirm'
|
||||
})
|
||||
confirm = new Confirm({model});
|
||||
} else {
|
||||
confirm.confirmation = u.getResolveablePromise();
|
||||
confirm.model.set({
|
||||
'title': title,
|
||||
'messages': messages,
|
||||
'type': 'confirm'
|
||||
});
|
||||
}
|
||||
const model = new Model({title, messages, fields, 'type': 'confirm'})
|
||||
const confirm = new Confirm({model});
|
||||
confirm.show();
|
||||
let result;
|
||||
try {
|
||||
return await confirm.confirmation;
|
||||
result = await confirm.confirmation;
|
||||
} catch (e) {
|
||||
return false;
|
||||
result = false;
|
||||
}
|
||||
confirm.remove();
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -208,35 +208,32 @@ converse.plugins.add('converse-modal', {
|
||||
* @param { String } title - The header text for the prompt
|
||||
* @param { (String[]|String) } messages - The prompt text to show to the user
|
||||
* @param { String } placeholder - The placeholder text for the prompt input
|
||||
* @returns { Promise } A promise which resolves with the text provided by the
|
||||
* @returns { Promise<String|false> } A promise which resolves with the text provided by the
|
||||
* user or `false` if the user canceled the prompt.
|
||||
*/
|
||||
async prompt (title, messages=[], placeholder='') {
|
||||
if (isString(messages)) {
|
||||
messages = [messages];
|
||||
}
|
||||
if (prompt === undefined) {
|
||||
const model = new Model({
|
||||
'title': title,
|
||||
'messages': messages,
|
||||
const model = new Model({
|
||||
title,
|
||||
messages,
|
||||
'fields': [{
|
||||
'name': 'reason',
|
||||
'placeholder': placeholder,
|
||||
'type': 'prompt'
|
||||
})
|
||||
prompt = new Prompt({model});
|
||||
} else {
|
||||
prompt.confirmation = u.getResolveablePromise();
|
||||
prompt.model.set({
|
||||
'title': title,
|
||||
'messages': messages,
|
||||
'type': 'prompt'
|
||||
});
|
||||
}
|
||||
}],
|
||||
'type': 'prompt'
|
||||
})
|
||||
const prompt = new Confirm({model});
|
||||
prompt.show();
|
||||
let result;
|
||||
try {
|
||||
return await prompt.confirmation;
|
||||
result = (await prompt.confirmation).pop()?.value;
|
||||
} catch (e) {
|
||||
return false;
|
||||
result = false;
|
||||
}
|
||||
prompt.remove();
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -6,9 +6,16 @@ const i18n_cancel = __('Cancel');
|
||||
const i18n_ok = __('OK');
|
||||
|
||||
|
||||
const tpl_reason = (o) => html`
|
||||
const tpl_field = (f) => html`
|
||||
<div class="form-group">
|
||||
<input type="text" name="reason" class="form-control" placeholder="${o.placeholder}"/>
|
||||
<label>
|
||||
${f.label || ''}
|
||||
<input type="text"
|
||||
name="${f.name}"
|
||||
class="${(f.challenge_failed) ? 'error' : ''} form-control form-control--labeled"
|
||||
?required="${f.required}"
|
||||
placeholder="${f.placeholder}" />
|
||||
</label>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@ -16,7 +23,7 @@ const tpl_reason = (o) => html`
|
||||
export default (o) => html`
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header ${o.level}">
|
||||
<div class="modal-header ${o.level || ''}">
|
||||
<h5 class="modal-title">${o.title}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
@ -28,7 +35,7 @@ export default (o) => html`
|
||||
<div class="form-group">
|
||||
${ o.messages.map(message => html`<p>${message}</p>`) }
|
||||
</div>
|
||||
${ (o.type === 'prompt') ? tpl_reason(o) : '' }
|
||||
${ o.fields.map(f => tpl_field(f)) }
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary">${i18n_ok}</button>
|
||||
<input type="button" class="btn btn-secondary" data-dismiss="modal" value="${i18n_cancel}"/>
|
||||
|
Loading…
Reference in New Issue
Block a user