I have a gallery of images that load dynamically with Flask. Each image has a bookmark button that updates the database when I click it. The problem is that it renders the template each time I click it and refreshes the page, which is annoying for the user. I don't know much about Javascript/JQuery/Ajax, but I tried to code something by following the Flask documentation. I really don't have a clue if what I did is totally wrong or if I'm close to something. This is my code:
HTML:
<div class="position-relative">
<!-- Loads the image and generates its HTML id (database image id (image[0]) + 'img') -->
<img class="card-img-top card-img-bottom thumb"
src="{{ url_for('static',filename=image[1]) }}" id="{{ image[0] ~ 'img' }}">
</div>
<!-- If image[2] is true the image has already been bookmarked and the bookmark icons loads solid, else it loads regular -->
{% if image[2]: %}
<!-- The divs iconBookb and iconBookn will toggle from display:block to none and vice-versa when the bookmark button is clicked -->
<div id="iconBookb" style="display:block;">
<a class="btn-floating bookmark" id="{{ image[0] ~ 'ims' }}"><i class="fa-solid fa-bookmark"></i></a>
</div>
<div id="iconBookn" style="display:none;">
<a class="btn-floating bookmark" id="{{ image[0] ~ 'imr' }}"><i class="regular fa-bookmark"></i></a>
</div>
{% else %}
<!-- The code after 'else' won't load initially if the image is bookmarked, so there won't be ID conflict with the divs before the 'else' -->
<div id="iconBookb" style="display:block;">
<a class="btn-floating bookmark" id="{{ image[0] ~ 'ims' }}"><i class="fa-regular fa-bookmark"></i></a>
</div>
<div id="iconBookn" style="display:none;">
<a class="btn-floating bookmark" id="{{ image[0] ~ 'imr' }}"><i class="solid fa-bookmark"></i></a>
</div>
{% endif %}
JQuery/AJAX:
$(function() {
$('.bookmark').bind('click', function() {
$.getJSON($SCRIPT_ROOT + '/bookmarking', {
// Gets the id of the 'button' I clicked and removes the last three characters so what's left is the database id of the image
var img_id = $(this).attr('id').slice(0,-3);
// Converts it to an integer (don't know if it's necessary)
image_id: parseInt(img_id)
// Toggle visibility of the divs
}, function() {
$("#iconBookb").toggle();
$("#iconBookn").toggle();
});
});
});
Python code:
@blueprint.route('/bookmark', methods=['GET', 'POST'])
def bookmarking():
image_id = request.args.get('image_id')
image_to_bookmark = db.session.query(AImages).get(image_id)
if not image_to_bookmark.bookmark:
image_to_bookmark.bookmark = True
db.session.commit()
else:
image_to_bookmark.bookmark = False
db.session.commit()