added image preview functionality to werk and titelbild

This commit is contained in:
eclipse 2025-06-01 19:50:25 +02:00
parent f84d24243e
commit 35e9e057e7
6 changed files with 88 additions and 28 deletions

View File

@ -225,28 +225,32 @@ label:has([type="radio"]) {
align-content: center; align-content: center;
height: calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2); height: calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2);
padding: var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal); padding: var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal);
}
.imageselect-div { td .imageselect-entry {
display: flex; padding-left: calc(-1 * var(--pico-form-element-spacing-vertical));
align-items: center; }
justify-content: center;
border: var(--pico-border-width) solid var(--pico-table-border-color); .imageselect-div {
cursor: zoom-in; display: flex;
max-height: 100%; align-items: center;
text-align: center; justify-content: center;
width: calc(1rem * var(--pico-line-height));
/* display: block; border: var(--pico-border-width) solid var(--pico-table-border-color);
padding: 0px; cursor: zoom-in;
margin: auto;*/ max-height: 100%;
} text-align: center;
width: calc(1rem * var(--pico-line-height));
}
.imageselect-img, #imagepreview-modal svg {
.imageselect-svg { height: 768px;
object-fit: contain; }
height: calc(1rem * var(--pico-line-height));
} .imageselect-img,
.imageselect-svg {
object-fit: contain;
height: calc(1rem * var(--pico-line-height));
} }
details.imageselect > summary.imageselect-summary { details.imageselect > summary.imageselect-summary {

View File

@ -11,8 +11,15 @@ function initImagepreview(modal_id) {
function handleImagepreview(event) { function handleImagepreview(event) {
let modal = document.getElementById("imagepreview-modal"); let modal = document.getElementById("imagepreview-modal");
modal.querySelector("img").setAttribute("src", event.target.closest(".imageselect-entry").dataset["bild"]); let src = event.target.closest(".imageselect-entry").dataset["bild"];
modal.querySelector(".imagepreview-details").innerText = event.target.closest(".imageselect-entry").querySelector(".imageselect-label").innerText; let img = modal.querySelector("img");
if ( src.toLowerCase().startsWith("<svg") ) { // placeholder svg
modal.querySelector(".imagepreview-details").innerText = "";
modal.querySelector(".imagepreview-div").innerHTML = src
} else { // actual image
modal.querySelector(".imagepreview-details").innerText = event.target.closest(".imageselect-entry").querySelector(".imageselect-label").innerText;
modal.querySelector(".imagepreview-div").innerHTML = `<img src="${src}" />`;
}
modal.showModal(); modal.showModal();
if ( event.target.closest(".imageselect-entry").localName.toLowerCase() == "div" ) { if ( event.target.closest(".imageselect-entry").localName.toLowerCase() == "div" ) {
event.stopPropagation(); event.stopPropagation();

View File

@ -25,7 +25,15 @@
<tbody> <tbody>
{% for titelbild in titelbilder %} {% for titelbild in titelbilder %}
<tr id="titelbild-{{ titelbild['ID'] }}"> <tr id="titelbild-{{ titelbild['ID'] }}">
<td title="Titelbild"><a href="{{ titelbild['Bild'] }}"><img src="{{ titelbild['Thumbnail'] }}" /></a></td> <td title="Titelbild">
<div class="imageselect-entry" data-bild="{{ titelbild['Bild'] }}">
<div class="imageselect-div">
<img src="{{ titelbild['Thumbnail'] }}" width="128" height="128" alt="Titelbild (Thumbnail)" />
<span class="imageselect-label display-none">
{{ titelbild['Dateiname'] }} ({{ titelbild['Breite'] }} x {{ titelbild['Hoehe'] }}, {{ titelbild['Dateigroesse'] }} Bytes)
</span>
</div>
</div>
<td>{{ titelbild["Dateiname"] }}</td> <td>{{ titelbild["Dateiname"] }}</td>
<td>{{ titelbild["Breite"] }}x{{ titelbild["Hoehe"]}}</td> <td>{{ titelbild["Breite"] }}x{{ titelbild["Hoehe"]}}</td>
<td>{{ sizeof_fmt(titelbild["Dateigroesse"]) }}</td> <td>{{ sizeof_fmt(titelbild["Dateigroesse"]) }}</td>
@ -94,12 +102,26 @@
</form> </form>
</article> </article>
</dialog> </dialog>
<dialog id="imagepreview-modal" closedby="any">
<article>
<header>
<button class="modal-close" aria-label="close" rel="prev"></button>
<div class="imagepreview-details"></div>
</header>
<div class="imagepreview-div">
<img src="#" alt="" />
</div>
</article>
</dialog>
{% endblock content %} {% endblock content %}
{% block script %} {% block script %}
<script src="{{ url_for('static', filename='js/datatables.js') }}"></script> <script src="{{ url_for('static', filename='js/datatables.js') }}"></script>
<script src="{{ url_for('static', filename='js/init_dt.js') }}"></script> <script src="{{ url_for('static', filename='js/init_dt.js') }}"></script>
<script src="{{ url_for('static', filename='js/modal.js') }}"></script> <script src="{{ url_for('static', filename='js/modal.js') }}"></script>
<script src="{{ url_for('static', filename='js/imagepreview.js') }}"></script>
<script src="{{ url_for('static', filename='js/fileinput.js') }}"></script> <script src="{{ url_for('static', filename='js/fileinput.js') }}"></script>
<script> <script>
window.onload = function () { window.onload = function () {
@ -107,6 +129,7 @@
initCreateButton("titelbild-table", "titelbild hinzufügen …"); initCreateButton("titelbild-table", "titelbild hinzufügen …");
initModal("titelbild-modal", [], ["Neues Titelbild", "Titelbild bearbeiten"], ["{{ url_for('titelbild.create') }}", "{{ url_for('titelbild.update', id=-1) }}"]); initModal("titelbild-modal", [], ["Neues Titelbild", "Titelbild bearbeiten"], ["{{ url_for('titelbild.create') }}", "{{ url_for('titelbild.update', id=-1) }}"]);
initFileinput("titelbild", "current", "titelbild-modal"); initFileinput("titelbild", "current", "titelbild-modal");
initImagepreview("imagepreview-modal");
} }
</script> </script>
{% endblock script %} {% endblock script %}

View File

@ -51,7 +51,20 @@
<td title="ISSN">{{ werk["ISSN"] }}</td> <td title="ISSN">{{ werk["ISSN"] }}</td>
<td title="Genre(s)">{{ werk["Genre_list"] | join(", ") }}</td> <td title="Genre(s)">{{ werk["Genre_list"] | join(", ") }}</td>
<td title="Herausgeber:in(nen)">{{ werk["Herausgeber_list"] | join(", ") }}</td> <td title="Herausgeber:in(nen)">{{ werk["Herausgeber_list"] | join(", ") }}</td>
<td title="Titelbild">{% if werk["Titelbild"] %}<img src="{{ werk['Titelbild'] }}" width="128" height="128" alt="Titelbild (Thumbnail)" />{% else %}&#10008;{% endif %}</td> <td title="Titelbild">
{% if werk["Titelbild"] %}
<div class="imageselect-entry" data-bild="{{ werk['Titelbild']['Bild'] }}">
<div class="imageselect-div">
<img src="{{ werk['Titelbild']['Thumbnail'] }}" width="128" height="128" alt="Titelbild (Thumbnail)" />
<span class="imageselect-label display-none">
{{ werk['Titelbild']['Dateiname'] }} ({{ werk['Titelbild']['Breite'] }} x {{ werk['Titelbild']['Hoehe'] }}, {{ werk['Titelbild']['Dateigroesse'] }} Bytes)
</span>
</div>
</div>
{% else %}
&#10008;
{% endif %}
</td>
<td title="Klappentext"{% if werk["Klappentext"] %} data-tooltip="{{ werk['Klappentext'] | replace('\n', ' &#13;&#10; ') | safe }}" data-placement="bottom">&#10004;{% else %}>&#10008;{% endif %}</td> <td title="Klappentext"{% if werk["Klappentext"] %} data-tooltip="{{ werk['Klappentext'] | replace('\n', ' &#13;&#10; ') | safe }}" data-placement="bottom">&#10004;{% else %}>&#10008;{% endif %}</td>
<td title="Anmerkungen">{{ werk["Anmerkungen"] }}</td> <td title="Anmerkungen">{{ werk["Anmerkungen"] }}</td>
<td class="action action-update" data-id="{{ werk['id'] }}"><a href="{{ url_for('werk.read', id=werk['id']) }}" title="Werk ansehen/bearbeiten"><svg viewbox="0 0 24 24"><use href="#update" /></svg></a></td> <td class="action action-update" data-id="{{ werk['id'] }}"><a href="{{ url_for('werk.read', id=werk['id']) }}" title="Werk ansehen/bearbeiten"><svg viewbox="0 0 24 24"><use href="#update" /></svg></a></td>
@ -61,16 +74,30 @@
</tbody> </tbody>
</table> </table>
</div> </div>
<dialog id="imagepreview-modal" closedby="any">
<article>
<header>
<button class="modal-close" aria-label="close" rel="prev"></button>
<div class="imagepreview-details"></div>
</header>
<div class="imagepreview-div">
<img src="" />
</div>
</article>
</dialog>
{% endblock content %} {% endblock content %}
{% block script %} {% block script %}
<script src="{{ url_for('static', filename='js/datatables.js') }}"></script> <script src="{{ url_for('static', filename='js/datatables.js') }}"></script>
<script src="{{ url_for('static', filename='js/init_dt.js') }}"></script> <script src="{{ url_for('static', filename='js/init_dt.js') }}"></script>
<script src="{{ url_for('static', filename='js/modal.js') }}"></script> <script src="{{ url_for('static', filename='js/imagepreview.js') }}"></script>
<script> <script>
window.onload = () => { window.onload = () => {
initDataTable("werk-table"); initDataTable("werk-table");
initCreateButton("werk-table", "Werk hinzufügen", "{{ url_for('werk.read', id=0) }}"); initCreateButton("werk-table", "Werk hinzufügen", "{{ url_for('werk.read', id=0) }}");
initImagepreview("imagepreview-modal");
} }
</script> </script>
{% endblock script %} {% endblock script %}

View File

@ -75,7 +75,7 @@ Werk bearbeiten
<summary id="form_Titelbild_summary" class="imageselect-summary"> <summary id="form_Titelbild_summary" class="imageselect-summary">
</summary> </summary>
<ul> <ul>
<li class="imageselect-entry" data-bild=""> <li class="imageselect-entry" data-bild='<svg width="900" height="1280" viewbox="0 0 90 128"><use class="imageselect-svg" href="#placeholder" /></svg>'>
<div class="imageselect-input"> <div class="imageselect-input">
<input id="imageselect-radio-0" type="radio" name="form_Titelbild" value="" {% if not werk['Titelbild'] %}checked{% endif %}/> <input id="imageselect-radio-0" type="radio" name="form_Titelbild" value="" {% if not werk['Titelbild'] %}checked{% endif %}/>
</div> </div>
@ -194,9 +194,7 @@ Werk bearbeiten
<button class="modal-close" aria-label="close" rel="prev"></button> <button class="modal-close" aria-label="close" rel="prev"></button>
<div class="imagepreview-details"></div> <div class="imagepreview-details"></div>
</header> </header>
<div class="imagepreview-div"> <div class="imagepreview-div" />
<img src="#" alt="#" />
</div>
</article> </article>
</dialog> </dialog>

View File

@ -28,7 +28,8 @@ def all():
"ISBN_10": row.Werk.ISBN_10 or "", "ISBN_10": row.Werk.ISBN_10 or "",
"ISSN": row.Werk.ISSN or "", "ISSN": row.Werk.ISSN or "",
"Preis": row.Werk.Preis or "", "Preis": row.Werk.Preis or "",
"Titelbild": url_for("titelbild.thumbnail", id=row.Werk.Titelbild) if row.Werk.Titelbild else "", # "Titelbild": url_for("titelbild.thumbnail", id=row.Werk.Titelbild) if row.Werk.Titelbild else "",
"Titelbild": db.session.get(Titelbild, row.Werk.Titelbild)._asdict_with_urls() if row.Werk.Titelbild else "",
"Klappentext": row.Werk.Klappentext or "", "Klappentext": row.Werk.Klappentext or "",
"Anmerkungen": row.Werk.Anmerkungen or "", "Anmerkungen": row.Werk.Anmerkungen or "",
"Herausgeber_list": [wh.herausgeber.Name for wh in row.Werk.werk_herausgeber], "Herausgeber_list": [wh.herausgeber.Name for wh in row.Werk.werk_herausgeber],