So, I am working on a <canvas> game which is created and presented inside a bootstrap modal. I am trying to write a javascript function that will be called on gameOver that will present a new (stacked) modal on top of my canvas with 3 buttons for score submission/registration/replay.
I present my first modal by data-toggle inside my html and works fine, but when I try to present my second modal on top (by javascript) it appears to be reported as not defined.
Here is my code: JSFiddle .
(in this case I call my second modal in my canvas draw method as an example, but I have also tried a separate button, other event listeners etc. The problem is always the same) .
If there is a better way to present that Game Over screen with buttons I'm open to suggestions. I want to avoid drawing any buttons in my canvas though and getting coordinates to read clicks on it.
Thanks in advance.
You have to adjust z-index if you want to open modal on top of another modal. Using the provided solution here Multiple modals overlay, you could do something like this.
$(document).ready(function() {
let canvas = null;
let drawCanvas = () => {
canvas = document.getElementById("myCanvas");
const context = canvas.getContext("2d");
context.fillStyle = "#FF0000";
context.fillRect(0, 0, 630, 850);
};
$('#openBtn').click(function() {
$('#myModal').modal({
show: true
});
if (!canvas) {
drawCanvas();
}
setTimeout(function() {
$('#myModal2').modal({
show: true,
});
}, 2000)
});
$(document).on('show.bs.modal', '.modal', function(event) {
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);
});
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<h2>Stacked Bootstrap Modal Example.</h2>
<a id="openBtn" class="btn btn-primary">Launch modal</a>
<div class="modal fade" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Modal 1</h4>
</div>
<div class="modal-body">
<canvas id="myCanvas" width="630" height="850">
</canvas>
<a data-toggle="modal" href="#myModal2" class="btn btn-primary">Launch modal</a>
</div>
<div class="modal-footer"> Close
Save changes
</div>
</div>
</div>
</div>
<div class="modal fade rotate" id="myModal2">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Modal 2</h4>
</div>
<div class="container"></div>
<div class="modal-body">Content for the dialog / modal goes here.
<br>
<br>
<p>come content</p>
<br>
<br>
<br> <a data-toggle="modal" href="#myModal3" class="btn btn-primary">Launch modal</a>
</div>
<div class="modal-footer"> Close
Save changes
</div>
</div>
</div>
</div>
<div class="modal fade" id="myModal3">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Modal 3</h4>
</div>
<div class="container"></div>
<div class="modal-body">Content for the dialog / modal goes here.
<br>
<br>
<br>
<br>
<br> <a data-toggle="modal" href="#myModal4" class="btn btn-primary">Launch modal</a>
</div>
<div class="modal-footer"> Close
Save changes
</div>
</div>
</div>
</div>
<div class="modal fade" id="myModal4">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Modal 4</h4>
</div>
<div class="container"></div>
<div class="modal-body">Content for the dialog / modal goes here.</div>
<div class="modal-footer"> Close
Save changes
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</body>
</html>
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>
For those code, there have a button "Launch modal" to open the Model, then in Model, also have a button "Launch modal2" to open a new model(just call model2) on Model. When I click the close button on model2, all of the Model will de dismiss. How can I fix that?
Please note that I need to put model2 in Model for display data.
Thanks.
http://jsfiddle.net/ve42xs6w/
<a data-toggle="modal" href="#myModal" class="btn btn-primary">Launch modal</a>
<div class="modal" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Modal title</h4>
</div><div class="container"></div>
<div class="modal-body">
Content for the dialog / modal goes here.
<br>
<br>
<br>
<br>
<br>
<a data-toggle="modal" href="#myModal2" class="btn btn-primary">Launch modal2</a>
<div class="modal" id="myModal2" data-backdrop="static">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Second Modal title</h4>
</div><div class="container"></div>
<div class="modal-body">
Content for the dialog / modal goes here.
</div>
<div class="modal-footer">
Close
Save changes
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
Close
Save changes
</div>
</div>
</div>
</div>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/js/bootstrap.min.js"></script>
The problem is that you are putting the second modal inside of the first modal. Bootstrap just closes all modals that the close button is inside of, so if you nest them the second close button will close all outside modals.
To fix this you can just move the whole div#myModal2 down under the first div#myModal so they are separate elements.
Like this: http://jsfiddle.net/e92o1j3s/3/
// I found it in jquery but i want it in javascript is there any alternative code. Please help, thanks
<script type="text/javascript">
$(window).on('load',function(){
$('#myModal').modal('show');
});
</script>
I believe bootstrap toggles a class on the modal (haven't looked it up recently.
The plain JS equivalent would be
window.addEventListener('load', () => {
const modal = document.querySelector('#myModal');
if (modal) {
modal.classList.add('show');
modal.style.display = 'block';
}
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" />
<div class="modal fade" id="myModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">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">
<p>Modal body text goes here.</p>
</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>
You may need to check the bootstrap docs to be sure what the class name it adds in.
I want a bootstrap modal to appear on the bottom left corner of the page on page load and allow it to disappear only when the x button is clicked and not when clicked anywhere on the screen. I have got these working till now but the next issue is that when the bootstrap modal is loaded it prevents any background activity like page scrolling or link clicking or any such thing and adds a background shade with opacity in front of the screen. How can I make the shade disappear and allow accessing the website while the modal is loaded and displayed in the bottom left corner?
Here are my codes.
<script>
$(document).ready(function() {
$(window).on('load',function(){
$('#myModal').modal('show');
});
$('#myModal').modal({
backdrop: 'static',
keyboard: false
});
});
</script>
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Sounds like your not after a modal dialog, but something that looks like one.
You can still render a modal, but don't call .modal on in, and then just handle the close events yourself.
eg.
$(document).ready(function() {
$(window).on('load',function(){
var m = $('#myModal');
m.show();
m.find("button").on("click",
function () { m.hide(); });
});
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="myModal" class="modal show" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Modal Header</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
For some reasons i cannot set id or class for my Bootstrap modal-dialog and i need a way to make them work without it, by maybe using JQuery or JavaScript?
<html>
<head>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<!-- Trigger the modal with a button -->
<button type="button" class="btn btn-info btn-lg" >Open Modal 1</button>
<!-- Modal -->
<div class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text11 in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- Trigger the modal with a button -->
<button type="button" class="btn btn-info btn-lg" >Open Modal 2</button>
<!-- Modal -->
<div class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text22 in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
define onclick function to both buttons and pass this as parameter and then use next() property of jquery
<button type="button" class="btn btn-info btn-lg" onclick="firstmodal(this)" >Open Modal 1</button>
<!-- Modal -->
<div class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text11 in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
js
function firstmodal(ele){
$(ele).next().modal('show');
}
Do the same for other modal as well
$(document).ready(function(){
var buttons = $(".container button");
if(buttons.length > 0){
buttons[0].on("click", function(){
//this will return two modals
var modals = $(".container div.modal")
if(modals.length > 0){
modals[0].modal("toggle");
}
})
}
if(buttons.length > 1){
buttons[1].on("click", function(){
//this will return two modals
var modals = $(".container div.modal")
if(modals.length > 1){
modals[1].modal("toggle");
}
})
}
})
Hope that solves the problem