Show multi images in a single slider page using ngb-carousel - javascript

I am using Angular 6 and ng-bootstrap and trying for a carousel.
carousel is working fine, but unable to show 4 images in one slider. it's showing 1 image in each slider.
This is the data coming via API response:
games= [{"title_id":1,"title_name":"MIssion Impossible","title_img":"https://media.services.cinergy.ch/media/box1600/f1323e57a2c4ea79dde779a89d561f85bfbe6bf5.jpg","genres":[{"id":1,"name":"Action"},{"id":2,"name":"Adventure"}]},{"title_id":2,"title_name":"Matrix","title_img":"https://www.sideshowtoy.com/assets/products/903302-neo/lg/the-matrix-neo-sixth-scale-figure-hot-toys-903302-01.jpg","genres":[{"id":1,"name":"Action"},{"id":2,"name":"Adventure"},{"id":6,"name":"Fantasy"}]},{"title_id":3,"title_name":"Avengers","title_img":"http://media.comicbook.com/2018/03/avengers-infinity-war-poster-all-iron-man-version-1096449.jpeg","genres":[{"id":1,"name":"Action"},{"id":2,"name":"Adventure"},{"id":6,"name":"Fantasy"}]},{"title_id":4,"title_name":"Stargate SG-1","title_img":"https://image.tmdb.org/t/p/w300_and_h450_bestv2/rst5xc4f7v1KiDiQjzDiZqLtBpl.jpg","genres":[{"id":1,"name":"Action"},{"id":5,"name":"Drama"},{"id":2,"name":"Adventure"},{"id":9,"name":"Sci Fi"}]},{"title_id":5,"title_name":"Scooby Doo","title_img":"https://images-na.ssl-images-amazon.com/images/G/01/aplusautomation/vendorimages/1cdd3ea2-f14f-416b-9aaa-644a9a01ad8c.jpg._CB321085566_.jpg","genres":[{"id":1,"name":"Action"},{"id":10,"name":"Thriller"},{"id":6,"name":"Fantasy"}]}];
here is my component.html code:
<ngb-carousel *ngIf="games" [showNavigationArrows]="showNavigationArrows" [showNavigationIndicators]="showNavigationIndicators">
<ng-template ngbSlide *ngFor="let image of games" style="">
<div class="" style="">
<div class="col-xs-3 col-md-3 col-lg-3 col-sm-6">
<img class="" src="{{image.title_img}}" width="" >
</div>
</div>
</ng-template>
</ngb-carousel>
each image per slide it's coming.
I tried with static images as below,
<ngb-carousel *ngIf="games" [showNavigationArrows]="showNavigationArrows" [showNavigationIndicators]="showNavigationIndicators">
<ng-template ngbSlide style="">
<div class="">
<img src="https://media.services.cinergy.ch/media/box1600/f1323e57a2c4ea79dde779a89d561f85bfbe6bf5.jpg" width="200px" class="img-responsive" style="float:left">
<img src="https://www.sideshowtoy.com/assets/products/903302-neo/lg/the-matrix-neo-sixth-scale-figure-hot-toys-903302-01.jpg" width="200px" class="img-responsive" style="float:left">
<img src="http://media.comicbook.com/2018/03/avengers-infinity-war-poster-all-iron-man-version-1096449.jpeg" width="200px" class="img-responsive" style="float:left">
</div>
</ng-template>
<ng-template ngbSlide style="">
<div class="">
<img src="https://media.services.cinergy.ch/media/box1600/f1323e57a2c4ea79dde779a89d561f85bfbe6bf5.jpg" width="200px" class="img-responsive" style="float:left">
<img src="https://www.sideshowtoy.com/assets/products/903302-neo/lg/the-matrix-neo-sixth-scale-figure-hot-toys-903302-01.jpg" width="200px" class="img-responsive" style="float:left">
<img src="http://media.comicbook.com/2018/03/avengers-infinity-war-poster-all-iron-man-version-1096449.jpeg" width="200px" class="img-responsive" style="float:left">
</div>
</ng-template>
</ngb-carousel>
result is:
But, in mobile it's showing one below one. I need only one image to show, on click on arrow navigation next image should display

