Grid application - lighbox not opening in field

Hi Good People,

Anybody knows how to make lightbox work in grid application. I have a custom code displaying thumbnails but when i click on any thumbnail the expected popup is not working. When i test it on blank application it works. I believe there’s some conflict but I cant figure out workaround.

Lookif there is a javasctipt error when you click the image.

Hi, No errors. Lightbox is not opening when I click on the thumbnails. No response on clicking. Seems like a conflict with Grid but I cannot figure out what I need to do. My declarations and javascript looks like below. It works perfectly in a blank application when I echo $html. But it is not working in the grid application (thumbnails are displaying but lightbox not opening).

$idx = '2678-bae0-bd54632td5e5';
$varvidx = '../_lib/myfolder/media/video.jpg';
$varimages = '../_lib/myfolder/' . $idx;

if (!is_dir($varimages)) {
die('Directory does not exist: ' . htmlspecialchars($varimages));
}

$files = array_diff(scandir($varimages), array('.', '..'));

$allowedTypes = array('jpeg', 'jpg', 'png', 'webp', 'mp4');

$media = array_filter($files, function($file) use ($varimages, $allowedTypes) {
$filePath = $varimages . '/' . $file;
$fileExtension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
$mime = mime_content_type($filePath);
return in_array($fileExtension, $allowedTypes) && (strpos($mime, 'image/') !== false || $fileExtension === 'mp4');
});

 $html .= '<div class="gallery">';

foreach ($media as $file) {
$filePath = $varimages . '/' . $file;
$fileExtension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
$isVideo = ($fileExtension === 'mp4');


$html = '<style> .gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; padding: 10px; } .gallery-item { position: relative; overflow: hidden; cursor: pointer; border-radius: 5px; background: #fff; width: 100%; height: 200px; } .gallery-item img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.3s ease; } .gallery-item:hover img { transform: scale(1.1); } .gallery-item .watermark { position: absolute; top: 20%; left: 50%; transform: translate(-50%, 0); color: #aeb6bf; background: rgba(23, 32, 42, 0.1); padding: 5px; font-size: 11px; text-align: center; z-index: 11; } .gallery-item .play-icon { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 30px; color: red; z-index: 12; } .gallery-item::after { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.3); z-index: 10; pointer-events: none; } .lightbox { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.8); z-index: 1005; display: none; justify-content: center; align-items: center; } .lightbox-content { position: relative; max-width: calc(100vw - 40px); max-height: calc(100vh - 40px); width: auto; height: auto; padding: 20px; box-sizing: border-box; display: flex; justify-content: center; align-items: center; } .lightbox img, .lightbox video { max-width: calc(100% - 40px); max-height: calc(100% - 40px); margin: auto; display: block; } .lightbox .overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0); z-index: 10; pointer-events: none; } .lightbox .watermark { position: absolute; top: 20%; left: 50%; transform: translate(-50%, 0); color: white; background: rgba(0, 0, 0, 0.5); padding: 5px; font-size: 12px; text-align: center; z-index: 11; } .caption { color: white; text-align: center; margin-top: 10px; font-size: 14px; } .lightbox .close { position: absolute; top: 20px; right: 20px; color: white; font-size: 24px; cursor: pointer; z-index: 21; } .lightbox .nav { position: absolute; top: 50%; width: 100%; display: flex; justify-content: space-between; transform: translateY(-50%); z-index: 15; } .lightbox .nav button { background: rgba(0, 0, 0, 0.5); border: none; color: white; font-size: 30px; padding: 10px; cursor: pointer; } .lightbox .nav button:hover { background: rgba(0, 0, 0, 0.7); } </style>';

   
$html .= '<div class="gallery-item" data-file="' . htmlspecialchars($file) . '">';
if ($isVideo) {
    $html .= '<img src="' . htmlspecialchars($varvidx) . '" alt="Video Thumbnail">';
    $html .= '<div class="watermark">Watermark</div>';
    $html .= '<div class="play-icon">▶</div>';
} else {
    $html .= '<img src="' . htmlspecialchars($filePath) . '" alt="Image">';
    $html .= '<div class="watermark">Watermark</div>';
}
$html .= '</div>';
}

$html .= '</div>';

$html .= '<div class="lightbox" id="lightbox">
<span class="close" id="close">&times;</span>
<div class="lightbox-content" id="lightbox-content"></div>
</div>';

$html .= '<script>
const galleryItems = document.querySelectorAll(".gallery-item");
const lightbox = document.getElementById("lightbox");
const lightboxContent = document.getElementById("lightbox-content");
const closeBtn = document.getElementById("close");
let currentIndex = -1;

function openLightbox(index) {
    currentIndex = index;
    const galleryItem = galleryItems[currentIndex];
    const file = galleryItem.getAttribute("data-file");
    const filePath = "' . $varimages . '/" + file;
    const fileExtension = file.split(".").pop().toLowerCase();
    const isVideo = (fileExtension === "mp4");

    if (isVideo) {
        lightboxContent.innerHTML = `<video controls autoplay><source src="${filePath}" type="video/mp4"></video>`;
    } else {
        lightboxContent.innerHTML = `<img src="${filePath}" alt="Image">`;
    }
    lightbox.style.display = "flex";
}

galleryItems.forEach((item, index) => {
    item.addEventListener("click", () => openLightbox(index));
});

closeBtn.addEventListener("click", () => {
    lightbox.style.display = "none";
});

document.addEventListener("keydown", (e) => {
    if (e.key === "Escape") {
        lightbox.style.display = "none";
    }
});
</script>';

 // End of thumbnail grid


// Store the generated HTML in the {myfield} field
{myfield} = $html; //assign to a virtual field

If this code is all the OnRecord event, then that’s the problem.
In the OnRecord event you have to create the HTML to display the item, other code have to be in the OnScriptInit event, and I suggest to inserto any javascript code in a $( document ).ready() function so it’s executed where the page is ready.

Thank you. I couldn’t get this work in Grid application so I worked around using a blank application which is not what I needed.