Now.js Framework Documentation

Now.js Framework Documentation

ImageGallery

EN 05 Apr 2026 10:11

ImageGallery

Overview

ImageGallery is an inline image gallery component for Now.js Framework. It renders a hero image with an optional thumbnail strip, and opens a fullscreen lightbox (via MediaViewer) when the image is tapped or clicked.

When to use:

  • Displaying product or part images inside a card or modal
  • Showing a photo set inside a form or a TemplateManager data-for loop
  • Any place where images need to be browsable inline without navigating away

Why use it:

  • ✅ Fully declarative — HTML only, zero custom JS required
  • ✅ Auto-initialises via ComponentManager (works in templates, modals, API-loaded content)
  • ✅ Multiple transition effects (fade, slide, none)
  • ✅ Flexible thumbnail position (bottom, left, right, top)
  • ✅ Fullscreen zoom via MediaViewer (swipe, pinch, keyboard)
  • ✅ REST API support (data-api)
  • ✅ Touch swipe navigation
  • ✅ Keyboard navigation (← / →)
  • ✅ Responsive with container queries
  • ✅ Accessible (ARIA labels, focus management)

Basic Usage

Static HTML

<div data-component="image-gallery">
  <img src="/images/photo1.jpg" alt="Front view" data-caption="Front view">
  <img src="/images/photo2.jpg" alt="Side view" data-caption="Side view">
</div>

Full-size vs thumbnail URLs

Use data-src for the full-size image. src is displayed as the thumbnail.
If only src is provided, the same URL is used for both.

<div data-component="image-gallery">
  <img src="/thumbs/photo1_sm.jpg" data-src="/images/photo1.jpg" alt="Photo 1" data-caption="Photo 1">
  <img src="/thumbs/photo2_sm.jpg" data-src="/images/photo2.jpg" alt="Photo 2">
</div>

Transition effects

<!-- Fade (default) -->
<div data-component="image-gallery" data-effect="fade">...</div>

<!-- Slide -->
<div data-component="image-gallery" data-effect="slide">...</div>

<!-- No animation -->
<div data-component="image-gallery" data-effect="none">...</div>

Aspect ratio

<!-- Square (1:1) -->
<div data-component="image-gallery" data-aspect="square">...</div>

<!-- Wide (16:9) -->
<div data-component="image-gallery" data-aspect="wide">...</div>

<!-- Tall (3:4) -->
<div data-component="image-gallery" data-aspect="tall">...</div>

<!-- Auto (natural image height) — default -->
<div data-component="image-gallery" data-aspect="auto">...</div>

Thumbnail position

<!-- Bottom (default) -->
<div data-component="image-gallery" data-thumbnails-position="bottom">...</div>

<!-- Left side -->
<div data-component="image-gallery" data-thumbnails-position="left">...</div>

<!-- Right side -->
<div data-component="image-gallery" data-thumbnails-position="right">...</div>

<!-- Top -->
<div data-component="image-gallery" data-thumbnails-position="top">...</div>

Hide thumbnails

Thumbnails are shown automatically when there are 2 or more images.
Set data-show-thumbnails="false" to always hide them.

<div data-component="image-gallery" data-show-thumbnails="false">
  <img src="/images/hero.jpg" alt="Hero">
</div>

Disable fullscreen zoom

<div data-component="image-gallery" data-enable-zoom="false">...</div>

API-Driven Loading

Load images from a REST API endpoint. The component shows a loading indicator while fetching.

<div data-component="image-gallery" data-api="api/parts/images?id=5"></div>
<!-- POST endpoint -->
<div data-component="image-gallery"
     data-api="api/products/gallery"
     data-api-method="POST">
</div>

Expected API response formats

The endpoint can return any of these formats:

["url1.jpg", "url2.jpg"]
[
  { "url": "photo1.jpg", "alt": "Front", "caption": "Front view" },
  { "url": "photo2.jpg", "thumb": "photo2_sm.jpg", "alt": "Side" }
]
{ "data": [ ... ] }
{ "items": [ ... ] }

Item fields: url / src / path, thumb / thumbnail, alt, caption / title.

Usage with TemplateManager

Works inside data-for loops. ComponentManager auto-initialises each gallery after TemplateManager renders the loop.

Single image per card

<div data-for="item in results">
  <div class="product-card">
    <div data-component="image-gallery" data-aspect="square" data-show-thumbnails="false">
      <img data-attr="src:item.image;alt:item.name" data-if="item.image" loading="lazy">
    </div>
    <div data-text="item.name"></div>
  </div>
</div>

Multiple images per item