Here is one possible solution :
Separate desktop and mobile version :
Separate the desktop version with mobile version, with a ngb-carousel for each version, selected through an *ngIf. The *ngIf checks the variable mobile, defined by (see the html below) :
ngOnInit() {
if (window.screen.width === 360) { // 768px portrait
this.mobile = true;
}
}
More about it in this question.
Slider
For the mobile version, use your code (I integrated it below)
For the desktop with multiple images :
Divide you array, in a multidimensional array (first dimension for slides, second dimension for images). If you have 2 slides of 3 images, your array will be a 2*3 one.
this.games = ["a", "b", "c", "d", "e"];
this.gamesFormatted = [];
var j = -1;
for (var i = 0; i < this.games.length; i++) {
if (i % 3 == 0) {
j++;
this.gamesFormatted[j] = [];
this.gamesFormatted[j].push(this.games[i]);
}
else {
this.gamesFormatted[j].push(this.games[i]);
}
}
Display the carousel with a double loop :
<div *ngIf="games">
<!-- Mobile section : one image per slide -->
<ngb-carousel *ngIf="mobile" [showNavigationArrows]="showNavigationArrows" [showNavigationIndicators]="showNavigationIndicators">
<ng-template ngbSlide *ngFor="let image of games">
<div class="" style="">
<div class="col-xs-3 col-md-3 col-lg-3 col-sm-6">
<img class="" src="{{image.title_img}}">
</div>
</div>
</ng-template>
</ngb-carousel>
<!-- Desktop section : multiple images per slide -->
<ngb-carousel *ngIf="!mobile" [showNavigationArrows]="showNavigationArrows" [showNavigationIndicators]="showNavigationIndicators">
<ng-template ngbSlide *ngFor="let group of gamesFormatted">
<div class="" style="" *ngFor="let game of group">
<img class="" src="{{game.title_img}}">
</div>
</ng-template>
</ngb-carousel>
</div>
I didn't test the html part, so there is surely improvements to do.

Have you tried it like this:
`<ngb-carousel *ngIf="games" [showNavigationArrows]="showNavigationArrows" [showNavigationIndicators]="showNavigationIndicators">
<ng-template ngbSlide style="">
<div class="">
<img src="https://media.services.cinergy.ch/media/box1600/f1323e57a2c4ea79dde779a89d561f85bfbe6bf5.jpg" width="200px" class="img-responsive" style="float:left">
</div>
<div class="">
<img src="https://www.sideshowtoy.com/assets/products/903302-neo/lg/the-matrix-neo-sixth-scale-figure-hot-toys-903302-01.jpg" width="200px" class="img-responsive" style="float:left">
</div>
<div class="">
<img src="http://media.comicbook.com/2018/03/avengers-infinity-war-poster-all-iron-man-version-1096449.jpeg" width="200px" class="img-responsive" style="float:left">
</div>
</ng-template>
</ngb-carousel>
`

Related

Simple picture gallery with enlarged thumbnails with Vue.js

I am trying to implement a simple pictures gallery in my Vue.js app.
This what I am looking for:
User click on a thumbnail and a larger picture is displayed on the right. This is the code I've done so far:
<div class="col-md-6">
<div class="row" id="grid">
<div v-for="(picture, index) in pictures"
:key="picture.pk"
class="col-md-4 my-auto"
>
<div #click="picToShow= index">
<img class="img-thumbnail img-responsive" :src="picture.picture_1">
</div>
</div>
</div>
</div>
<div class="col-6 text-center my-auto">
<div v-for="(picture,index) in pictures"
:key="picture.pk"
class="col-md-4 my-auto"
>
<img v-show="pictToShow == index" :src="picture.picture_1">
</div>
</div>
But as I run it, I get this error :
[Vue warn]: Property or method "pictToShow" is not defined on the
instance but referenced during render. Make sure that this property is
reactive, either in the data option, or for class-based components, by
initializing the property. See:
https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
I do have in my <script>:
data () {
return {
pictures: [],
picToShow: null,
}
},
How can I fix it?
You're making a typo by adding an extra t in v-show="pictToShow == index" which should be v-show="picToShow == index", but I see that it's not a good practice to make two loops, i recommend to keep the first one and use the selected index to show its image :src="pictures[picToShow].picture_1":
<div class="col-md-6">
<div class="row" id="grid">
<div v-for="(picture, index) in pictures"
:key="picture.pk"
class="col-md-4 my-auto"
>
<div #click="picToShow= index">
<img class="img-thumbnail img-responsive" :src="picture.picture_1">
</div>
</div>
</div>
</div>
<div class="col-6 text-center my-auto">
<div v-if="picToShow!==null" class="col-md-4 my-auto">
<img :src="pictures[picToShow].picture_1" />
</div>
</div>

