I created the following array that contains images with angularJS:
$scope.docImg = [
'../../Content/Image/BackGrounds/abra.png',
'../../Content/Image/BackGrounds/background_black.jpg',
'../../Content/Image/BackGrounds/halloween.jpg',
'../../Content/Image/BackGrounds/registration.jpg',
]
I displayed them by using ng-repeat and Bootstrap 5
<div class="#colmode mh-100 mt-4" ng-show="docImg.length>0">
<div class="card bg-dark h-100 border-eniac">
<div class="card-header bg-eniac d-flex justify-content-between">
#Global.Images
<i class="fas fa-file"></i>
</div>
<div class="card-body container">
<div class="row col-12">
<div ng-repeat="a in docImg" class="col-4">
<div id="{{a.Id}}" class="img-container">
<img ng-src="{{a}}" class="img-fluid" data-bs-toggle="modal" data-bs-target="#docImgModal"/>
</div>
</div>
</div>
</div>
</div>
</div>
These are small images, but I want to display them in large size too and I thought I am going to use Modals for this purpose.
So I want to create a bootstrap modal that displays the clicked and only the clicked image, and this is where I got stuck: I can display the images if I put the modal in the loop, but then obviously it displays all the images at the same time, which I don't want.
Modal that doesn't work well:
<div class="modal fade" id="docImgModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<img ng-src="{{a}}">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
What I want to do: Create a Modal or a function that takes and displays only the image that I clicked on. Maybe using a dynamically changing id, but I am open to other ideas too.
The images in the loop:
The issue: ( It displays all the images from the loop )
PS.: The reason I am using AngularJS - This is an older project, so I have no choice.
If my question is not understandable please ask, or tell me how could I explain it better. I am always open to constructive critics.
Your idea of using dynamically changing id is already correct.
Here, I only copy pasted your code, put your modal inside your loop, add dynamic index to the id and data-bs-target of docImgModal.
And it works!
<div class="#colmode mh-100 mt-4" ng-show="docImg.length>0">
<div class="card bg-dark h-100 border-eniac">
<div class="card-header bg-eniac d-flex justify-content-between">
#Global.Images
<i class="fas fa-file"></i>
</div>
<div class="card-body container">
<div class="row col-12">
<div ng-repeat="(idx, a) in docImg" class="col-4">
<div id="img{{idx}}" class="img-container">
<img ng-src="{{a}}" class="img-fluid h-50" data-bs-toggle="modal" data-bs-target="#docImgModal{{idx}}"/>
</div>
<div class="modal fade" id="docImgModal{{idx}}" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<img ng-src="{{a}}">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
You should probably dynamic change the src of the image inside the modal.
With something similar to this:
$('#modal').on('show.bs.modal', function (e) {
// the clicked element is available as the relatedTarget property of the event
var src = $(e.relatedTarget).attr('src');
$(this).find('.modal-body > img').attr('src', src);
});
this is JQuery btw, found at another post
Or you could use some lightbox library like fslightbox. I would use a library because, besides the dynamic changing, it handles a lot more features such as full screen, gallery if needed, and more.
I added the features you needed, you may change it to make it more suitable!
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.docImg = [
'https://docs.juliahub.com/TestImages/cMlD2/1.6.1/thumbnails/airplaneF16.png',
'https://docs.juliahub.com/TestImages/cMlD2/1.6.1/thumbnails/barbara_color.png',
'https://docs.juliahub.com/TestImages/cMlD2/1.6.1/thumbnails/chelsea.png',
'https://docs.juliahub.com/TestImages/cMlD2/1.6.1/thumbnails/coffee.png',
]
});
const exampleModal = document.getElementById('docImgModal')
exampleModal.addEventListener('show.bs.modal', function (event) {
const imgElement = event.relatedTarget
const imgSrc = imgElement.getAttribute('src')
const modalImgElement = exampleModal.querySelector('#modal-img')
modalImgElement.src = imgSrc
})
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<div ng-app="myApp" ng-controller="myCtrl">
<div class="#colmode mh-100 mt-4" ng-show="docImg.length>0">
<div class="card bg-dark h-100 border-eniac">
<div class="card-header bg-eniac d-flex justify-content-between">
#Global.Images
<i class="fas fa-file"></i>
</div>
<div class="card-body container">
<div class="row col-12">
<div ng-repeat="a in docImg" class="col-4">
<div id="{{a.Id}}" class="img-container">
<img ng-src="{{a}}" class="img-fluid" data-bs-toggle="modal" data-bs-target="#docImgModal"/>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="docImgModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<img id="modal-img" src="">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
Related
This concept is based on the post Multiple modals overlay
I am trying to create a folder modal, and within every folder modal the user should be able 1) open existing
or
2) create a new file modal
Please run the code below to understand how it works. You will have to click buttons and the list items for opening the modals
But this operates in a bootstrap full screen mode instead of dialog
Clicking on the button creates a folder in the list
When you click the "This is folder ###" it opens a modal as shown below
Now I could create a file
The issue is that needs to be fixed is when file item is cliked, the file modal should overlay on top of the folder modal, But now its closing and both modals wont stay.
<!doctype html>
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous" -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
</head>
<body>
<button class="btn btn-primary" id="addnewfolder">Create new folder</button>
<ul class="list-group folder"></ul>
<script>
$("#addnewfolder").click(function(event) {
var code = (Math.random() + 1).toString(36).substring(7)
$(".folder").append(`<li class="list-group-item">
<img src="https://img.icons8.com/officel/48/null/live-folder.png" class="float-start" />
<div class="ms-5" data-bs-toggle="modal" href="#modal-toggle-${code}">This is folder ${code}<br />
<div>
<div class="modal fade" id="modal-toggle-${code}" aria-hidden="true" aria-labelledby="modal-toggleLabel" tabindex="-1">
<div class="modal-dialog modal-fullscreen">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="modal-toggleLabel">Inside Folder ${code}</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<ul class="list-group file"></ul>
<button data-bs-target="#modal-toggle2" data-bs-toggle="modal" class="btn btn-primary file-${code}">Add File Inside ${code}</button>
</div>
<div class="modal-footer">
<button class="btn btn-primary">Save</button>
</div>
</div>
</div>
</div>
</div>
</div>
</li>`);
//$(`#modal-toggle-${code}`).modal("show");
$(`.file-${code}`).click(function(event) {
var dcode = Math.floor(Math.random() * 10);
$(".file").append(`<li class="list-group-item">
<img src="https://img.icons8.com/cotton/64/null/happy-file.png" class="float-start" />
<div class="ms-5">This is file inside ${code}-${dcode}<br />
<small class="text-secondary">This is a ${code}-${dcode} item description</small>
<div>
<div class="modal fade" id="modal-toggle-${code}-${dcode}" aria-hidden="true" aria-labelledby="modal-toggleLabel" tabindex="-1">
<div class="modal-dialog modal-fullscreen">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="modal-toggleLabel">Inside Folder</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Hello World
</div>
<div class="modal-footer">
<button class="btn btn-primary">Save</button>
</div>
</div>
</div>
</div>
</div>
</div>
</li>`);
//$(`#modal-toggle-${code}-${dcode}`).modal("show");
});
});
$(document).on('show.bs.modal', '.modal', function() {
const zIndex = 1040 + 10 * $('.modal:visible').length;
$(this).css('z-index', zIndex);
setTimeout(() => $('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack'));
});
</script>
</body>
Don't stack Bootstrap modals.
Bootstrap only supports one modal window at a time. Nested modals
aren’t supported as we believe them to be poor user experiences.
https://getbootstrap.com/docs/5.2/components/modal/#how-it-works
Toggle between multiple modals with some clever placement of the
data-bs-target and data-bs-toggle attributes. Please note multiple
modals cannot be open at the same time—this method simply toggles
between two separate modals.
https://getbootstrap.com/docs/5.2/components/modal/#toggle-between-modals
Therefore toggle the modals instead of stacking them. Better UX and no need for any z-index tricks.
Your issue.
With that out of the way, the reason why the modal is closing when clicking the "Add File" button is because...
<button data-bs-target="#modal-toggle2" data-bs-toggle="modal" class="btn btn-primary file-${code}">Add File Inside ${code}</button>
...you have a data-bs-target & -toggle on your button that creates a new 'file'. This will toggle modal #modal-toggle2, and since it doesn't exists on your page you get the error of an undefined modal.
You also have a few typos, like forgetting to close a <div> in a few places.
Your solution...
Appends the modal to the body, not the <li> element.
Uses the data attributes data-bs-target and data-bs-toggle to toggle the modals.
Features a "Go back to folder" button when accessing the 'file' modal.
$(document).ready(function() {
$("#addnewfolder").click(function() {
var code = (Math.random() + 1).toString(36).substring(7)
$(".folder").append(`
<li class="list-group-item" data-bs-toggle="modal" data-bs-target="#modal-${code}">
<img src="https://img.icons8.com/officel/48/null/live-folder.png" class="float-start" />
<div class="ms-5">This is folder ${code}</div>
</li>
`);
$('body').append(`
<div class="modal fade" id="modal-${code}" tabindex="-1" aria-labelledby="modal-${code}-label" aria-hidden="true">
<div class="modal-dialog modal-fullscreen">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modal-${code}-label">Folder ${code}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<button class="btn btn-primary file-${code}">Add new File</button>
<ul class="list-group file"></ul>
</div>
<div class="modal-footer">
<button class="btn btn-primary">Save</button>
</div>
</div>
</div>
</div>
`)
$(`.file-${code}`).click(function() {
var dcode = Math.floor(Math.random() * 10);
$(this).closest('.modal').find('.file').append(`
<li class="list-group-item" data-bs-toggle="modal" data-bs-target="#modal-${code}-${dcode}">
<img src="https://img.icons8.com/cotton/64/null/happy-file.png" class="float-start" />
<div class="ms-5">
This is file inside ${code}-${dcode}
<br>
<small class="text-secondary">This is a ${code}-${dcode} item description</small>
</div>
</li>
`)
$('body').append(`
<div class="modal fade" id="modal-${code}-${dcode}" tabindex="-1" aria-labelledby="modal-${code}-${dcode}-label" aria-hidden="true">
<div class="modal-dialog modal-fullscreen">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modal-${code}-${dcode}-label">File ${code}-${dcode}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Hello World</p>
</div>
<div class="modal-footer">
<button class="btn btn-primary">Save</button>
<button type="button" class="btn btn-secondary" data-bs-toggle="modal" data-bs-target="#modal-${code}" >Go back to folder ${code}</button>
</div>
</div>
</div>
</div>
`)
})
})
})
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<button class="btn btn-primary" id="addnewfolder">Create new folder</button>
<ul class="list-group folder"></ul>
If you also want the top-right close button (X) in the 'File' modal to act as going back to the 'folder' modal, simply do:
<button type="button" class="btn-close" data-bs-toggle="modal" data-bs-target="#modal-${code}" aria-label="Close"></button>
I have three divs each looking like this
<div class="col-lg-6 col-md-6 col-sm-12 mb-4">
<div class="card">
<div class="card-body b-primary">
<div class="row justify-content-center">
<div class="col-md-5 col-sm-12">
<img src="assets/images/gateway/61eedfd72289f1643044823.jpg" class="card-img-top w-100"
alt="Stripe">
</div>
<div class="col-md-7 col-sm-12">
<ul class="list-group text-center">
<li class="list-group-item">Stripe</li>
<li class="list-group-item">Limit : 50- 50000 USD</li>
<li class="list-group-item"> Charge - 0 USD+ 0% </li>
<li class="list-group-item">
<button type="button" data-id="str"
data-base_symbol="" class=" btn deposit cmn-btn w-100" data-toggle="modal"
data-target="#exampleModal">
Deposit</button>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
i have identified and differentiated each of the 3 divs using data-id now when the deposit button is clicked it opens up this modal below,
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content modal-content-bg">
<div class="modal-header">
<strong class="modal-title method-name text-white" id="exampleModalLabel">Input Deposit Amount</strong>
<a href="javascript:void(0)" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</a>
</div>
<form action=" {{ route('deposit_request') }}" method="post" class="register">
#csrf
<div class="modal-body">
<div class="form-group">
<input type="hidden" name="method_code" class="edit-method-code" value="">
<x-jet-validation-errors class="mb-4" />
#include('flash-message')
</div>
<div class="form-group">
<label>Enter Amount:</label>
<div class="input-group">
<input id="amount" type="text" class="form-control form-control-lg" name="usdamt"
placeholder="0.00" required="" autocomplete="off">
<div class="input-group-prepend">
<span class="input-group-text currency-addon addon-bg">USD</span>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-md btn-danger" data-dismiss="modal">Close</button>
<button type="submit" class="btn-md cmn-btn">Next</button>
</div>
</form>
</div>
</div>
</div>
now my question is how do I get the data-id variable to the hidden input in the modal to be able to identify which particular payment method was/is been used to open the modal, I suppose it can be done with Ajax or JavaScript, but not being so diverse in this areas I can seem to get it sorted out and is there a better way to differentiate the divs without using data-id
Bootstrap provides events of their modals.
The event I used here is show.bs.modal. The event details has a property called relatedTarget which tells you what prompted the modal event.
From that element you can extract the data-id attribute.
$('#exampleModal').on('show.bs.modal', function (e) {
var data_id = $(e.relatedTarget).data('id');
console.log(data_id);
})
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-id="MAGIC" data-toggle="modal" data-target="#exampleModal">
Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModal" 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">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
There could be multiple solutions, but you could implement event delegation here.
Move the click event handler up to the parent div element containing all these buttons.
In your event listener, you could do something like this:
let selectedPaymentMethod = "";
const paymentClickHandler = (event) => {
// get the element
const buttonClicked = event.target;
// there are several to check if it's button, i'm using classList
if (buttonClicked && buttonClicked.classList.contains("btn")) {
// there are multiple ways to handle this
// if (buttonClicked.classList.contains('stripe')) payingUsingStripe();
// if (buttonClicked.dataset.paymentmethod === 'stripe') payingUsingStripe();
// I would do something like below
setPaymentMethod(buttonClicked.dataset.paymentmethod);
displayModal();
}
};
function setPaymentMethod(paymentMethod) {
// do some checks to ensure valid value and then
selectedPaymentMethod = paymentMethod;
}
CodeSandbox to demonstrate above.
Hope it helps.
I simply copied the example from Bootstrap 5 docs, but the first modal is not hidden if I open the 2nd modal from within the modal popup. Why?
You can see that the backdrop is also a bit darker for the 2nd popup, which is because the 2nd one is simply overlayed on the 1st one, without hiding the prior modal.
I also tried it locally with same result: the 1st modal is never hidden.
Interestingly it works as expected on the bootstrap docs website...
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.2/dist/css/bootstrap.min.css" integrity="sha384-uWxY/CJNBR+1zjPWmfnSnVxwRheevXITnMqoEIeG1LJrdI0GlVs/9cVSyPYXdcSF" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-kQtW33rZJAHjgefvhyyzcGF3C5TFyBQBA13V1RKPf4uH+bwyzQxZ6CmMZHmNBEfJ" crossorigin="anonymous"></script>
<a class="btn btn-primary" data-bs-toggle="modal" href="#exampleModalToggle" role="button">Open first modal</a>
<div class="modal fade" id="exampleModalToggle" aria-hidden="true" aria-labelledby="exampleModalToggleLabel" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalToggleLabel">Modal 1</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Show a second modal and hide this one with the button below.
</div>
<div class="modal-footer">
<button class="btn btn-primary" data-bs-target="#exampleModalToggle2" data-bs-toggle="modal" data-bs-dismiss="modal">Open second modal</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="exampleModalToggle2" aria-hidden="true" aria-labelledby="exampleModalToggleLabel2" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalToggleLabel2">Modal 2</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Hide this modal and show the first with the button below.
</div>
<div class="modal-footer">
<button class="btn btn-primary" data-bs-target="#exampleModalToggle" data-bs-toggle="modal" data-bs-dismiss="modal">Back to first</button>
</div>
</div>
</div>
</div>
https://jsfiddle.net/neog0236/1/
I see that your JSFiddle demo uses an older library version. When I update that it works. See the Highlights section of the 5.1.1 release notes.
var myModalEl = document.querySelector('#scheduleMeetingModal');
var myModal = bootstrap.Modal.getOrCreateInstance(myModalEl);
myModal.hide();
I list out my users. It works perfectly, every user has their own Bootstrap card. But when I click on "more" to trigger the Modal, every "more" button gives the same Modal, which is the pop-up window for User #1. So no matter which user's data interests me, it always shows the same Modal. I want it to work properly, so that whenever I click on the more button the window pops up with that user's data.
<div th:each="user : ${listUsers}" class="card mb-3">
<div class="row g-0">
<!-- <div class="col-md-3">
<img src="/images/noimage2.png" alt="...">
</div>-->
<div class="col-md-12">
<div class="card-body">
<h3 class="card-title"
th:text="${user.name}">Name</h3>
<!-- Button trigger modal -->
<button type="button" class="btn btn-secondary btn-sm"
data-bs-toggle="modal" data-bs-target="#exampleModal">
<i class="fas fa-address-card"></i> More
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1"
aria-labelledby="exampleModalLabel" aria-hidden="true">
<div
class="modal-dialog modal-dialog-scrollable modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel"
th:text="${user.name}">Modal title</h5>
<button type="button" class="btn-close"
data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<span class="d-inline"
th:text="${user.address}"></span> | <span
th:text="${user.phoneNumber}"></span> | <span
th:text="${user.email}">email</span>
</div>
<p class="card-body"
th:text="${user.description}"></p>
</div>
<div class="modal-footer"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<p>
</div>
All of your buttons are targetting #exampleModal -- you can see here:data-bs-target="#exampleModal". If you want the buttons to work, you need to give each of your modals a unique id and then target the correct modal with the correct button. So...
Add the status variable onto your loop.
<div th:each="user, status : ${listUsers}" class="card mb-3">
Use the ${status.index} variable to create a unique id for your target:
<button type="button" class="btn btn-secondary btn-sm"
data-bs-toggle="modal" th:data-bs-target="|#userModal${status.index}|">
<i class="fas fa-address-card"></i> More
</button>
Use the ${status.index} variable to create a unique id for your modal:
<div class="modal fade" th:id="|#userModal${status.index}|" tabindex="-1"
aria-labelledby="exampleModalLabel" aria-hidden="true">
I have a modal stacked on top of another modal. How can I position the second modal on top of the first modal? See jsFiddle here.
The problem I am currently having is positioning the second modal exactly on top of the first modal. The first modal seem to ignore the space occupied by the scroll bar, however the second modal doesn't and as a result the second modal appeared to have shifted to the right and smaller than the first modal (just my assumption).
I tried adding the following but doesn't work:
.modal-content {
margin: auto !important;
}
if you set modal-content height to 368px this will work, as this is the size of the first popup modal.
.modal-content {
min-height: 368px;
}
See updated jsfiddle here.
// bootstrap 3.3.6
// jquery 2.2.1
// fontawesome 4.5.0
/*
MODAL STACKING
*/
// Backdrop z-index fix
$(document).on('show.bs.modal', '.modal', function () {
var zIndex = 1040 + (10 * $('.modal:visible').length);
$(this).css('z-index', zIndex);
setTimeout(function() {
$('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack');
}, 0);
});
// Scrollbar fix
$(document).on('hidden.bs.modal', '.modal', function () {
$('.modal:visible').length && $(document.body).addClass('modal-open');
});
.modal-content {
margin: auto !important;
min-height: 368px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet"/>
<section id="services" class="padding-bottom">
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h1 class="section-heading turquoise">At Your Service</h1>
<hr class="underlined_orange">
</div>
</div>
<div class="row">
<!-- Thumbnail -->
<div class="col-lg-3 col-sm-6 text-center">
<a href="#" title="More about Branding & Marketing" target="_self" data-toggle="modal" data-target="#marketing">
<div class="service-box">
<i class="fa fa-5x fa-globe turquoise sr-icons" aria-hidden="true"></i>
<h2 class="orange">Service 1</h2>
<p>About Service 1</p><br>
<p class="turquoise automaticaBRK"><br><span class="btn btn-default sketchFlowPrint">Open Modal</span><br></p>
</div>
</a>
</div>
<!-- Branding & Digital Marketing Modal -->
<div class="modal fade" id="marketing" tabindex="-1" role="dialog" aria-labelledby="marketing-xLabel">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fa fa-times orange" aria-hidden="true"></i></button>
<h1 class="modal-title" id="marketing-xLabel">Service</h1>
</div>
<div class="modal-body text-center">
<div class="row">
<div class="col-sm-6 service-box">
<i class="fa fa-5x turquoise fa-home" aria-hidden="true"></i>
<br><br>
<h2>Less info</h2>
<button type="button" class="btn btn-default automaticaBRK" data-toggle="modal" data-target="#brandingOptions">See Even More about this service</button>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="brandingOptions" tabindex="-1" role="dialog" aria-labelledby="brandingOptions-xLabel">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fa fa-times orange" aria-hidden="true"></i></button>
<h1 class="modal-title" id="brandingOptions-xLabel">More about Service</h1>
</div>
<div class="modal-body text-center">
<div class="row">
<div class="col-xs-12">
<div class="housePlanPackage">
<i class="fa fa-5x turquoise fa-home" aria-hidden="true"></i>
<br><br>
<h2>Too much info</h2>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
</section>