Comments (12)
The example does not show all the option, but it has all boxTemplate
itemTemplate
imageTemplate
and thumbTemplate
. in they belong to the gallery config.
Could you add a reproduction? also have thought about trying v12
from ngx-gallery.
So, itemTemplate
in a galleryConfig added to a lightbox gallery (by ID) should work in v11 with that option just like it did in v9.
I'll see if I can narrow it down and get more information.
from ngx-gallery.
Working through this...
The documentation says:
- itemTemplate: Custom template that overrides any type of item template. (emphasis mine)
The code, however, has:
<ng-container *ngIf="load" [ngSwitch]="type">
<ng-container *ngSwitchCase="Types.Image">
<gallery-image [src]="imageData.src"
[alt]="imageData.alt"
[index]="index"
[loadingAttr]="config.loadingAttr"
[loadingIcon]="config.loadingIcon"
[loadingError]="config.loadingError"
(error)="error.emit($event)"></gallery-image>
<div *ngIf="config.imageTemplate" class="g-template g-item-template">
<ng-container *ngTemplateOutlet="config.imageTemplate; context: imageContext"></ng-container>
</div>
</ng-container>
<gallery-video *ngSwitchCase="Types.Video"
[src]="videoData.src"
[mute]="videoData.mute"
[poster]="videoData.poster"
[controls]="videoData.controls"
[controlsList]="videoData.controlsList"
[disablePictureInPicture]="videoData.disablePictureInPicture"
[play]="isAutoPlay"
[pause]="currIndex !== index"
(error)="error.emit($event)"></gallery-video>
<gallery-iframe *ngSwitchCase="Types.Youtube"
[src]="youtubeSrc"
[autoplay]="isAutoPlay"
[loadingAttr]="config.loadingAttr"
[pause]="currIndex !== index"></gallery-iframe>
<gallery-iframe *ngSwitchCase="Types.Iframe"
[src]="data.src"
[loadingAttr]="config.loadingAttr"></gallery-iframe>
<ng-container *ngSwitchDefault>
<div *ngIf="config.itemTemplate" class="g-template g-item-template">
<ng-container *ngTemplateOutlet="config.itemTemplate; context: itemContext"></ng-container>
</div>
</ng-container>
</ng-container>
The ngIf
for config.itemTemplate
is inside a switch case of ngSwitchDefault
meaning that it doesn't get emitted for "any type of item template" but instead only those that are not image, video, youtube, or iframe.
That should mean that if I instead use imageTemplate
then my caption overlay should appear. It fails, however, because the let-data="data"
is not working. The attempt to access data.caption
throws an "undefined" exception.
The images are added to the gallery with this code:
gallery.addImage({
src: this.urlPrefix + parts[0] + this.urlFullPostfix,
thumb: this.urlPrefix + parts[0] + this.urlThumbPostfix,
caption: captionString,
} as ImageItemData)
What is the new method for accessing arbitrary data fields from within a template?
from ngx-gallery.
When you use itemTemplate
, you are creating your own type, so you also have to define this type when creating new items https://github.com/MurhafSousli/ngx-gallery/wiki/Custom-Templates#galleryitemdef
Therefore, you should use the gallery.ref.add
not addImage
galleryRef.add({
type: 'my-image-template',
data: {
src: 'IMAGE_SRC_URL',
thumb: 'IMAGE_THUMBNAIL_URL'
alt: 'Test'
}
})
and in template
<div *galleryItemDef="let item; let type = type">
<div *ngIf="type === 'my-image-template'">
<img [src]="item.src">
</div>
<div *ngIf="type === 'my-video-template'">
<video>
<source src="item.src">
</video>
</div>
</div>
from ngx-gallery.
I see.
I don't want a custom item since I'm only displaying images so I'll just use imageTemplate
and addImage()
.
This works as expected:
<ng-template #gallerySlide>
<span class="c-img-caption">testing</span>
</ng-template>
But this doesn't, showing nothing:
<ng-template #gallerySlide>
<span *galleryImageDef="let item; let active=active" class="c-img-caption">testing</span>
</ng-template>
As soon as I add *galleryImageDef to any element (span, div, ng-container, etc.), that element and below are not added to the DOM. There are no console messages.
from ngx-gallery.
You don't need to wrap them with ng-template
, the following is sufficient:
<span *galleryImageDef="let item; let active=active" class="c-img-caption">testing</span>
Basically using a star before the directive name is a shortcut to produce
<ng-template>
<span [galleryImageDef]="let item; let active=active" class="c-img-caption">testing</span>
</ng-template>
When querying with ViewChild
just use the directive class
@ViewChild(GalleryImageDef) imageDef: GalleryImageDef;
from ngx-gallery.
In my component's template, I tried:
...
<span *galleryImageDef="let item; let active=active" class="c-img-caption">testing</span>
...
but
@ViewChild(GalleryImageDef) imageDef: GalleryImageDef;
results in undefined. Even if it had been found, I can't assign that to imageTemplate
in setConfig()
because the types don't match: Type GalleryImageDef is missing the following properties from type TemplateRef : elementRef, createEmbeddedView
I tried the "expanded" version with [galleryImageDef]
but that is an error: Property galleryImageDef is not provided by any applicable directives nor by span element
For reference, here is my entire component:
import {AfterViewInit, Component, Input, OnChanges, SimpleChanges, TemplateRef, ViewChild} from '@angular/core';
import {CommonModule} from "@angular/common";
import {Gallery, GalleryState, ImageItemData} from "ng-gallery";
import {Lightbox} from "ng-gallery/lightbox";
import {MatIconModule} from "@angular/material/icon";
import {MatTooltipModule} from "@angular/material/tooltip";
import {AppConstants} from "../AppConstants";
import {ImageThumbnailStripComponent} from "./image-thumbnail-strip/image-thumbnail-strip.component";
const GALLERY_ID = "thumbstrip-gallery"
@Component({
standalone: true,
imports: [CommonModule, ImageThumbnailStripComponent, MatIconModule, MatTooltipModule],
selector: 'lightbox-thumbnail-strip',
template: `
<image-thumbnail-strip [urlPrefix]="urlPrefix" [urlPostfix]="urlThumbPostfix" [imageIds]="imageIds"
[orientation]="orientation">
</image-thumbnail-strip>
<ng-template #gallerySlide>
<span *galleryImageDef="let item; let active=active" class="c-img-caption">testing</span>
<!-- span *ngIf="(data.caption??'')!=''" class="c-img-caption">
{{data.caption}}
</span -->
</ng-template>
<ng-template #galleryBox>
<div class="c-btn c-btn-share-tab" title="Send image to another tab." i18n-title>
<mat-icon class="c-btn-icon" (click)="onShareToTabClicked($event)">open_in_browser</mat-icon>
</div>
</ng-template>
`,
styles: [`
:host, lightbox-thumbnail-strip {
display: block;
height: 100%;
width: 100%;
cursor: pointer;
}
.c-img-caption {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
padding: 0.4rem 1rem 0.4rem 1rem;
background-color: antiquewhite;
border: 1px solid black;
color: black;
border-radius: 1.0rem;
font-size: 1.2rem;
font-style: italic;
font-weight: bold;
}
.c-btn {
position: absolute;
left: 0.9em;
width: 2em;
height: 2em;
z-index: 60;
color: white;
opacity: 0.6;
text-shadow: 0 0 2px rgba(0,0,0,0.8);
transition: opacity linear 0.15s;
cursor: pointer;
}
.c-btn-icon {
width: 2em;
height: 2em;
font-size: 2em;
}
.c-btn:hover {
opacity: 1;
}
.c-btn-share-tab {
top: 0.9em;
left: 0.9em;
}
.c-btn-share-pv {
top: 3.9em;
left: 0.9em;
}
`]
})
export class LightboxThumbnailStripComponent implements AfterViewInit, OnChanges {
@Input() urlPrefix: string = ''
@Input() urlFullPostfix: string = ''
@Input() urlThumbPostfix: string = ''
@Input() imageTags: string[] = []
@Input() orientation: 'h'|'v' = 'h'
@ViewChild(ImageThumbnailStripComponent) thumbnailStrip!: ImageThumbnailStripComponent
@ViewChild('gallerySlide') gallerySlide!: TemplateRef<any>
@ViewChild('galleryBox') galleryBox!: TemplateRef<any>
imageIds: string[] = []
currentIndex: number = 0
constructor(private gallery: Gallery, private lightbox: Lightbox) {
}
ngAfterViewInit(): void {
this.thumbnailStrip.clicked$.subscribe((id: string) => {
this.openLightbox(id)
})
this.gallery.ref(GALLERY_ID).indexChanged.subscribe((state: GalleryState) => {
this.currentIndex = state.currIndex || 0
})
}
ngOnChanges(changes: SimpleChanges) {
this.imageIds = this.imageTags.map(tag => tag.split(':', 1)[0])
}
openLightbox(id: string) {
const gallery = this.gallery.ref(GALLERY_ID)
gallery.reset()
gallery.setConfig({
imageTemplate: this.gallerySlide,
boxTemplate: this.galleryBox,
thumb: this.imageTags.length > 1,
loadingStrategy: "lazy",
slidingDirection: "horizontal",
loop: false,
counterPosition: "top",
nav: true,
dots: false,
autoPlay: false,
})
this.lightbox.setConfig({
hasBackdrop: true,
keyboardShortcuts: true,
panelClass: 'fullscreen',
})
for (let tag of this.imageTags) {
let parts = tag.split(':')
if (parts.length == 1) parts[1] = parts.slice(1).join(':')
gallery.addImage({
src: this.urlPrefix + parts[0] + this.urlFullPostfix,
thumb: this.urlPrefix + parts[0] + this.urlThumbPostfix,
caption: (parts.length > 1) ? parts[1] : '',
} as ImageItemData)
}
for (let i = 0; i < this.imageIds.length; i++) {
if (this.imageIds[i].startsWith(id)) {
this.currentIndex = i
this.lightbox.open(i, GALLERY_ID)
break
}
}
}
onShareToTabClicked($event: MouseEvent) {
let parts = this.imageTags[this.currentIndex].split(':')
if (parts.length == 1) parts[1] = parts.slice(1).join(':')
window.open(`${AppConstants.SHOW_PAGE}?b=${parts[0]+this.urlFullPostfix}&c=${encodeURIComponent(parts[1])}`, 'dimg')
}
}
from ngx-gallery.
Ahhh... This works:
<ng-template #gallerySlide let-data>
<span class="c-img-caption" *ngIf="(data.caption??'')!=''">{{data.caption}}</span>
</ng-template>
from ngx-gallery.
Ofcourse, this code will not work
<ng-template #gallerySlide>
<span *galleryImageDef="let item; let active=active" class="c-img-caption">testing</span>
</ng-template>
Because wrapping content with ng-template
means it will not be rendered, therefore @ViewChild
will return undefined
This is how you should use it
@Component({
standalone: true,
imports: [GalleryModule, CommonModule, ImageThumbnailStripComponent, MatIconModule, MatTooltipModule],
selector: 'lightbox-thumbnail-strip',
template: `
<image-thumbnail-strip [urlPrefix]="urlPrefix" [urlPostfix]="urlThumbPostfix" [imageIds]="imageIds"
[orientation]="orientation">
</image-thumbnail-strip>
<span *galleryImageDef="let item; let active=active" class="c-img-caption">testing</span>
<div *galleryBoxDef class="c-btn c-btn-share-tab" title="Send image to another tab." i18n-title>
<mat-icon class="c-btn-icon" (click)="onShareToTabClicked($event)">open_in_browser</mat-icon>
</div>
`,
})
export class LightboxThumbnailStripComponent implements AfterViewInit, OnChanges {
@ViewChild(GalleryImageDef) imageDef: GalleryImageDef;
@ViewChild(GalleryBoxDef) galleryBox: GalleryBoxDef;
ngAfterViewInit(): void {
this.thumbnailStrip.clicked$.subscribe((id: string) => {
this.openLightbox(id)
})
// Set the config here, you can use setConfig or inside ref function
this.gallery.ref(GALLERY_ID, {
imageTemplate: this.imageDef.templateRef,
boxTemplate: this.galleryBox.templateRef,
loadingStrategy: "lazy",
slidingDirection: "horizontal",
loop: false,
counterPosition: "top",
nav: true,
dots: false,
autoPlay: false,
}).indexChanged.subscribe((state: GalleryState) => {
this.currentIndex = state.currIndex || 0
})
}
openLightbox(id: string) {
const gallery = this.gallery.ref(GALLERY_ID)
gallery.reset()
// Not sure if you need to do it here but you can update the config at any time
gallery.setConfig({
thumb: this.imageTags.length > 1,
})
this.lightbox.setConfig({
hasBackdrop: true,
keyboardShortcuts: true,
panelClass: 'fullscreen',
})
// .....
}
}
Don't forget to import GalleryModule
or its directives individually in the component's imports
from ngx-gallery.
As I said, I tried just
<span *galleryImageDef="let item; let active=active" class="c-img-caption">testing</span>
(no surrounding ) and it wasn't found. Maybe because there was some import
missing but there were no build errors. In addition, I could not pass a variable of the form
@ViewChild(GalleryImageDef) imageDef: GalleryImageDef;
to imageTemplate
because of a type mismatch.
But it does work with just
<ng-template #gallerySlide let-data>
<span class="c-img-caption" *ngIf="(data.caption??'')!=''">{{data.caption}}</span>
</ng-template>
from ngx-gallery.
I just tried it on my end, it works... They all have the same type when you pass the imageDef.templateRef
, maybe you are passing just imageDef
and thus you get type mismatch
If you provide a reproduction stackblitz I can help with it, but if you are good with ng-template
then we can close this I guess
from ngx-gallery.
imageDef.templateRef
would be the difference.
Thanks for all your help!
from ngx-gallery.
Related Issues (20)
- Performance / too many ChangeDetections [ng-gallery < 8.0.0] HOT 2
- Suggestions for Two Additional Thumbnail Features HOT 1
- Gallery Config overwritten in GalleryService `ref` method
- ng-gallery.mjs:287 [NgGallery]: Unable to set the active item because the given index (1) is outside the items range! HOT 2
- Lightbox: Use the native dialog element instead of CDK dialog
- Thumbnails are not aligned at the start HOT 2
- cant install it -new to angular- HOT 1
- Make it possible to use the gallerize directive in a container in which gallery items are added and removed dynamically. HOT 2
- (click) dynamically change class HOT 1
- capture currently visible and clicked image HOT 3
- Fix custom item template documentation
- Lightbox : Wrong image opened using custom imageTemplate HOT 2
- Possible to disable Lightbox features?
- Does NG-gallery support .ogv video files
- My ng-gallery is not loading the main image initially, even with preload HOT 3
- imageSize = cover working as though imageSize = contain selected HOT 8
- Installation guide in wiki missing important part about CDK
- Add corssorigin support
- Does ng-gallery support angular 18+? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ngx-gallery.