When the API returns item.images[], use data-for on the <img> elements:

<div data-component="image-gallery" data-effect="fade">
  <img data-for="img in item.images"
       data-attr="src:img.url;alt:img.alt"
       data-attr-extra="data-caption:img.caption"
       loading="lazy">
</div>

Usage inside Modal / ResponseHandler

When the server returns HTML containing data-component="image-gallery" via action.html,
Modal.setContent() inserts the HTML into the DOM and CoreObserver fires ComponentManager
automatically — no extra JS needed.

PHP (Kotchasan controller)

// images array from model
$imgTags = '';
foreach ($part->images as $i => $img) {
    $url = htmlspecialchars($img['url']);
    $imgTags .= '<img src="'.$url.'" data-src="'.$url.'" alt="'.htmlspecialchars($part->name).'">';
}

$html = '<div data-component="image-gallery" data-effect="fade" '
      . 'data-aspect="auto" data-thumbnails-position="bottom" '
      . 'data-show-thumbnails="true" data-enable-zoom="true">'
      . $imgTags
      . '</div>';

// Return as modal action
$this->sendSuccess(['html' => $html, ...]);

Programmatic API

Use ImageGallery.create() when you need to build a gallery entirely from JavaScript.

const gallery = ImageGallery.create(element, {
  images: [
    { url: '/images/photo1.jpg', thumb: '/thumbs/photo1.jpg', alt: 'Photo 1', caption: 'Photo 1' },
    { url: '/images/photo2.jpg', alt: 'Photo 2' }
  ],
  effect: 'slide',
  aspect: 'wide',
  thumbnailsPosition: 'bottom',
  enableZoom: true
});

// Navigate to specific image
gallery.goTo(1);

// Replace all images at runtime
gallery.update(newImages);

// Remove gallery and clean up events
gallery.destroy();

Data Attributes Reference

Attribute Values Default Description
data-effect fade | slide | none fade Transition effect when switching images
data-aspect square | wide | tall | auto auto Hero image aspect ratio
data-show-thumbnails true | false true Show thumbnail strip (hidden when ≤ 1 image)
data-thumbnails-position bottom | left | right | top bottom Position of thumbnail strip
data-enable-zoom true | false true Enable fullscreen zoom via MediaViewer
data-empty-icon CSS icon class icon-picture Icon shown when no images
data-api URL string REST API endpoint to load images from
data-api-method GET | POST GET HTTP method for API request

Image <img> Attributes

Attribute Description
src Thumbnail URL (displayed in the thumbnail strip)
data-src Full-size URL (used in fullscreen viewer). Falls back to src if not set
alt Alt text for accessibility
data-caption Caption shown below hero image. Falls back to alt

Programmatic API Reference

ImageGallery.create(element, options)

Create a gallery programmatically on an existing element.

Parameter Type Description
element HTMLElement Container element
options.images Array Array of image objects
options.effect string fade | slide | none
options.aspect string square | wide | tall | auto
options.showThumbnails boolean Show thumbnail strip
options.thumbnailsPosition string bottom | left | right | top
options.enableZoom boolean Enable fullscreen viewer
options.emptyIcon string CSS class for empty state icon

Returns an instance object with:

Method Description
goTo(index) Navigate to image at index
update(newItems) Replace all images and rebuild
destroy() Remove events and clean up

Keyboard & Touch Controls

Control Action
/ Previous / Next image (when gallery or a child has focus)
Click / Tap hero Open fullscreen MediaViewer
Zoom button (hover) Open fullscreen MediaViewer
Swipe left / right Next / Previous image

CSS Classes Reference

Class Description
.ig Root element
.ig--fade / .ig--slide / .ig--none Active effect modifier
.ig--square / .ig--wide / .ig--tall / .ig--auto Active aspect modifier
.ig--bottom / .ig--left / .ig--right / .ig--top Active thumbnail position
.ig-hero Hero image container
.ig-main-img The displayed <img>
.ig-zoom-btn Fullscreen zoom button (visible on hover)
.ig-caption Caption text below hero
.ig-thumbs Thumbnail strip container
.ig-thumb Individual thumbnail button
.ig-thumb.is-active Currently viewed thumbnail
.ig-empty Modifier when no images
.ig-loading Modifier while loading from API

Integration with MediaViewer

When data-enable-zoom="true" (default), clicking the hero or the zoom button calls
MediaViewer.show() with all images starting at the current index.
MediaViewer provides zoom, pan, keyboard, touch, and autoplay for the fullscreen view.

MediaViewer is loaded automatically as part of the core bundle.