XF 2.2 Opening an image in lightbox

Orit

Active member
Hello :-)
Is there a way to make an image in a template open in lightbox, when clicked?

This is my code. It opens the image in a new tab, not in a lightbox:

HTML:
<a href="{{ link('media/full', $mediaItem) }}" style="cursor: pointer;"
    class="js-lbImage"
    target="_blank"
    data-src="{$mediaItem.lightbox_src}"
    data-type="{$mediaItem.lightbox_type}">               
    <img class="xfmg-image" src="{{ link('media/full', $mediaItem)}}" width="100%" data-zoom-target="1"/>
</a>

Thanks!!
 
There already is a lightbox.
Right, but I think OP is asking how to instantiate the built-in lightbox feature on specific images.

I have been working on this today, and so far this is what I have found:

First, you need to load the lightbox script in the template where you want images to appear in a lightbox:

Code:
        <xf:css src="lightbox.less" />
        <xf:js prod="xf/lightbox-compiled.js" dev="vendor/fancybox/jquery.fancybox.js, xf/lightbox.js" />

        <xf:if is="!page_param('hasLb')">
            <script class="js-extraPhrases" type="application/json">
            {
                "lightbox_close": "{{ phrase('lightbox_close')|escape('js') }}",
                "lightbox_next": "{{ phrase('lightbox_next')|escape('js') }}",
                "lightbox_previous": "{{ phrase('lightbox_previous')|escape('js') }}",
                "lightbox_error": "{{ phrase('lightbox_error')|escape('js') }}",
                "lightbox_start_slideshow": "{{ phrase('lightbox_start_slideshow')|escape('js') }}",
                "lightbox_stop_slideshow": "{{ phrase('lightbox_stop_slideshow')|escape('js') }}",
                "lightbox_full_screen": "{{ phrase('lightbox_full_screen')|escape('js') }}",
                "lightbox_thumbnails": "{{ phrase('lightbox_thumbnails')|escape('js') }}",
                "lightbox_download": "{{ phrase('lightbox_download')|escape('js') }}",
                "lightbox_share": "{{ phrase('lightbox_share')|escape('js') }}",
                "lightbox_zoom": "{{ phrase('lightbox_zoom')|escape('js') }}",
                "lightbox_new_window": "{{ phrase('lightbox_new_window')|escape('js') }}",
                "lightbox_toggle_sidebar": "{{ phrase('lightbox_toggle_sidebar')|escape('js') }}"
            }
            </script>
        </xf:if>
        <xf:page option="hasLb" value="{{ true }}" />

Then, the images have to be wrapped in an a tag and need the bbImage class. I'm still playing around with this, so anyone else feel free to chime in, but I did get this to work (in this case, it displays the thumbnail image from an attachment and loads the full image in the lightbox):

Code:
<a href="{$attachment.direct_url}" target="_blank" class="js-lbImage" data-lb-sidebar-href="" data-lb-caption-extra-html="" data-fancybox="lb-undefined" style="cursor: pointer;" data-caption="">
<img src="{$attachment.thumbnail_url}" alt="{$attachment.filename}"
width="{$attachment.thumbnail_width}" height="{$attachment.thumbnail_height}" class="bbImage" loading="lazy" />
</a>
 
Right, but I think OP is asking how to instantiate the built-in lightbox feature on specific images.

I have been working on this today, and so far this is what I have found:

First, you need to load the lightbox script in the template where you want images to appear in a lightbox:

Code:
        <xf:css src="lightbox.less" />
        <xf:js prod="xf/lightbox-compiled.js" dev="vendor/fancybox/jquery.fancybox.js, xf/lightbox.js" />

        <xf:if is="!page_param('hasLb')">
            <script class="js-extraPhrases" type="application/json">
            {
                "lightbox_close": "{{ phrase('lightbox_close')|escape('js') }}",
                "lightbox_next": "{{ phrase('lightbox_next')|escape('js') }}",
                "lightbox_previous": "{{ phrase('lightbox_previous')|escape('js') }}",
                "lightbox_error": "{{ phrase('lightbox_error')|escape('js') }}",
                "lightbox_start_slideshow": "{{ phrase('lightbox_start_slideshow')|escape('js') }}",
                "lightbox_stop_slideshow": "{{ phrase('lightbox_stop_slideshow')|escape('js') }}",
                "lightbox_full_screen": "{{ phrase('lightbox_full_screen')|escape('js') }}",
                "lightbox_thumbnails": "{{ phrase('lightbox_thumbnails')|escape('js') }}",
                "lightbox_download": "{{ phrase('lightbox_download')|escape('js') }}",
                "lightbox_share": "{{ phrase('lightbox_share')|escape('js') }}",
                "lightbox_zoom": "{{ phrase('lightbox_zoom')|escape('js') }}",
                "lightbox_new_window": "{{ phrase('lightbox_new_window')|escape('js') }}",
                "lightbox_toggle_sidebar": "{{ phrase('lightbox_toggle_sidebar')|escape('js') }}"
            }
            </script>
        </xf:if>
        <xf:page option="hasLb" value="{{ true }}" />

