applied latest improvements (fetch API, dedicated "read" endpoint, DataTables) from werk.py|html to corresponding text.*
This commit is contained in:
parent
5093bdd6cd
commit
1eac044e4b
@ -1,23 +0,0 @@
|
|||||||
<script>
|
|
||||||
function showCreateModal() {
|
|
||||||
document.getElementById("dialog-heading").textContent = "Text hinzufügen";
|
|
||||||
document.getElementById("form_Titel").value = "";
|
|
||||||
document.getElementById("form_Untertitel").value = "";
|
|
||||||
document.getElementById('form_Reihe').selectedIndex = "";
|
|
||||||
document.getElementById("form_Textform").selectedIndex = "";
|
|
||||||
document.getElementById("form_Sprache").selectedIndex = "";
|
|
||||||
document.getElementById("form_submit").formAction = "{{ url_for('text.create') }}";
|
|
||||||
document.getElementById("textmodal").showModal();
|
|
||||||
}
|
|
||||||
|
|
||||||
function showUpdateModal(titel, untertitel, reihe, textform, sprache, formaction) {
|
|
||||||
document.getElementById("dialog-heading").textContent = "Text bearbeiten";
|
|
||||||
document.getElementById("form_Titel").value = titel;
|
|
||||||
document.getElementById("form_Untertitel").value = untertitel;
|
|
||||||
document.getElementById('form_Reihe').selectedIndex = reihe;
|
|
||||||
document.getElementById("form_Textform").selectedIndex = textform;
|
|
||||||
document.getElementById("form_Sprache").selectedIndex = sprache;
|
|
||||||
document.getElementById("form_submit").formAction = formaction;
|
|
||||||
document.getElementById("textmodal").showModal();
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@ -2,53 +2,115 @@
|
|||||||
|
|
||||||
{% block title %}Texte{% endblock title %}
|
{% block title %}Texte{% endblock title %}
|
||||||
|
|
||||||
|
{% block script %}<script>
|
||||||
|
const SCRIPT_ROOT = {{ request.script_root | tojson }};
|
||||||
|
const textValues = ["Titel", "Untertitel"];
|
||||||
|
const selectValues = ["Reihe", "Textform", "Sprache"];
|
||||||
|
|
||||||
|
function showCreateModal() {
|
||||||
|
// set modal heading
|
||||||
|
document.getElementById("dialog-heading").textContent = "Text hinzufügen";
|
||||||
|
// empty text inputs
|
||||||
|
for (const v of textValues) { document.getElementById(`form_${v}`).value = ""; }
|
||||||
|
// empty select inputs
|
||||||
|
for (const v of selectValues) { document.getElementById(`form_${v}`).selectedIndex = ""; }
|
||||||
|
// set form action
|
||||||
|
document.getElementById("form_submit").formAction = "{{ url_for('text.create') }}";
|
||||||
|
// show modal
|
||||||
|
document.getElementById("textmodal").showModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
function showUpdateModal() {
|
||||||
|
let id = this.dataset.id;
|
||||||
|
let url = `${SCRIPT_ROOT}/text/read/${id}`;
|
||||||
|
fetch(url)
|
||||||
|
// throw error if network error occurred, get JSON data otherwise
|
||||||
|
.then((response) => {
|
||||||
|
if (response.ok) {
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
throw new Error ("There was an error while fetching data for the text with ID " + id);
|
||||||
|
})
|
||||||
|
// populate modal with response data and raise modal
|
||||||
|
.then(
|
||||||
|
function (response) {
|
||||||
|
console.log(response);
|
||||||
|
// set modal heading
|
||||||
|
document.getElementById("dialog-heading").textContent = "Text ansehen / bearbeiten";
|
||||||
|
// populate text inputs
|
||||||
|
for (const v of textValues) { document.getElementById(`form_${v}`).value = response[v]; }
|
||||||
|
// populate select imputs
|
||||||
|
for (const v of selectValues) { document.getElementById(`form_${v}`).selectedIndex = response[v]; }
|
||||||
|
// set form action
|
||||||
|
document.getElementById("form_submit").formAction = `${SCRIPT_ROOT}/text/update/${id}`;
|
||||||
|
// show modal
|
||||||
|
document.getElementById("textmodal").showModal();
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.catch((error) => console.log(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = function () {
|
||||||
|
// add event listeners
|
||||||
|
document.getElementById ("create-button").addEventListener("click", showCreateModal, false);
|
||||||
|
for (const el of document.querySelectorAll('.action-update') ) {
|
||||||
|
el.addEventListener("click", showUpdateModal, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialise DataTable
|
||||||
|
let table = new DataTable('#text-table', {
|
||||||
|
paging: false,
|
||||||
|
order: []
|
||||||
|
});
|
||||||
|
deRole("#text-table");
|
||||||
|
}
|
||||||
|
</script>{% endblock script %}
|
||||||
|
|
||||||
{% block heading %}Texte{% endblock heading %}
|
{% block heading %}Texte{% endblock heading %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
{% include "_icons.svg" %}
|
{% include "_icons.svg" %}
|
||||||
|
|
||||||
{% include "views/_text.js" %}
|
<section>
|
||||||
|
<button id="create-button" onclick="showCreateModal()" title="Text hinzufügen">
|
||||||
|
<!-- <svg viewbox="0 0 24 24"><use href="#create" /></svg> -->
|
||||||
|
Neu …
|
||||||
|
</button>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section>
|
<table id="text-table">
|
||||||
<button onclick="showCreateModal()" title="Text hinzufügen">
|
<thead>
|
||||||
<!-- <svg viewbox="0 0 24 24"><use href="#create" /></svg> -->
|
<tr>
|
||||||
Neu …
|
<th>Titel</th>
|
||||||
</button>
|
<th>Untertitel</th>
|
||||||
</section>
|
<th>Reihe</th>
|
||||||
|
<th>Textform</th>
|
||||||
<table>
|
<th>Sprache</th>
|
||||||
<thead>
|
<th colspan="2">Aktionen</th>
|
||||||
<tr>
|
</tr>
|
||||||
<th>Titel</th>
|
</thead>
|
||||||
<th>Untertitel</th>
|
<tbody>
|
||||||
<th>Reihe</th>
|
{% for text in texte %}
|
||||||
<th>Textform</th>
|
<tr id="text-{{ text['id'] }}">
|
||||||
<th>Sprache</th>
|
<td title="Titel">{{ text["Titel"] }}</td>
|
||||||
<th colspan="2">Aktionen</th>
|
<td title="Untertitel">{{ text["Untertitel"] }}</td>
|
||||||
</tr>
|
<td title="Reihe">{{ text["Reihe"] }}</td>
|
||||||
</thead>
|
<td title="Textform">{{ text["Textform"] }}</td>
|
||||||
<tbody>
|
<td title="Sprache">{{ text["Sprache"] }}</td>
|
||||||
{% for text in texte %}
|
<td class="action action-update" data-id="{{ text['id'] }}"><a href="#" title="Text ansehen/bearbeiten"><svg viewbox="0 0 24 24"><use href="#update" /></svg></a></td>
|
||||||
<tr id="text-{{ text['id'] }}">
|
<td id="delete-{{ text['id'] }}" class="action"><a onclick="return confirm('Eintrag wirklich löschen?');" href="{{ url_for('text.delete', id=text['id']) }}" title="Text löschen"><svg viewbox="0 0 24 24"><use href="#delete" /></svg></a></td>
|
||||||
<td title="Titel">{{ text["Titel"] }}</td>
|
</tr>
|
||||||
<td title="Untertitel">{{ text["Untertitel"] }}</td>
|
{% endfor %}
|
||||||
<td title="Reihe">{{ text["Reihe"] }}</td>
|
</tbody>
|
||||||
<td title="Textform">{{ text["Textform"] }}</td>
|
</table>
|
||||||
<td title="Sprache">{{ text["Sprache"] }}</td>
|
|
||||||
<td><a onclick="showUpdateModal('{{ text["Titel"] }}', '{{ text["Untertitel"] }}', '{{ text["r_id"] }}', '{{ text["tf_id"] }}', '{{ text["s_id"] }}', '{{ url_for("text.update", id=text["id"]) }}');" href="#" title="Text bearbeiten"><svg viewbox="0 0 24 24"><use href="#update" /></svg></a></td>
|
|
||||||
<td><a onclick="return confirm('Eintrag wirklich löschen?');" href="{{ url_for('text.delete', id=text['id']) }}" title="Text löschen"><svg viewbox="0 0 24 24"><use href="#delete" /></svg></a></td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<dialog aria-labelledby="dialog-heading" id="textmodal">
|
<dialog aria-labelledby="dialog-heading" id="textmodal">
|
||||||
<article>
|
<article>
|
||||||
<form>
|
<form id="text_detail_form" method="post" >
|
||||||
<header>
|
<header>
|
||||||
<button aria-label="close" rel="prev" onclick="textmodal.close()"></button>
|
<button aria-label="close" rel="prev" onclick="textmodal.close()"></button>
|
||||||
<h1 id="dialog-heading">Neuer Text</h1>
|
<h1 id="dialog-heading">#</h1>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
@ -57,43 +119,31 @@
|
|||||||
Titel (erforderlich)
|
Titel (erforderlich)
|
||||||
<input id="form_Titel" name="form_Titel" aria-Label="Titel" placeholder="Titel" required />
|
<input id="form_Titel" name="form_Titel" aria-Label="Titel" placeholder="Titel" required />
|
||||||
</label>
|
</label>
|
||||||
</article>
|
<label>
|
||||||
|
Untertitel
|
||||||
<article>
|
<input id="form_Untertitel" name="form_Untertitel" aria-Label="Untertitel" placeholder="Untertitel" />
|
||||||
<details name="text" open>
|
</label>
|
||||||
<summary>Untertitel und Reihe</summary>
|
<label>
|
||||||
<label>
|
Reihe
|
||||||
Untertitel
|
<select id="form_Reihe" name="form_Reihe" aria-label="Der Text gehört zur Reihe …">
|
||||||
<input id="form_Untertitel" name="form_Untertitel" aria-Label="Untertitel" placeholder="Untertitel" />
|
<option selected value="">keine Reihe</option>
|
||||||
</label>
|
{% for r in reihen %}<option value="{{ r.ID }}">{{ r.Titel }}</option>{% endfor %}
|
||||||
<label>
|
</select>
|
||||||
Reihe
|
</label>
|
||||||
<select id="form_Reihe" name="form_Reihe" aria-label="Der Text gehört zur Reihe …">
|
<label>
|
||||||
<option selected value="">keine Reihe</option>
|
Textform (erforderlich)
|
||||||
{% for r in reihen %}<option value="{{ r.ID }}">{{ r.Titel }}</option>{% endfor %}
|
<select id="form_Textform" name="form_Textform" aria-label="Textform" required>
|
||||||
</select>
|
<option selected disabled value="">Textform auswählen …</option>
|
||||||
</label>
|
{% for tf in textformen %}<option value="{{ tf.ID }}">{{ tf.Textform }}</option>{% endfor %}
|
||||||
</details>
|
</select>
|
||||||
</article>
|
</label>
|
||||||
|
<label>
|
||||||
<article>
|
Sprache (erforderlich)
|
||||||
<details name="text">
|
<select id="form_Sprache" name="form_Sprache" aria-label="Sprache des Textes" required>
|
||||||
<summary>Textform und Sprache</summary>
|
<option selected disabled value="">Sprache auswählen …</option>
|
||||||
<label>
|
{% for s in sprachen %}<option value="{{ s.ID }}">{{ s.Sprache }}</option>{% endfor %}
|
||||||
Textform (erforderlich)
|
</select>
|
||||||
<select id="form_Textform" name="form_Textform" aria-label="Textform" required>
|
</label>
|
||||||
<option selected disabled value="">Textform auswählen …</option>
|
|
||||||
{% for tf in textformen %}<option value="{{ tf.ID }}">{{ tf.Textform }}</option>{% endfor %}
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Sprache (erforderlich)
|
|
||||||
<select id="form_Sprache" name="form_Sprache" aria-label="Sprache des Textes" required>
|
|
||||||
<option selected disabled value="">Sprache auswählen …</option>
|
|
||||||
{% for s in sprachen %}<option value="{{ s.ID }}">{{ s.Sprache }}</option>{% endfor %}
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
</details>
|
|
||||||
</article>
|
</article>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
|||||||
@ -8,30 +8,36 @@ bp = Blueprint("text", __name__)
|
|||||||
@bp.route("/text")
|
@bp.route("/text")
|
||||||
@bp.route("/text/all")
|
@bp.route("/text/all")
|
||||||
def all():
|
def all():
|
||||||
# build ORM equivalent of SELECT statement
|
# select all rows from table "Text", ORM style
|
||||||
stmt = (
|
rows = db.session.execute(select(Text, Reihe, Textform, Sprache).join(Text.reihe, isouter=True).join(Text.textform, isouter=True).join(Text.sprache, isouter=True))
|
||||||
select(Text, Reihe, Textform, Sprache)
|
|
||||||
.join(Text.reihe, isouter=True)
|
|
||||||
.join(Text.textform, isouter=True)
|
|
||||||
.join(Text.sprache, isouter=True)
|
|
||||||
)
|
|
||||||
# condense result into list of dicts
|
# condense result into list of dicts
|
||||||
texte = []
|
texte = []
|
||||||
for row in db.session.execute(stmt):
|
for row in rows:
|
||||||
texte.append({
|
texte.append({
|
||||||
"id": row.Text.ID,
|
"id": row.Text.ID,
|
||||||
"Titel": row.Text.Titel,
|
"Titel": row.Text.Titel,
|
||||||
"Untertitel": row.Text.Untertitel or "",
|
"Untertitel": row.Text.Untertitel or "",
|
||||||
"Reihe": row.Reihe.Titel if row.Reihe else "",
|
"Reihe": row.Reihe.Titel if row.Reihe else "",
|
||||||
"r_id": str(row.Reihe.ID) if row.Reihe else "",
|
"r_id": row.Text.Reihe or "",
|
||||||
"Textform": row.Textform.Textform if row.Textform else "",
|
"Textform": row.Textform.Textform,
|
||||||
"tf_id": str(row.Textform.ID) if row.Textform else "",
|
"tf_id": row.Text.Textform,
|
||||||
"Sprache": row.Sprache.Sprache,
|
"Sprache": row.Sprache.Sprache,
|
||||||
"s_id": str(row.Sprache.ID) if row.Sprache else ""
|
"s_id": row.Text.Sprache
|
||||||
})
|
})
|
||||||
return render_template("views/text.html", texte=texte, reihen=db.session.scalars(select(Reihe)), textformen=db.session.scalars(select(Textform)), sprachen=db.session.scalars(select(Sprache)))
|
return render_template("views/text.html", texte=texte, reihen=db.session.scalars(select(Reihe)), textformen=db.session.scalars(select(Textform)), sprachen=db.session.scalars(select(Sprache)))
|
||||||
|
|
||||||
@bp.route("/text", methods=["POST"])
|
@bp.route("/text/read/<int:id>")
|
||||||
|
def read(id):
|
||||||
|
text = db.session.get(Text, id)
|
||||||
|
return {
|
||||||
|
"Titel": text.Titel,
|
||||||
|
"Untertitel": text.Untertitel or "",
|
||||||
|
"Reihe": text.Reihe or "",
|
||||||
|
"Textform": text.Textform,
|
||||||
|
"Sprache": text.Sprache
|
||||||
|
}
|
||||||
|
|
||||||
|
@bp.route("/text/create", methods=["POST"])
|
||||||
def create():
|
def create():
|
||||||
db.session.add(Text(
|
db.session.add(Text(
|
||||||
Titel = request.form["form_Titel"],
|
Titel = request.form["form_Titel"],
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user