How to make a multi item carousel from materialize(css) cards when the cards data is provided by a loop?

The code here generates a list of cards using the for loop. These cards are to be put in a carousel with 4 cards visible each time and a next arrow button brings the next 4 cards. I have used materialize cards.
'''
<div class="row">
{% for course in course_details %}
<div class="col s3">
<div class="card medium">
<div class="card-image">
<img src="{{ course.0 }}" alt="">
</div>
<div class="card-content">
<p>{{ course.1 }}</p>
</div>
<div class="card-action">
Price
</div>
</div>
</div>
{%endfor%}
</div>
'''
One way to do this:
Create a carousel-slider:
<div class="carousel carousel-slider"></div>
Create a carousel-item for every 4 cards. This is a single slide, and needs also a class of row so that we can use the grid on the cards:
<div class="carousel-item row"></div>
Place your cards:
<div class="col s3"><div class="card blue-grey darken-1"></div></div>
And then initialise:
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.carousel-slider');
var instances = M.Carousel.init(elems); });
https://codepen.io/doughballs/pen/RwrYBYx

How to cycle a class through siblings on an event

I am working on a full screen carousel, I want the captions to be images, I couldn't find an appropriate plugin. So I am building a custom solution.
I figured out how to trigger an event during slide change. Now I want the visible class to cycle through divs with .caption under div.carousel-captions
<div id="mycarousel" class="carousel slide carousel-fade" data-ride="carousel">
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="item">
<img src="images/slide2.jpg" data-color="firebrick" alt="Second Image">
</div>
<div class="item">
<img src="images/slide3.jpg" data-color="violet" alt="Third Image">
</div>
<div class="item">
<img src="images/slide4.jpg" data-color="lightgreen" alt="Fourth Image">
</div>
</div>
</div>
<div class="row">
<div class="carousel-captions">
<div class="caption visible">
<img src="images/banner2-text.png" alt="" class="img-responsive" />
</div>
<div class="caption second">
<img src="images/banner3-text.png" alt="" class="img-responsive" />
</div>
<div class="caption third">
<img src="images/banner4-text.png" alt="" class="img-responsive" />
</div>
</div>
</div>
The first caption is hiding properly with following jquery but how do I cycle through all the captions for each slides.
// Js
$('#myCarousel').on('slid.bs.carousel', function () {
$('.caption.visible').removeClass('visible');
})
Edit (just realized that you're actualy using bootstrap carousel)
Indicate which slide item is currently shown (by :visible or .active class), then grab its index and show .caption at the same index, using .eq(index)
$('#myCarousel').on('slid.bs.carousel', function(){
var i = $('.item.active').index(); // or: $('.item:visible').index();
$('.caption').removeClass('visible').eq(i).addClass('visible');
});
JSFiddle Demo

Unable to load data from Json file

What i'm trying to do is create an image grid layout. Similar to this but in each box is a photo which is loaded from a json file via a HTTP.get
I'm trying to create the grid layout by creating the first row and then using ng-repeat so it creates new rows.
I'm retrieving my images from a $http.get request which loads the images via a JSON file.
I cannot get the images to display and i'm unsure why. I have no errors in my console log.
This is my HTML code so far.
<div class="row" ng-repeat="" ng-if="$index % 1 === 0">
<div class="col col-33" ng-if="$index < length">
<img ng-src="{{image.image}}">
</div>
</div>
The reason your not seeing any images is because your not accessing your data properly in your HTML. Try this:
<div class="row" ng-repeat="image in data.under9s">
<div id="container" class="col col-33" ng-if="$index < data.under9s.length">
<img class="image image-list-thumb" id="image" ng-src="{{image.image}}" />
</div>
<div id="container" class="col col-33" ng-if="$index + 1 < data.under9s.length">
<img class="image image-list-thumb" id="image" ng-src="{{data.under9s[$index + 1].image}}" />
</div>
<div id="container" class="col col-33" ng-if="$index + 2 < data.under9s.length">
<img class="image image-list-thumb" id="image" ng-src="{{data.under9s[$index + 2].image}}" />
</div>
I think you could easily accomplish your grid using two ng-repeats. Something like:
<div class="row" ng-repeat="category in data">
<div ng-repeat="image in category" id="container" class="col col-33">
<img class="image image-list-thumb" id="image" ng-src="{{image.image}}" />
</div>
</div>
That is security issue. Either use jsonp or CORS.

Initialize Slick Slider by the image just clicked

I need a feature to finish my slider image. I've used Slick.js to build my slider and a little HTML and CSS to be displayed inside a modal that is fired up when the user clicks in an static image. Well, I need the first slide shown in the slider to be the one just clicked by the user. I think this is a very common feature in sliders of the world. But I haven't found the way of doing it after a lot of searching. I'm asking because maybe someone has used Slick before and he has had the same situation. I guess the setting I have to play with is initialSlide, but no idea how to store the reference of the image at the same time slider is initialized. I'm aware is a tricky problem but I'm asking just in case.Thank you in advanced
This is how I initialize the slider
<script>
$(document).ready(function(){
$('.slider-gallery').slick({
lazyLoad: 'ondemand',
slidesToShow: 1,
slidesToScroll: 1
});
$(".slick-prev").hide();
$(".slick-next").hide();
});
$('#prev').click(function(){
$(".slider-gallery").slick('slickNext');
});
$('#next').click(function(){
$(".slider-gallery").slick('slickPrev');
});
</script>
This is the html of the static gallery image
<div class="large-6 medium-6 small-12 columns">
<div class="main-img"><a href="#openGallery">
<img src="assets/images/2.png" alt=""></a>
</div>
<div class="thumbnails">
<img class="large-4 medium-4 small-4 columns" src="assets/images/1.png" alt="">
<img class="large-4 medium-4 small-4 columns" src="assets/images/2.png" alt="">
<div class="thumbnail-hover"><a href="#openGallery">
<div class="hover-gallery">23fotos</div>
<img class="large-4 medium-4 small-4 columns" src="assets/images/3.png" alt=""></a>
</div>
</div>
And this the html of the slider
<div id="openGallery" class="item-gallery">
<div class="row">
X
<div class="large-1 medium-1 columns">
<button class="button-slider-gallery previous-button fa fa-chevron-left" id="prev" value="prev"></button>
</div>
<div class="large-10 medium-10 columns">
<div class="slider-gallery">
<div class="image">
<img id="image-slider" class="width-images" data-lazy="assets/images/1.png">
</div>
<div class="image">
<img id="image-slider" class="width-images" data-lazy="assets/images/2.png">
</div>
<div class="image">
<img id="image-slider" class="width-images" data-lazy="assets/images/3.png">
</div>
</div>
</div>
<div class="large-1 medium-1 columns">
<button class="button-slider-gallery next-button fa fa-chevron-right" id="next" value="next"></button>
</div>
</div>
</div>
One way to do so is to use the slickGoTo() function attached to each click on image.
<img class="small-4 columns" src="assets/images/1.png" alt="" onclick="$('.slider-gallery').slickGoTo(0)">
<img class="small-4 columns" src="assets/images/2.png" alt="" onclick="$('.slider-gallery').slickGoTo(1)">
Notes:
The first slide is 0, the second is 1 and so...
You are using Foundation which is awesome. You don't need to add medium-4 and large-4 as you did when you have small-4. The Foundation rule is that "small" = small and larger.
If this is not working try the following syntax instaed:
onclick="$('.slider-gallery').slick('slickGoTo', 0);"
This depends on the slick version you're using.

Categories

Resources