Issue
It is a template file where I wish to implement: hiding prev arrow on first item, next arrow on last item, and both arrow if single item. I have used bootstrap carousel in angular 12 version.
//html code
<div id="carouselExampleControls" *ngIf="selectedMusic?.type==='image'" class="carousel slide" data-bs-touch="false" data-bs-interval="false" data-bs-wrap=false>
<div class="carousel-inner">
<div class="carousel-item" [ngClass] = "{ active: selectedMusic.src === data, first: first, last: last}" *ngFor="let data of carouselAsset; let first = first; let last = last" >
<img *ngIf="selectedMusic?.type==='image'" [src]="data">
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
The carouselAsset used in the template file, is the collection of image file only after the filter operation achieved on the package module on other file.
//ts code
// For carouselAsset
this.carouselAsset = this.packageDetails.assets.filter(item=>item.fileType==="Images")[0].files.map(itemUrl=>itemUrl.previewUrl);
Solution
from de documentation control via javascript
Bootstrap’s carousel class exposes two events for hooking into carousel functionality. Both events have the following additional properties:
direction: The direction in which the carousel is sliding (either "left" or "right"). relatedTarget: The DOM element that is being slid into place as the active item. from: The index of the current item to: The index of the next itemAll carousel events are fired at the carousel itself (i.e. at the ). Event type Description slide.bs.carousel Fires immediately when the slide instance method is invoked. slid.bs.carousel Fired when the carousel has completed its slide transition.
var myCarousel = document.getElementById('myCarousel') myCarousel.addEventListener('slide.bs.carousel', function () { // do something... })
We know now that it's possible control when the carousel when change. But in Angular we don't usually use docuemnt.getElementById else a template reference variable and Viewchild. Also it's better use fromEvent rxjs operator than addEventListener. So first we are going to give template reference variable to our elements
<div #carousel id="carouselExampleControls" class="carousel slide"..>
<div class="carousel-inner">
<div #item *ngFor="let carousel of carousels; class="carousel-item">
....
</div>
</div>
</div>
See the two references variables carousel and item
The idea is create an observable in ngOnInit to know the "active carousel", so, in ngOnInit
@ViewChildren('item') items:QueryList<ElementRef>
@ViewChild('carousel',{static:true}) carousel!:ElementRef
change$:any //<--our observable
ngOnInit(){
//enclosed under a setTimeout to give Angular time to
//give value to "items" and "carousel"
setTimeout(()=>{
this.items.first.nativeElement.classList.add("active")
this.change$=fromEvent(this.carousel.nativeElement,'slide.bs.carousel').pipe(
startWith({to:0}),
map((res:any)=>res.to))
})
}
See that if we write in our .html some like
Actual slider: {{change$|async}}
We are going to see how goes to 0 to imagenes length-1
Well, we can use this, remove the line before and put the buttons under a ng-container
<ng-container *ngIf="{ item: change$ | async } as actual">
<button
*ngIf="actual.item != 0"
class="carousel-control-prev"
...
>
...
</button>
<button
*ngIf="actual.item < carousels.length - 1"
class="carousel-control-next"
...
>
...
</button>
</ng-container>
(*) the use of the construction *ngIf="{prop:observable|async} as variable is very common and makes that the variable get's the value {prop:0} {prop:1}... etc. This makes not necessary makes two subscription to the observable.
Answered By - Eliseo
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.