images working, featured still broken
This commit is contained in:
@ -5,6 +5,7 @@
|
||||
<div class="container mt-4">
|
||||
<h2>Edit Plant</h2>
|
||||
|
||||
{# ——— Plant Edit Form ——— #}
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
@ -54,6 +55,7 @@
|
||||
|
||||
<hr>
|
||||
|
||||
{# ——— Upload New Image ——— #}
|
||||
<h4>Upload Image</h4>
|
||||
<form
|
||||
method="POST"
|
||||
@ -68,56 +70,63 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{# ——— Existing Images & Featured Toggle ——— #}
|
||||
<h4>Existing Images</h4>
|
||||
<form method="POST" id="delete-images-form"
|
||||
<form method="POST"
|
||||
id="delete-images-form"
|
||||
action="{{ url_for('media.bulk_delete_media', plant_uuid=plant.uuid) }}"
|
||||
onsubmit="return confirm('Are you sure you want to delete selected images?');">
|
||||
{{ form.csrf_token }}
|
||||
<div class="row">
|
||||
{% for media in plant.media %}
|
||||
{% for media in plant.media_items %}
|
||||
<div class="col-md-3 mb-4">
|
||||
<div class="card h-100">
|
||||
<img
|
||||
id="image-{{ media.id }}"
|
||||
src="{{ generate_image_url(media) }}"
|
||||
src="{{ url_for('media.media_file',
|
||||
context='plants',
|
||||
context_id=plant.id,
|
||||
filename=media.filename) }}"
|
||||
class="card-img-top img-fluid"
|
||||
alt="Plant Image"
|
||||
style="object-fit:cover; height:150px;"
|
||||
>
|
||||
<div class="card-body text-center">
|
||||
|
||||
{# Featured radio driven off media.featured #}
|
||||
<div class="form-check mb-2">
|
||||
<input
|
||||
class="form-check-input featured-radio"
|
||||
type="radio"
|
||||
name="featured_media"
|
||||
value="{{ media.id }}"
|
||||
{% if plant.featured_media_id == media.id %} checked {% endif %}
|
||||
{% if media.featured %}checked{% endif %}
|
||||
data-url="{{ url_for('media.set_featured_image',
|
||||
context='plant',
|
||||
context='plants',
|
||||
context_id=plant.id,
|
||||
media_id=media.id) }}"
|
||||
>
|
||||
<label class="form-check-label">Featured</label>
|
||||
</div>
|
||||
|
||||
<div class="d-grid gap-1">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline-secondary btn-sm rotate-btn"
|
||||
data-url="{{ url_for('media.rotate_media', media_id=media.id) }}"
|
||||
data-id="{{ media.id }}"
|
||||
>Rotate</button>
|
||||
{# Rotate button #}
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline-secondary btn-sm rotate-btn"
|
||||
data-url="{{ url_for('media.rotate_media', media_id=media.id) }}"
|
||||
data-id="{{ media.id }}"
|
||||
>Rotate</button>
|
||||
|
||||
<div class="form-check mt-2">
|
||||
<input class="form-check-input delete-checkbox"
|
||||
type="checkbox"
|
||||
name="delete_ids"
|
||||
value="{{ media.id }}">
|
||||
<label class="form-check-label">Delete</label>
|
||||
</div>
|
||||
{# Delete checkbox #}
|
||||
<div class="form-check mt-2">
|
||||
<input
|
||||
class="form-check-input delete-checkbox"
|
||||
type="checkbox"
|
||||
name="delete_ids"
|
||||
value="{{ media.id }}"
|
||||
>
|
||||
<label class="form-check-label">Delete</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -132,43 +141,42 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
const csrfToken = "{{ form.csrf_token._value() }}";
|
||||
{{ super() }}
|
||||
<script>
|
||||
const csrfToken = "{{ form.csrf_token._value() }}";
|
||||
|
||||
// Rotate
|
||||
document.querySelectorAll('.rotate-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const url = btn.dataset.url;
|
||||
const id = btn.dataset.id;
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'X-CSRFToken': csrfToken }
|
||||
})
|
||||
.then(r => {
|
||||
if (!r.ok) throw Error();
|
||||
const img = document.getElementById(`image-${id}`);
|
||||
img.src = img.src.split('?')[0] + `?v=${Date.now()}`;
|
||||
})
|
||||
.catch(() => alert('Failed to rotate image.'));
|
||||
// Rotate buttons
|
||||
document.querySelectorAll('.rotate-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
fetch(btn.dataset.url, {
|
||||
method: 'POST',
|
||||
headers: { 'X-CSRFToken': csrfToken }
|
||||
})
|
||||
.then(r => {
|
||||
if (!r.ok) throw Error();
|
||||
const img = document.getElementById(`image-${btn.dataset.id}`);
|
||||
img.src = img.src.split('?')[0] + `?v=${Date.now()}`;
|
||||
})
|
||||
.catch(() => alert('Failed to rotate image.'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Feature
|
||||
document.querySelectorAll('.featured-radio').forEach(radio => {
|
||||
radio.addEventListener('change', () => {
|
||||
const url = radio.dataset.url;
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'X-CSRFToken': csrfToken }
|
||||
})
|
||||
.then(r => {
|
||||
if (!r.ok) throw Error();
|
||||
// uncheck all, then check this one
|
||||
document.querySelectorAll('.featured-radio').forEach(r => r.checked = false);
|
||||
radio.checked = true;
|
||||
})
|
||||
.catch(() => alert('Could not set featured image.'));
|
||||
// Featured‐radio AJAX
|
||||
document.querySelectorAll('.featured-radio').forEach(radio => {
|
||||
radio.addEventListener('change', () => {
|
||||
fetch(radio.dataset.url, {
|
||||
method: 'POST',
|
||||
headers: { 'X-CSRFToken': csrfToken }
|
||||
})
|
||||
.then(r => {
|
||||
if (!r.ok) throw Error();
|
||||
// uncheck them all, then check this one
|
||||
document.querySelectorAll('.featured-radio')
|
||||
.forEach(r => r.checked = false);
|
||||
radio.checked = true;
|
||||
})
|
||||
.catch(() => alert('Could not set featured image.'));
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
Reference in New Issue
Block a user