Implement vocab delete in Stimulus

TODO: show modal warning before deleting
This commit is contained in:
Nicolò P 2024-11-09 11:18:45 +01:00
parent dce0e1b693
commit a622b3c256
2 changed files with 96 additions and 24 deletions

View File

@ -18,10 +18,10 @@ export default class extends Controller {
* @todo Simpler way? * @todo Simpler way?
*/ */
edit(event) { edit(event) {
const id = event.currentTarget.getAttribute('data-vocabs-id-value'); const id = event.currentTarget.getAttribute('data-id');
this.saveTargets.forEach((btn, index) => { this.saveTargets.forEach((btn, index) => {
if (btn.getAttribute('data-vocabs-id-value') === id) { if (btn.getAttribute('data-id') === id) {
btn.classList.toggle('is-hidden'); btn.classList.toggle('is-hidden');
this.inputTargets[index].disabled = false; this.inputTargets[index].disabled = false;
this.cancelTargets[index].classList.toggle('is-hidden'); this.cancelTargets[index].classList.toggle('is-hidden');
@ -32,11 +32,11 @@ export default class extends Controller {
} }
async save(event) { async save(event) {
const id = event.currentTarget.getAttribute('data-vocabs-id-value'); const id = event.currentTarget.getAttribute('data-id');
let term = ''; let term = '';
for (let input of this.inputTargets) { for (let input of this.inputTargets) {
if (input.getAttribute('data-vocabs-id-value') === id) { if (input.getAttribute('data-id') === id) {
term = input.value; term = input.value;
} }
} }
@ -45,25 +45,62 @@ export default class extends Controller {
data.append("_id", id); data.append("_id", id);
data.append("_new_term", term); data.append("_new_term", term);
const res = await fetch(this.saveUrlValue, { const url = event.currentTarget.getAttribute('data-url');
const res = await fetch(url, {
method: "POST", method: "POST",
body: data, body: data,
}); });
// TODO: show notification
if (res.status === 200) { if (res.status === 200) {
console.log('Saved...'); let notif = document.getElementById('ajax-saved');
notif.classList.toggle('is-hidden');
}; };
}
delete() { this.cancelTargets.find(btn => btn.getAttribute('data-id') === id)
.classList.toggle('is-hidden');
this.editTargets.find(btn => btn.getAttribute('data-id') === id)
.classList.toggle('is-hidden');
const input = this.inputTargets.find(input => input.getAttribute('data-id') === id)
input.disabled = true;
event.target.classList.toggle('is-hidden');
}
/**
*
* @todo Show modal before deleting! Show delete error (500)!
*/
async delete(event) {
const id = event.currentTarget.getAttribute('data-id');
const url = event.currentTarget.getAttribute('data-url');
let data = new FormData;
data.append("_id", id);
const res = await fetch(url, {
method: "POST",
body: data,
});
if (res.status === 200) {
let notif = document.getElementById('ajax-deleted');
notif.classList.toggle('is-hidden');
this.rowTargets.find(row => row.getAttribute('data-id') === id)
.classList.add('is-hidden');
};
if (res.status === 500) {
let notif = document.getElementById('ajax-error');
notif.classList.toggle('is-hidden');
}
} }
cancel(event) { cancel(event) {
const id = event.currentTarget.getAttribute('data-vocabs-id-value'); const id = event.currentTarget.getAttribute('data-id');
this.editTargets.forEach((btn, index) => { this.editTargets.forEach((btn, index) => {
if (btn.getAttribute('data-vocabs-id-value') === id) { if (btn.getAttribute('data-id') === id) {
btn.classList.toggle('is-hidden'); btn.classList.toggle('is-hidden');
this.inputTargets[index].disabled = true; this.inputTargets[index].disabled = true;
this.saveTargets[index].classList.toggle('is-hidden'); this.saveTargets[index].classList.toggle('is-hidden');

View File

@ -3,7 +3,7 @@
{% block title %}Vocab - Functional context | ArCOA{% endblock %} {% block title %}Vocab - Functional context | ArCOA{% endblock %}
{% block rightpanel %} {% block rightpanel %}
<div class="container" style="max-width: 50vw"> <div class="container" style="max-width: 50vw" data-controller="vocabs">
<h1 class="is-size-1 mt-0 has-text-centered">Vocabulary</h1> <h1 class="is-size-1 mt-0 has-text-centered">Vocabulary</h1>
<h2 class="is-size-3 mt-4 has-text-centered">Functional context</h2> <h2 class="is-size-3 mt-4 has-text-centered">Functional context</h2>
@ -30,8 +30,24 @@
<div class="notification is-success is-hidden mt-5" <div class="notification is-success is-hidden mt-5"
data-controller="notification" data-controller="notification"
data-notification-target=""="notif"> data-notification-target="notif"
id="ajax-saved">
<button class="delete" data-action="click->notification#close"></button> <button class="delete" data-action="click->notification#close"></button>
Term saved successfully
</div>
<div class="notification is-success is-hidden mt-5"
data-controller="notification"
data-notification-target="notif"
id="ajax-deleted">
<button class="delete" data-action="click->notification#close"></button>
Term deleted successfully
</div>
<div class="notification is-danger is-light is-hidden mt-5"
data-controller="notification"
data-notification-target="notif"
id="ajax-error">
<button class="delete" data-action="click->notification#close"></button>
The term could not be deleted because it's related to existing records
</div> </div>
{% for message in app.flashes('notice') %} {% for message in app.flashes('notice') %}
<div class="notification is-success mt-5" data-controller="notification" <div class="notification is-success mt-5" data-controller="notification"
@ -41,14 +57,14 @@
</div> </div>
{% endfor %} {% endfor %}
<h3 class="mt-6 mb-5 is-size-5"><strong>Terms in vocabulary</strong></h3> <h3 class="mt-6 mb-5 is-size-5"><strong>Terms in vocabulary</strong></h3>
<table class="table is-fullwidth" id="terms" data-controller="vocabs"> <table class="table is-fullwidth" id="terms">
<tr><th>Term</th>{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_REVISOR') %}<th>Actions</th>{% endif %}</tr> <tr><th>Term</th>{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_REVISOR') %}<th>Actions</th>{% endif %}</tr>
{% for term in terms %} {% for term in terms %}
<tr data-vocabs-target="row" <tr data-vocabs-target="row"
data-vocabs-id-value="{{ term.id }}"> data-id="{{ term.id }}">
<td> <td>
<input class="input" type="text" value="{{ term.term }}" disabled <input class="input" type="text" value="{{ term.term }}" disabled
data-vocabs-id-value="{{ term.id }}" data-vocabs-target="input" /> data-id="{{ term.id }}" data-vocabs-target="input" />
</td> </td>
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_REVISOR') %} {% if is_granted('ROLE_ADMIN') or is_granted('ROLE_REVISOR') %}
<td> <td>
@ -56,15 +72,15 @@
<button class="button is-primary is-hidden" <button class="button is-primary is-hidden"
data-vocabs-target="save" data-vocabs-target="save"
data-action="click->vocabs#save" data-action="click->vocabs#save"
data-vocabs-saveUrl-value="{{ path('app_vocab_func_context_upd') }}" data-url="{{ path('app_vocab_func_context_upd') }}"
data-vocabs-id-value="{{ term.id }}"> data-id="{{ term.id }}">
Save Save
<span class="icon ml-2"> <span class="icon ml-2">
<i class="fa fa-save"></i> <i class="fa fa-save"></i>
</span> </span>
</button> </button>
<button class="button is-hidden" <button class="button is-hidden"
data-vocabs-id-value="{{ term.id }}" data-id="{{ term.id }}"
data-vocabs-target="cancel" data-vocabs-target="cancel"
data-action="click->vocabs#cancel"> data-action="click->vocabs#cancel">
Cancel Cancel
@ -74,7 +90,7 @@
</button> </button>
<button class="button is-link" <button class="button is-link"
data-vocabs-target="edit" data-vocabs-target="edit"
data-vocabs-id-value="{{ term.id }}" data-id="{{ term.id }}"
data-action="click->vocabs#edit"> data-action="click->vocabs#edit">
Edit Edit
<span class="icon ml-2"> <span class="icon ml-2">
@ -82,9 +98,9 @@
</span> </span>
</button> </button>
<button class="button is-danger" <button class="button is-danger"
data-vocabs-id-value="{{ term.id }}" data-id="{{ term.id }}"
data-action="click->vocabs#delete" data-action="click->vocabs#delete"
data-vocabs-delUrl-value="{{ path('app_vocab_func_context_del') }}"> data-url="{{ path('app_vocab_func_context_del') }}">
Delete Delete
<span class="icon ml-2"> <span class="icon ml-2">
<i class="fa fa-trash"></i> <i class="fa fa-trash"></i>
@ -96,8 +112,27 @@
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
</div>
<div class="modal" data-vocabs-target="modal">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<span class="icon is-large has-text-warning">
<i class="fa fa-warning fa-2x"></i>
</span>
<p class="modal-card-title has-text-danger pl-2"><strong>Delete term?</strong></p>
<button class="delete" aria-label="close"></button>
</header>
<section class="modal-card-body">
<p class="is-size-5">This term will be permanently deleted. Proceed?</p>
</section>
<footer class="modal-card-foot">
<div class="buttons is-right">
<button class="button is-link" data-action="click->vocabs#delete">Confirm</button>
<button class="button is-light" id="cancel">Cancel</button>
</div>
</footer>
</div>
</div> </div>
</div> </div>
<script type="text/javascript" defer></script>
{% endblock %} {% endblock %}