In the examples above, i use a button to close the modal. However, with a little bit of JavaScript, you can also close the modal when clicking outside of the modal box.
the problem is when i use 2 modals just i can close first modal when i click any where , the second one i cannot !!
<!DOCTYPE html>
<html>
<title>W3.CSS</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<body>
<button onclick="document.getElementById('id01').style.display='block'" class="w3-button w3-black">Open Modal 1</button>
<button onclick="document.getElementById('id02').style.display='block'" class="w3-button w3-black">Open Modal 2</button>
<div id="id01" class="w3-modal">
<div class="w3-modal-content w3-card-4">
<div class="w3-container">
<p>model 1</p>
</div>
</div>
</div>
<div id="id02" class="w3-modal">
<div class="w3-modal-content w3-card-4">
<div class="w3-container">
<p>model 2</p>
</div>
</div>
</div>
<script>
// Get the modal
var modal = document.getElementById('id01','id02');
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
</body>
</html>
The function document.getElementById, just like the Element in the name indicates, only gets one element, so the second parameter, 'id2', is ignored, and you end up only getting the first modal element. Read more in the document.
You can use document.getElementsByClassName to fix this:
<!DOCTYPE html>
<html>
<title>W3.CSS</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<body>
<button onclick="document.getElementById('id01').style.display='block'" class="w3-button w3-black">Open Modal 1</button>
<button onclick="document.getElementById('id02').style.display='block'" class="w3-button w3-black">Open Modal 2</button>
<div id="id01" class="w3-modal">
<div class="w3-modal-content w3-card-4">
<div class="w3-container">
<p>model 1</p>
</div>
</div>
</div>
<div id="id02" class="w3-modal">
<div class="w3-modal-content w3-card-4">
<div class="w3-container">
<p>model 2</p>
</div>
</div>
</div>
<script>
// Get the modal
var modals = document.getElementsByClassName('w3-modal');
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
console.log(event.target, event.target == modals[0], event.target == modals[1]);
if (event.target == modals[0] || event.target == modals[1]) {
modals[0].style.display = "none";
modals[1].style.display = "none";
}
}
</script>
</body>
</html>
Optionally, you can use a relatively new api, document.querySelector, to unify the usages of selecting DOM elements. It uses css selector like string to select elements. But it's a bit new so you may want to check browser compatibility before using it.
Related
What specific changes need to be made in the Bootstrap 5 example below in order for the following two things to occur:
the "afterAcceptingTerms" div should be hidden until the user has clicked on the Accept Terms modal button, so that only the "beforeAcceptingTerms" div should be visible until the user has clicked on the Accept Terms modal button.**
the "afterAcceptingTerms" should become visible once the user clicks on the Accept Terms modal button, and the "beforeAcceptingTerms" div should be hidden once the user clicks on the Accept Terms modal button.
Here is the Bootstrap 5 code we are currently starting with, but you can see that the code example below fails to toggle the
div classes as stated in the requirements above.
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>Modal Popup Page</title>
<link href="/assets/css/bootstrap.min.css" rel="stylesheet">
<script src="/assets/js/popper.min.js"></script>
<script src="/assets/js/bootstrap.min.js" ></script>
</head>
<body>
<div class="wrapper" id="beforeAcceptingTerms">
<section class="content-section">
<p>You must click on the "I agree to the terms button" in order to see the content on this page.</p>
</section>
</div>
<div class="wrapper" id="afterAcceptingTerms">
<section class="content-section">
<p>The page content goes here. But this is only visible because you clicked on the Accept button on the modal in order to get the modal to go away.</p>
</section>
</div>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="exampleModalLabel" data-bs-backdrop="static" aria-hidden="true">
<div class="modal-dialog" style="position: fixed;bottom: 0;left: 0;right: 0;">
<div class="modal-content">
<div class="modal-body">
By using this site, you certify that you agree to our Terms of Use.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" onclick="localStorage.setItem('acceptTerms',1)">I agree to the Terms.</button>
</div>
</div>
</div>
</div>
<script>
let acceptTerms = localStorage.getItem('acceptTerms');
if(acceptTerms != 1){
var myModal = new bootstrap.Modal(document.getElementById('myModal'), {})
myModal.show()
}
</script>
</body>
</html>
You forgot to add CDNs instead your local files.
(I added a button to clear local storage data for testing purpose).
What did I change?
// Window onload event to display your content if users has accepted terms
// calling checkTerms() function
window.onload = (event) => {
checkTerms();
};
const afterAcceptingTerms = document.getElementById('afterAcceptingTerms');
const acceptTermsButton = document.getElementById('acceptTermsButton');
// Added a listener to your accept terms button
// removing inline onclick element attribute
acceptTermsButton.addEventListener('click', function() {
termsAccepted();
});
// Here we manage what to do when user click in the accept terms button
// in this case with try/catch to prevent critical errors its good to send
// errors like that (in a catch block) to a server for you stay on what errors users can experience
function termsAccepted() {
try {
localStorage.setItem('acceptTerms',1);
} catch (error) {
alert('CRITICAL ERROR !!!! USER WILL NOT SEE THE CONTENT');
}
afterAcceptingTerms.classList.remove('none');
}
// Function called when window load !! To check if user has accept the terms !
// I'm using try/catch because this is critical, if the localStorage can't be accessed
// your content won't be shown
function checkTerms() {
let val = '';
try {
val = localStorage.getItem('acceptTerms');
} catch (error) {
alert('CRITICAL ERROR !!!! USER WILL NOT SEE THE CONTENT');
}
if (val === '1') {
afterAcceptingTerms.classList.remove('none');
} else {
var myModal = new bootstrap.Modal(document.getElementById('myModal'), {})
myModal.show()
}
}
Also added a .none class with (display:none) to your #afterAcceptingTerms element, it was essential this element starts with display:none. We are going to remove that class programmatically:
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>Modal Popup Page</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<style>
.none {
display: none;
}
</style>
</head>
<body>
<div class="wrapper" id="beforeAcceptingTerms">
<section class="content-section">
<p>You must click on the "I agree to the terms button" in order to see the content on this page.</p>
</section>
<button id="clearData">Clear storage data</button>
</div>
<div class="wrapper none" id="afterAcceptingTerms">
<section class="content-section">
<p>The page content goes here. But this is only visible because you clicked on the Accept button on the modal in order to get the modal to go away.</p>
</section>
</div>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="exampleModalLabel" data-bs-backdrop="static" aria-hidden="true">
<div class="modal-dialog" style="position: fixed;bottom: 0;left: 0;right: 0;">
<div class="modal-content">
<div class="modal-body">
By using this site, you certify that you agree to our Terms of Use.
</div>
<div class="modal-footer">
<button type="button" id="acceptTermsButton" class="btn btn-secondary" data-bs-dismiss="modal">I agree to the Terms.</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script>
var clearData = document.getElementById('clearData');
clearData.addEventListener('click', function() {
localStorage.clear();
});
window.onload = (event) => {
checkTerms();
};
const afterAcceptingTerms = document.getElementById('afterAcceptingTerms');
const acceptTermsButton = document.getElementById('acceptTermsButton');
acceptTermsButton.addEventListener('click', function() {
termsAccepted();
});
function termsAccepted() {
try {
localStorage.setItem('acceptTerms',1);
afterAcceptingTerms.classList.remove('none');
} catch (error) {
alert('CRITICAL ERROR !!!! USER WILL NOT SEE THE CONTENT');
}
}
function checkTerms() {
let val = '';
try {
val = localStorage.getItem('acceptTerms');
if (val === '1') {
afterAcceptingTerms.classList.remove('none');
} else {
var myModal = new bootstrap.Modal(document.getElementById('myModal'), {})
myModal.show()
}
} catch (error) {
alert('CRITICAL ERROR !!!! USER WILL NOT SEE THE CONTENT');
}
}
</script>
</body>
</html>
I have a Bootstrap 5 modal, which is used to download a file by clicking a button. This works fine, but I want the modal to be hidden after clicking the download button, and this is where I'm struggling.
I am attempting to use jQuery to do this. I know that the jQuery library is successfully imported and that my function is being executed because I can display an alert box within the same function, but I can't get the modal to hide.
The full code snippet is pasted below with the script section at the bottom. The key line of code that I am trying to use to dismiss the modal is: -
$('#downloadConfirm1').modal({show : false});
I have also tried the following: -
$('.modal.in').modal('hide');
But neither has worked. I am extremely grateful to anyone who takes the time to read my post. Any suggestions most welcome!
<!DOCTYPE html>
<html>
<head lang="en">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Java Documentum Services</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.min.js" integrity="sha512-OvBgP9A2JBgiRad/mM36mkzXSXaJE9BEIENnVEmeZdITvwT09xnxLtT4twkCa8m/loMbPHsvPl0T8lRGVBwjlQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/css/bootstrap.min.css" integrity="sha512-GQGU0fMMi238uA+a/bdWJfpUGKUkBdgfFdgBm72SUQ6BeyWjoY/ton0tEjH+OSH9iP4Dfh+7HM0I9f5eR0L/4w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>
<body>
<div class="container">
<a class="btn btn-sm btn-outline-primary" data-bs-toggle="modal"
data-bs-target="#downloadConfirm1"
role="button">Download
</a>
<div class="modal fade" id="downloadConfirm1" tabindex="-1" aria-labelledby="downloadConfirm1"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="downloadModalLabel">Confirm download</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Download Docx_test_file.docx?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<a href="files/dummy.pdf" download="dummy.pdf">
<button type="button" id="download_button1">Download</button>
</a>
</div>
</div>
</div>
</div>
</div>
</body>
<script>
$('#download_button1').click(function() {
alert("Hello! I am an alert box!!");
$('#downloadConfirm1').modal({show : false});
});
</script>
</html>
Bootstrap 5 modal dropped jQuery so that is why you cannot hide the modal with jQuery. You should save your modal instance in the moment of initialization.
Afterwards you can use this code to hide your modal.
Ref: Bootstrap 5 Modal#hide
var modalInstance = new bootstrap.Modal(document.getElementById('downloadConfirm1'));
var modal = document.getElementById('downloadConfirm1');
modalInstance.hide(modal);
var myModalEl = document.querySelector('#scheduleMeetingModal');
var myModal = bootstrap.Modal.getOrCreateInstance(myModalEl);
myModal.hide();
The main goal is to show different divs depending on which button I click, so they all start with the display style at "none" (except a default one called "atualizacoes"). And after I click a button ALL of the divs should be set to
display="none" and after that the one I associated that button with is set to display="block".
However something isn't right because when I click one of the buttons, the default div does disappear however nothing ever appears.
This is how I'm trying to accomplishing it:
In order:
snippet 1 - function I use inside my index.html to change all the
displays
snippet 2 - rule in my stylesheet
snippet 3 - parts of my index.html code (I didn't want to paste
EVERYTHING)
<script type="text/javascript">
function replace(show) {
document.getElementById('default').style.display="none";
document.getElementById('ecra').style.display="none";
document.getElementById(show).syle.display = "block";
}
</script>
.ecra
{
display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>University Platform</title>
<!-- Bootstrap core CSS -->
<link href="bootstrap/css/bootstrap.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="dashboard.css" rel="stylesheet">
<!-- jquery -->
<script src="assets/js/jquery.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
<!-- these are the buttons that are located on a sidebar -->
<div class="row">
<h3>Options</h3>
<button type="button" class="btn btn-default botao pull-left" onclick="replace('addestudante')">Adicionar Estudante</button>
</div>
<div class="row">
<button type="button" class="btn btn-default botao pull-left" onclick="replace('adduc')">Adicionar UC</button>
</div>
<!-- these are the divs I want to switch around -->
<div class="row" id='default'>
<p> Hello World </p>
</div>
<!-- in CSS I also made a rule that makes all "ecra" divs be invisible from the start-->
<div class="row ecra" id='addestudante'>
<button type="button" class="btn btn-default"> TEST 1</button>
</div>
<div class="row ecra" id='adduc'>
<button type="button" class="btn btn-default"> TEST 2</button>
</div>
</body>
Why is this function not working properly? Is there something wrong with my code?
There are a couple of issues with what you've written.
For one, you don't have any elements with ID "ecra" — what you want to do is affect all the elements that have the class "ecra". You can do this by looping or mapping over document.getElementsByClassName("ecra").
Secondly, you've misspelt style when you try to show the show element.
Try using this adapted function instead:
function replace(show) {
document.getElementById("default").style.display = "none";
Array.from(document.getElementsByClassName("ecra")).map(element => element.style.display = "none");
document.getElementById(show).style.display = "block";
}
By what I thought, you want to get elements by class name. They're ecra, so you can use querySelectorAll and do a loop for its length. I'll not use getElementsByClassName because it will make the line more longer and return an array.
function replace(show){
var q=document.querySelectorAll('.ecra'),
document.getElementById('default').style.display="none";
for(var i=0,l=q.length;i<l;i++){
!function(i){
q[i].style.display="none"
}(i)
}
document.querySelector('#'+show).style.display = "block"
}
I saw jQuery imported in your page. So I suggest to use jQuery.
<script type="text/javascript">
function replace(show) {
jQuery(function($){
$("#default").css({
"display" : "none"
});
$(".ecra").css({
"display" : "none"
});
$("#"+show).css({
"display" : "block"
});
});
}
</script>
Edited, missing characters.
JS corrected : http://jsfiddle.net/csfd8x35/
.ecra
{
display: none;
}
<!-- these are the buttons that are located on a sidebar -->
<div class="row">
<h3>Options</h3>
<button type="button" class="btn btn-default botao pull-left" onclick="replace1('addestudante')">Adicionar Estudante</button>
</div>
<div class="row">
<button type="button" class="btn btn-default botao pull-left" onclick="replace1('adduc')">Adicionar UC</button>
</div>
<!-- these are the divs I want to switch around -->
<div class="row" id='default'>
<p> Hello World </p>
</div>
<!-- in CSS I also made a rule that makes all "ecra" divs be invisible from the start-->
<div class="row ecra" id='addestudante'>
<button type="button" class="btn btn-default"> TEST 1</button>
</div>
<div class="row ecra" id='adduc'>
<button type="button" class="btn btn-default"> TEST 2</button>
</div>
<script>
function replace1(show) {
document.getElementById('default').style.display="none";
var allByClass = document.getElementsByClassName('ecra');
for (var i=0;i< allByClass.length; i++) {
allByClass[i].style.display = "none";
}
document.getElementById(show).style.display = "block";
}
</script>
I need to make the letter "x" clickable and ad a function that removes the text that this line below creates.
$("#user").prepend("<li>Hello! <span id='clickable'>x</span></li>");
$(document).ready(function() {
$("#hello").click(function() {
$("#user").prepend("<li>Hello! <span id='clickable'>x</span></li>");
$("#webpage").prepend("<li>Why hello there!!</li>");
$("#user").children("li").first().click(function(){
$(this).remove();
});
$("#webpage").children("li").first().click(function(){
$(this).remove();
});
});
$("#goodbye").click(function() {
$("#user").prepend("<li>Goodbye!</li>");
$("#webpage").prepend("<li>Goodbye, dear user!</li>");
$("#user").children("li").first().click(function(){
$(this).remove();
});
$("#webpage").children("li").first().click(function(){
$(this).remove();
});
});
$("#stop").click(function() {
$("#user").prepend("<li>Stop copying me!</li>");
$("#webpage").prepend("<li>Sorry, i meant no offense.</li>");
$("#user").children("li").first().click(function(){
$(this).remove();
});
$("#webpage").children("li").first().click(function(){
$(this).remove();
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
<link href="CSS/bootstrap.css" rel="stylesheet" type="text/css">
<link href="CSS/styles.css" rel="stylesheet" type="text/css">
<script src="jQuery/jQuery.js"></script>
<script src="talk.js"></script>
<title>Talk to the web page</title>
</head>
<body>
<div class="container">
<h1>Talk to the web page</h1>
<p>Click a button to say something to the web page. See what it says back!</p>
<button class="btn btn-primary" id="hello">Say "hello"</button>
<button class="btn btn-inverse" id="goodbye">Say "goodbye"</button>
<button class="btn btn-danger" id="stop">Say "stop copying me!"</button>
<div class="row">
<div class="col-md-6">
<h2>You said:</h2>
<ul class="unstyled" id="user">
</ul>
</div>
<div class="col-md-6">
<h2>The web page said back:</h2>
<ul class="unstyled" id="webpage">
</ul>
</div>
</div>
</div>
</body>
</html>
a clickable letter that removes the text this line above creates.
Create one click event that uses .on (since dynamic content and what not) and remove the parent li element:
$("#user").on("click", "span.clickable", function() {
$(this).parent("li").remove();
});
Also use the class clickable and not the ID (I assume you have more than 1);
i am new to twitter bootstrap .i am using the bootstrap 3
and this is my html code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Bootstrap Samples</title>
<script src="scripts/jquery1.10.2.min.js"></script>
<script src="bootstrap-3.1.1-dist/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="bootstrap-3.1.1-dist/css/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="bootstrap-3.1.1-dist/css/bootstrap-theme.min.css" />
<style>
.banner {color:#FF0000;}
</style>
<script>
$(document).ready(function(){
$("#MyModal5").on('hidden.bs.modal',function(){
$("#btnYes").on('click',function(e){
var $myMod = $(this);
var id = $myMod.data('cust-id');
if(id=='y'){
alert("You clicked yes button");
}
});
});
});
</script>
</head>
<body>
<!-- -------------------------------------------------------------------- -->
<div class="modal fade" id="MyModal5">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-title">
<label style="color:#FF6600;">Confirmation</label>
</div>
<div class="modal-header">
<button class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
<label>This may cause to make an additional hit to server. Are you sure you want to continue ?</label>
</div>
<div class="modal-footer">
<button class="btn btn-success btn-sm" id="btnYes" data-cust-id="y" data-dismiss="modal">Yes</button>
<button class="btn btn-danger btn-sm" id="btnNo" data-cust-id="n" data-dismiss="modal">No</button>
</div>
</div>
</div>
</div>
<!-- -------------------------------------------------------------------- -->
<div class="container">
<div class="row">
<div class="col-sm-12">
<label>If you want to visit google</label>Click here
</div>
</div>
</div>
</body>
</html>
idea is that i have a link, while i click on that link i need to populate the model.its working,now if i click on the 'yes' button on that modal ,i need an alert, but problem is that alert is not showing when i click on yes button for first time ,but if i again click on that button for second time it is showing,another problem is tht if i clicked on third time alert is showing twise,i dont know the exact reason,i suspect this is because of the on event of jquery.
can any one help me to slove this issue
I believe the issue may stem from your click event bindings being nested. Try removing the outer binding and just register the click event in this way:
$(document).ready(function() {
$("#btnYes").on("click",function(e) {
var $myMod = $(this).closest(".modal"); // Select on closest parent modal
// Now run your required code
});
});
});
Hope this works and helps! Good luck.