Reputation: 31
For context: I'm building a social network. Just like with Facebook, each profile has a tab titled "images", which is a collection of thumbnails from the profile owner's posts.
My goal: Just like with Facebook, I'd like the user navigating the page to be able to click on any thumbnail image, launching a bootstrap carousel and displaying that specific image in a much larger view. The user could then use the carousel-control class to scroll through the profile owner's other images.
Current situation: The thumbnails display, you can click on any thumbnail and launch the carousel, but all of the profile owner's images appear stacked, as if they're all active.
I'm using a jinja2 for loop and a url_for statement to access the images. I also use a loop counter within an if statement to make it so only one image is active, but its obviously not working :(
It was this 4 year old stackoverflow post that I used to attempt solving this problem to begin with.
When using the carousel with a few images added statically it works properly, but I need it to be dynamic for obvious reasons.
I'm unsure how to go about showing just the specific image that was clicked on, and having the ability to scroll through the others.
Any help will be greatly appreciated!
Here is my HTML
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
{% for post in user.posts %}
{% if post.post_img != None %}
<div class="container">
<div class="item {% if loop.counter == 1 %} active {% endif %}" id="slide{{ loop.counter }}">
<img src="{{ url_for('static', filename='post_pics/' + post.post_img) }}">
</div>
<a class="carousel-control-prev" href="#pageCarousel" role="button" data-slide="prev">
<span class="carousel-control-prev-icon bg-primary" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#pageCarousel" role="button" data-slide="next">
<span class="carousel-control-next-icon bg-primary" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
{% endif %}
{% endfor %}
</div>
</div>
Upvotes: 2
Views: 4862
Reputation: 1387
I was not able to find a complete fully worked out Bootstrap carousel (using Flask/jinja) example out there, but this question/answer helped me, so I'll post mine here - perhaps it can help others.
{% extends "base.html" %}
{% block title %} Our Carousel{% endblock %}
{% block body %}
<div class="p-4 shadow-sm">
<div class="row">
<div class="col">
<h1>Our Carousel</h1>
<div id="ourCarousel" class="carousel slide">
<ol class="carousel-indicators">
{% for i in range(10) %}
<li data-target="#ourCarousel" data-slide-to="{{ i }}"></li>
{% endfor %}
</ol>
<div class="carousel-inner">
{% for record in records %}
<div class="carousel-item {% if loop.index == 1 %} active {% endif %} img-fluid">
<img class="d-block w-100"
src="{{ url_for('.sendImageURL', pflqh=record.ImageID)}}">
<div class="carousel-caption d-none d-md-block">
<a href="{{ url_for('staf.sendImageURL', pflqh=record.ImageID)}}"><h5>{{ record.ParentDirName }} / {{ record.Filename }}</h5></a>
<p>{{ record.DetectedObjects }}</p>
</div>
</div>
{% endfor %}
</div>
<a class="carousel-control-prev" href="#ourCarousel" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#ourCarousel" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>
</div>
{% endblock %}
<script type="text/javascript">
$(document).ready(function () {
$('#ourCarousel').carousel({
wrap: false
})
});
$('#ourCarousel img').click(function () {
console.log("js click test");
});
</script>
Notes:
10 images are sent into this page
I lay down the carousel positional indicators using a loop
the key bit I found in the question/answer above is how to set the first image active, using <div class="carousel-item {% if loop.index == 1 %} active {% endif %} img-fluid">
the function I'm using with url_for (sendImageURL) is a wrapper around the Flask send_from_directory() function, so that I can serve images from a large repository on an NFS share (rather than from /static)
I also provide a URL to the image in the caption so that user can look at the image full frame, outside of the carousel (since a carousel uses clicks on the image to do next/prev, I prefer to make opening the image itself a more explicit action)
for the caption I'm using the result of an object detection model whose results are available in the record (not relevant to carousels, just FYI)
I tried many different ways to get the image sizing right - ultimately the use of img-fluid and d-block w-100 (as shown in the code above) gave me the best results, given that my images are all of different sizes and vary in aspect ratio
base.html includes the bootstrap and jquery imports after the <body>
, so the javascript here also has to be after the body (or else it will be loaded before jquery is available and you'll get the cryptic $ is not defined
error
Note that the second bit of javascript doesn't seem to work ($('#ourCarousel img').click(function ()
) perhaps someone can suggest a fix there (possible that it needs to be in the body)
the only css I added was to put a background on the caption, with:
.carousel-caption {
background: rgba(0, 0, 0, 0.35);
}
(this was added to base.html)
Upvotes: 0
Reputation: 1632
You can move the a
tags outside the inner-carousel
div
, maybe like below ( its untested)
If you look at the documentaion, the a
tags have to be outside.
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
{% for post in user.posts %}
{% if post.post_img != None %}
<div class="carousel-item {% if loop.index == 1 %} active {% endif %}" id="slide{{ loop.index }}">
<img src="{{ url_for('static', filename='post_pics/' + post.post_img) }}">
</div>
{% endif %}
{% endfor %}
</div>
<a class="carousel-control-prev" href="#pageCarousel" role="button" data-slide="prev">
<span class="carousel-control-prev-icon bg-primary" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#pageCarousel" role="button" data-slide="next">
<span class="carousel-control-next-icon bg-primary" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
Upvotes: 3