Added confirmation dialog to delete forms
This commit is contained in:
parent
1b21bcf769
commit
ff179360cc
|
@ -275,6 +275,71 @@ ready(() => {
|
||||||
document.querySelectorAll('.modal').forEach((element) => new bootstrap.Modal(element));
|
document.querySelectorAll('.modal').forEach((element) => new bootstrap.Modal(element));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show confirmation modal before submitting form
|
||||||
|
*
|
||||||
|
* Uses the buttons data attributes to show in the modal:
|
||||||
|
* - data-confirm_title: Optional title of the modal
|
||||||
|
* - data-confirm_submit: Body of the modal
|
||||||
|
*
|
||||||
|
* The class, title and content of the requesting button gets copied for confirmation
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
ready(() => {
|
||||||
|
document.querySelectorAll('[data-confirm_submit_title], [data-confirm_submit_text]').forEach((element) => {
|
||||||
|
let modalOpen = false;
|
||||||
|
let oldType = element.type;
|
||||||
|
if (element.type !== 'submit') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
element.type = 'button';
|
||||||
|
element.addEventListener('click', (event) => {
|
||||||
|
if (modalOpen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
document.getElementById('confirmation-modal')?.remove();
|
||||||
|
document.body.insertAdjacentHTML(
|
||||||
|
'beforeend',
|
||||||
|
`
|
||||||
|
<div class="modal" tabindex="-1" id="confirmation-modal">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content ${document.body.dataset.theme_type === 'light' ? 'bg-white' : 'bg-dark'}">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">${element.dataset.confirm_submit_title ?? ''}</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body${element.dataset.confirm_submit_text ? '' : ' d-none'}">
|
||||||
|
<p>${element.dataset.confirm_submit_text ?? ''}</p>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="${element.className}"
|
||||||
|
title="${element.title}" data-submit="">${element.innerHTML}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
let modal = document.getElementById('confirmation-modal');
|
||||||
|
modal.addEventListener('hide.bs.modal', () => {
|
||||||
|
modalOpen = false;
|
||||||
|
});
|
||||||
|
modal.querySelector('[data-submit]').addEventListener('click', (event) => {
|
||||||
|
element.type = oldType;
|
||||||
|
element.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
modalOpen = true;
|
||||||
|
let bootstrapModal = new bootstrap.Modal(modal);
|
||||||
|
bootstrapModal.show();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show oauth buttons on welcome title click
|
* Show oauth buttons on welcome title click
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1989,3 +1989,6 @@ msgstr "Was möchtest Du machen?"
|
||||||
|
|
||||||
msgid "registration.register"
|
msgid "registration.register"
|
||||||
msgstr "Registrieren"
|
msgstr "Registrieren"
|
||||||
|
|
||||||
|
msgid "confirmation.delete"
|
||||||
|
msgstr "Möchtest du es wirklich löschen?"
|
||||||
|
|
|
@ -644,3 +644,6 @@ msgstr "Please enter a lastname in your settings!"
|
||||||
|
|
||||||
msgid "mobile.required.hint"
|
msgid "mobile.required.hint"
|
||||||
msgstr "Please enter a mobile number in your settings!"
|
msgstr "Please enter a mobile number in your settings!"
|
||||||
|
|
||||||
|
msgid "confirmation.delete"
|
||||||
|
msgstr "Do you really want to delete it?"
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
<form method="post" class="ps-1">
|
<form method="post" class="ps-1">
|
||||||
{{ csrf() }}
|
{{ csrf() }}
|
||||||
{{ f.hidden('id', location.id) }}
|
{{ f.hidden('id', location.id) }}
|
||||||
{{ f.button(m.icon('trash'), {'title': __('form.delete'), 'name': 'delete', 'type': 'submit', 'btn_type': 'danger', 'size': 'sm'}) }}
|
{{ f.delete(null, {'size': 'sm','confirm_title': location.name|e}) }}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body data-theme_type="{{ theme.type }}">
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
{% block header %}
|
{% block header %}
|
||||||
|
|
|
@ -261,6 +261,8 @@ Renders a button.
|
||||||
Must be a Bootstrap icon class without prefix, such as "info" or "check".
|
Must be a Bootstrap icon class without prefix, such as "info" or "check".
|
||||||
@param {string} [opt.icon_right] - Optional icon to be added after the button label.
|
@param {string} [opt.icon_right] - Optional icon to be added after the button label.
|
||||||
Must be a Bootstrap icon class without prefix, such as "info" or "check".
|
Must be a Bootstrap icon class without prefix, such as "info" or "check".
|
||||||
|
@param {string} [opt.confirm_title] - Optional value for the confirmation title.
|
||||||
|
@param {string} [opt.confirm_text] - Optional value for the confirmation text.
|
||||||
#}
|
#}
|
||||||
{% macro button(label, opt) %}
|
{% macro button(label, opt) %}
|
||||||
<button
|
<button
|
||||||
|
@ -270,6 +272,8 @@ Renders a button.
|
||||||
{%- if opt.name is defined %} name="{{ opt.name }}"{% endif %}
|
{%- if opt.name is defined %} name="{{ opt.name }}"{% endif %}
|
||||||
{%- if opt.title is defined %} title="{{ opt.title }}"{% endif %}
|
{%- if opt.title is defined %} title="{{ opt.title }}"{% endif %}
|
||||||
{%- if opt.value is defined or opt.name is defined %} value="{{ opt.value|default('1') }}"{% endif -%}
|
{%- if opt.value is defined or opt.name is defined %} value="{{ opt.value|default('1') }}"{% endif -%}
|
||||||
|
{%- if opt.confirm_title is defined %} data-confirm_submit_title="{{ opt.confirm_title }}"{% endif -%}
|
||||||
|
{%- if opt.confirm_text is defined %} data-confirm_submit_text="{{ opt.confirm_text }}"{% endif -%}
|
||||||
>
|
>
|
||||||
{%- if opt.icon_left is defined %}<span class="bi bi-{{ opt.icon_left }}"></span>{% endif %}
|
{%- if opt.icon_left is defined %}<span class="bi bi-{{ opt.icon_left }}"></span>{% endif %}
|
||||||
{{ label }}
|
{{ label }}
|
||||||
|
@ -281,6 +285,16 @@ Renders a button.
|
||||||
{{ _self.button(label|default(__('form.submit')), {'type': 'submit', 'btn_type': 'primary'}|merge(opt|default({}))) }}
|
{{ _self.button(label|default(__('form.submit')), {'type': 'submit', 'btn_type': 'primary'}|merge(opt|default({}))) }}
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
|
||||||
|
{% macro delete(label, opt) %}
|
||||||
|
{{ _self.submit(label|default(' '), {
|
||||||
|
'icon_left': 'trash',
|
||||||
|
'title': __('form.delete'),
|
||||||
|
'name': 'delete',
|
||||||
|
'btn_type': 'danger',
|
||||||
|
'confirm_text': __('confirmation.delete')
|
||||||
|
}|merge(opt|default({}))) }}
|
||||||
|
{%- endmacro %}
|
||||||
|
|
||||||
{#
|
{#
|
||||||
Renders a "checkbox" element that will be styled as switch.
|
Renders a "checkbox" element that will be styled as switch.
|
||||||
|
|
||||||
|
|
|
@ -354,10 +354,14 @@
|
||||||
'title': 'Click me!',
|
'title': 'Click me!',
|
||||||
}) }}
|
}) }}
|
||||||
</div>
|
</div>
|
||||||
<code>f.submit(label)</code>
|
<code>f.submit(label, opt)</code>
|
||||||
<form id="form">
|
<form class="prevent-default">
|
||||||
{{ f.submit('Go!') }}
|
{{ f.submit('Go!') }}
|
||||||
</form>
|
</form>
|
||||||
|
<code>f.delete(label, opt)</code>
|
||||||
|
<form class="prevent-default">
|
||||||
|
{{ f.delete('Delete it', {'confirm_title': 'Delete some item'}) }}
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="checkboxes" class="col-md-3 col-lg-2">
|
<div id="checkboxes" class="col-md-3 col-lg-2">
|
||||||
|
@ -529,9 +533,11 @@ Por scientie, musica, sport etc, litot Europa usa li sam vocabular.</code></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
document.getElementById('form').addEventListener('submit', (e) => {
|
[...document.getElementsByClassName('prevent-default')].forEach((element) => {
|
||||||
e.preventDefault();
|
element.addEventListener('submit', (e) => {
|
||||||
return false;
|
e.preventDefault();
|
||||||
});
|
return false;
|
||||||
|
});
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
action="{{ url('/news/comment/' ~ comment.id) }}" enctype="multipart/form-data"
|
action="{{ url('/news/comment/' ~ comment.id) }}" enctype="multipart/form-data"
|
||||||
method="post">
|
method="post">
|
||||||
{{ csrf() }}
|
{{ csrf() }}
|
||||||
{{ f.submit(m.icon('trash'), {'name': 'delete', 'btn_type': 'danger', 'size': 'sm', 'title': __('form.delete')}) }}
|
{{ f.delete(null, {'size': 'sm', 'confirm_title': comment.text[:40]|e}) }}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
>
|
>
|
||||||
{{ csrf() }}
|
{{ csrf() }}
|
||||||
{{ f.hidden('id', question.id) }}
|
{{ f.hidden('id', question.id) }}
|
||||||
{{ f.submit(m.icon('trash'), {'name': 'delete', 'btn_type': 'danger', 'size': 'sm', 'title': __('form.delete')}) }}
|
{{ f.delete(null, {'size': 'sm', 'confirm_title': question.text[:40]|e}) }}
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
|
@ -20,10 +20,7 @@
|
||||||
<form action="" enctype="multipart/form-data" method="post">
|
<form action="" enctype="multipart/form-data" method="post">
|
||||||
{{ csrf() }}
|
{{ csrf() }}
|
||||||
{{ f.hidden('id', 'all') }}
|
{{ f.hidden('id', 'all') }}
|
||||||
{{ f.submit(
|
{{ f.delete(__('form.delete_all'), {'size': 'sm', 'confirm_title': __('form.delete_all')}) }}
|
||||||
__('form.delete_all'),
|
|
||||||
{'name': 'delete', 'btn_type': 'danger', 'size': 'sm', 'icon_left': 'trash'}
|
|
||||||
) }}
|
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</th>
|
</th>
|
||||||
|
|
Loading…
Reference in New Issue