Sekiro's avatar

Images Modal

Hi I want to create a single modal for showing the products images insted of repeating the modal for every single product

                    <td class="text-truncate" style="max-width: 100px;">
                        <!-- Button trigger modal -->
                        <button type="button" class="btn btn-primary" data-toggle="modal"
                            data-target="#ImagesModal">
                            Show
                        </button>
                    </td>

                    <div class="modal fade" id="ImagesModal" tabindex="-1" role="dialog"
                        aria-labelledby="exampleModalLabel" aria-hidden="true">
                        <div class="modal-dialog" role="document">
                            <div class="modal-content">
                                <div class="modal-header">
                                    <h5 class="modal-title" id="exampleModalLabel">Images for {{ $item->name }}
                                    </h5>
                                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                        <span aria-hidden="true">&times;</span>
                                    </button>
                                </div>
                                {{-- Slider --}}
                                <div id="ImageSlider" class="carousel slide" data-ride="carousel">
                                    <div class="carousel-inner">
                                        @foreach ($item->images as $index => $image)
                                            <div class="carousel-item {{ $index === 0 ? 'active' : '' }}">
                                                <img src="{{ asset($image->name) }}" class="w-100"
                                                    alt="Product Image">
                                            </div>
                                        @endforeach
                                    </div>
                                    <a class="carousel-control-prev" href="#ImageSlider" role="button"
                                        data-slide="prev">
                                        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                                        <span class="sr-only">Previous</span>
                                    </a>
                                    <a class="carousel-control-next" href="#ImageSlider" role="button"
                                        data-slide="next">
                                        <span class="carousel-control-next-icon" aria-hidden="true"></span>
                                        <span class="sr-only">Next</span>
                                    </a>
                                </div>

                                <div class="modal-footer">
                                    <button type="button" class="btn btn-secondary"
                                        data-dismiss="modal">Close</button>
                                </div>
                            </div>
                        </div>
                    </div>

Can anyone guide me ?

1 like
2 replies
martinbean's avatar

@sekiro The Bootstrap docs have a section on how to change the modal content based on what trigger is clicked: https://getbootstrap.com/docs/5.3/components/modal/#varying-modal-content

So you’d have a list of thumbnails:

<ul>
  <li>
    <a data-bs-toggle="modal" data-bs-target="#photo-modal" href="full-1.jpg">
      <img src="thumb-1.jpg">
    </a>
  </li>
  <li>
    <a data-bs-toggle="modal" data-bs-target="#photo-modal" href="full-2.jpg">
      <img src="thumb-2.jpg">
    </a>
  </li>
  <li>
    <a data-bs-toggle="modal" data-bs-target="#photo-modal" href="full-3.jpg">
      <img src="thumb-3.jpg">
    </a>
  </li>
</ul>

Add a modal with that ID, and an image to hold the full-sized image:

<div class="modal fade" id="photo-modal" tabindex="-1" aria-labelledby="photo-modal-label" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h1 class="modal-title fs-5" id="photo-modal-label">Photo</h1>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <img src="">
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>

Then some JavaScript that listens on the #photo-modal being triggered so that you can intercept the click, but change the image src to the href of the clicked thumbnail before showing:

var imageModal = document.querySelector('#image-modal');

if (imageModal) {
  var imageModalImage = imageModal.querySelector('.modal-body img');

  imageModal.addEventListener('show.bs.modal', function (event) {
    imageModalImage.src = event.relatedTarget.href;
  });
}

So you’ll now have full-sized images open in a modal if JavaScript is available, or it will gracefully fall back and just navigate to the full-sized image if JavaScript is not available in the user’s browser for whatever reason (they’ve disabled it, there’s an error in your JavaScript bundle, they’re on a ridiculously slow connection, etc).

1 like
Tray2's avatar
Tray2
Best Answer
Level 73

The simplest is to create a dialog element.

<dialog id="my-dialog">
	<img src="" alt="">
</dialog>

<button onclick="showImage('product-1.png')">Show</button> 

Then you can just do something like.

let dialog = document.querySelector('#my-dialog');
let dialogImage = document.querySelector('#my-dialog > img');

function showImage(product) {
	dialogImage.src = `/images/products/${product}`;
    dialog.showModal(); 
}
1 like

Please or to participate in this conversation.