Then, the images have to be wrapped in an a tag and need the bbImage class. I'm still playing around with this, so anyone else feel free to chime in, but I did get this to work (in this case, it displays the thumbnail image from an attachment and loads the full image in the lightbox):

Code:
<a href="{$attachment.direct_url}" target="_blank" class="js-lbImage" data-lb-sidebar-href="" data-lb-caption-extra-html="" data-fancybox="lb-undefined" style="cursor: pointer;" data-caption="">
<img src="{$attachment.thumbnail_url}" alt="{$attachment.filename}"
width="{$attachment.thumbnail_width}" height="{$attachment.thumbnail_height}" class="bbImage" loading="lazy" />
</a>
Thank you ever so much!!
This is so helpful (no idea how I missed your reply...)!

What would I need to change if I don't want the lightbox to display all the images on the page- at once, but rather only the current images in the loop I have?

EDIT: I have it disabled in the options:
1721741624316.webp
 
Last edited:
Thank you ever so much!!
This is so helpful (no idea how I missed your reply...)!

What would I need to change if I don't want the lightbox to display all the images on the page- at once, but rather only the current images in the loop I have?

EDIT: I have it disabled in the options:
View attachment 306894

TLDR; the data-lb-id and data-fancybox must match and must be unique to avoid showing images from all the other lightbox galleries on the page.

For my use case, I didn't want to change how the lightbox operated for the whole site so I had to determine what causes that checkbox option to work.

Specifically, I use this to display a lightbox image gallery for resources that have been uploaded with XFRM, so my template code borrows the resource object. I also place the lightbox thumbnails in search results on the site, so I need a separate lightbox for each search result on the page.

Code:
<div class="js-lbContainer" data-xf-init="lightbox" data-lb-id="resource-{{ $resource.resource_id }}" data-lb-caption-desc="{{ $resource.title }}">
This element is the container for the thumbnail images for the lightbox gallery. If you leave data-lb-id blank or give it a generic name, then the lightbox will display all images from all elements on the page that share that data-lb-id. I have given it a unique id by defining it using the resource's resource_id.

Likewise, your a tags for the individual thumbnails need their data-fancybox to be unique and to match the parent element:
Code:
<a href="{$yourImageUrl}" target="_blank" class="js-lbImage" data-lb-sidebar-href="" data-lb-caption-extra-html="" data-fancybox="resource-{{ $resource.resource_id }}" style="cursor: pointer;" data-caption="{{ $resource.title }}">

In this way, you can have multiple lightboxes on the same page and each will display its own set of images and image gallery thumbnails.
 
Last edited:
TLDR; the data-lb-id and data-fancybox must match and must be unique to avoid showing images from all the other lightbox galleries on the page.

For my use case, I didn't want to change how the lightbox operated for the whole site so I had to determine what causes that checkbox option to work.

Specifically, I use this to display a lightbox image gallery for resources that have been uploaded with XFRM, so my template code borrows the resource object. I also place the lightbox thumbnails in search results on the site, so I need a separate lightbox for each search result on the page.

Code:
<div class="js-lbContainer" data-xf-init="lightbox" data-lb-id="resource-{{ $resource.resource_id }}" data-lb-caption-desc="{{ $resource.title }}">
This element is the container for the thumbnail images for the lightbox gallery. If you leave data-lb-id blank or give it a generic name, then the lightbox will display all images from all elements on the page that share that data-lb-id. I have given it a unique id by defining it using the resource's resource_id.

Likewise, your a tags for the individual thumbnails need their data-fancybox to be unique and to match the parent element:
Code:
<a href="{$yourImageUrl}" target="_blank" class="js-lbImage" data-lb-sidebar-href="" data-lb-caption-extra-html="" data-fancybox="resource-{{ $resource.resource_id }}" style="cursor: pointer;" data-caption="{{ $resource.title }}">

In this way, you can have multiple lightboxes on the same page and each will display its own set of images and image gallery thumbnails.

Thank you so much!
I tried playing around and had a look at the FancyBox documentation.

I added the FancyBox setup using the built in xenforo macro:
HTML:
<xf:macro template="lightbox_macros" name="setup" arg-canViewAttachments="{$canView}" />
(the canViewAttachments argument can probably be hardcoded as true)

My html is:
HTML:
<a href="{$attachment.direct_url}" target="_blank" class="js-lbImage" data-fancybox="gallery--{$thread.thread_id}" style="cursor: pointer;" data-caption="{$attachment.filename}">
    <img src="{$attachment.thumbnail_url}" alt="{$attachment.filename}"
         width="{$attachment.thumbnail_width}" height="{$attachment.thumbnail_height}" class="bbImage" loading="lazy" />
</a>

Lastly, I added the code for my FancyBox setting:
JavaScript:
$(document).ready(function() {
    $(".js-lbImage").fancybox({
        buttons: [
            "zoom",
            "share",
            "slideShow",
            "fullScreen",
            "download",
            "thumbs",
            "close"
        ],
        thumbs: {
            autoStart: true, // Display thumbnails on opening
            axis: 'x' // Display thumbnails at the bottom (horizontal axis)
        },
    });
});

Works perfecly.
Thank you so much!!
 
Back
Top Bottom