How do I create a function that will close the bootstrap modal? - javascript

How do I create a function that will close the bootstrap modal?
I’ve created a bootstrap modal for my Google Maps API, which can be seen with this link: http://userpages.flemingc.on.ca/~eluli/modal.html
I want to make it possible for users to click on the x button to exit the modal, in order to access the map.
I am not sure how to get it to close.
Below is a snippet of my code:
/* The boostrap modal*/
.reveal-modal{
left: 50%;
margin-left: -300px;
width: 520px;
background: #eee;
position: absolute;
z-index: 101;
padding: 30px 40px 34px;
-webkit-box-shadow: 0 0 10px rgba(0,0,0,.4);
-box-shadow: 0 0 10px rgba(0,0,0,.4);
top: 100px; o
pacity: 1;
visibility: visible;
}
/* The close button */
.reveal-modal .close-reveal-modal {
font-size: 22px;
line-height: .5;
position: absolute;
top: 8px;
right: 11px;
color: #aaa;
text-shadow: 0 -1px 1px rbga(0,0,0,.6);
font-weight: bold;
cursor: pointer;
}
/*HTML of bootstrap modal*/
<div id="map" class="reveal-modal" style="top: 100px; opacity: 1; visibility: visible;">
/* close button*/
<a class="close-reveal-modal">✕</a>
<h1>Ontario Water Company and Electoral District Map</h1>
<p>This map provides information on stakeholders, companies and schools that affiliate with WaterTAP.</p>
<p>Note: the map information might have discrepancies since the boundaries of some electoral districts change when provincial elections occur. </p> </div>
<div class="reveal-modal-bg" style="display: block; cursor: pointer;"></div>

You can add an attribute to <a class="close-reveal-modal">✕</a>.
<a class="close-reveal-modal" data-dismiss="modal">✕</a>
Also, close-reveal-modal is Foundation and not Bootstrap.

<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
or by jQuery
$(function(){
$('.close-reveal-modal').click(function(){
$('#map').modal('hide');
});
});

Let us say you need to bind the close modal function to a button with id close_my_modal and the id of modal is my_modal
jQuery("close_my_modal").click(function(){
// Do your stuff here
jQuery('#my_modal').modal("toggle");
jQuery(".modal-backdrop").remove(); // Though this should have been controlled by bootstrap, but it did not, hence, have to do it our code.
});
Also, there is an attribute data-dismiss that can be used as well.
In case you do not have any code to execute before closing the modal, it is recommended to use data-dismiss attribute as it's working is then controlled by bootstrap. However, if you need to perform any operations, prior to close of modal, you have to bind the click function to a button and then manually toggle the modal.

Related

Create Popup for existing button

edit: i cant edit the original code, since the button and its function is provided by a plugin. If could find the initial JS for the function of the button, i would hide the first one and recreate / modify it myself if thats somehow possible..
I have a button which is already styled and running a javascript function (cant find the code for it).
Is it possible to create a popup for that existing button?
Found this tutorial on how to create a popup on W3
<div class="popup w3-text-blue" onclick="myFunction()">Click me to toggle the popup!
<span class="popuptext" id="myPopup">A Simple Popup!</span>
</div>
<style>
.popup {
position: relative;
display: inline-block;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.popup .popuptext {
visibility: hidden;
width: 160px;
background-color: #555;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 8px 0;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -80px;
}
.popup .popuptext::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #555 transparent transparent transparent; }
span#myPopup.popuptext.show {
visibility: visible;
}
</style>
<script>
// When the user clicks the div, open the popup
function myFunction() {
var popup = document.getElementById('myPopup');
popup.classList.toggle('show');
}
</script>
but cant make it work for an existing button.
All info i have for that button:
<button type="button" class="class class2 class3" data-overwrite-fields="1"><i class="fas fa-check fa-fw"></i> Submit</button>
(the i class is an svg image)
Is it possible to create a popup for that button or should i move on?
You could try wrapping the button in a div with an onclick for the div, in which you preventDefault(), then show your popup, and use JS or jQuery to "click" the button you can't modify.
Something like this:
<div onclick="yourOwnFunction">
<button id="buttonId"></button> <!-- Button you can't change -->
</div>
Then:
function yourOwnFunction(event){
showPopup();
event.preventDefault();
}
Note, this assumes that you don't want the button's function to execute before your popup is displayed. If this is the case, once the user does what is needed on your popup, you can then "fire" the button's function with something like this:
function whatHappensWhenModalIsClosed(){
document.getElementById("buttonId").click();
}
Notes
There are a lack of details in the question that make this a bit tricky. Because the <button> in question does not have an id set and there appears to be other buttons with potentially the same class, a lot of assumptions have to be made.
Ideally if we know the parent element, we can use that as a selector first to narrow the results, then attempt to select our button. Also, if any siblings or nearby elements have an id set, we could use things like nextElementSibling() or the closest() methods to grab this specific button.
Solution
The approach however is to grab all of the potential buttons and loop through them. From there, I am checking to make sure the data-overwrite-fields attribute is equal to 1 and that the text within the button is equal to submit (forced to lower case). Without more information from OP I cannot guarantee these criteria will limit the result to only 1 button, but this should be a useful start for OP to translate into a solution.
The next steps are to copy the button, add a new event listener (as well as the popup element) and then replace the old button with the newly created one.
const _ReplaceButton = () => {
document.querySelectorAll("button.class.class2.class3").forEach(b => {
// Because we do not know if there are other buttons with this class,
// we must try to narrow it down
if(b.dataset.overwriteFields != "1" || b.innerText.trim().toLowerCase() != "submit") return
// Copy the button and create the popup element
let newButton = b.cloneNode(true),
popup = document.createElement("div")
// Set the event listener for the new button
newButton.addEventListener("click", myFunction)
// Set the class and content for the popup
popup.className = "popup w3-text-blue"
popup.innerHTML = `<span class="popuptext" id="newPopup">New Button!</span>`
// Replace the old button
b.replaceWith(newButton, popup)
})
}
function myFunction() {
document.getElementById('newPopup').classList.toggle('show');
}
.popup {
position: relative;
display: inline-block;
height: 1.2em;
user-select: none;
}
.popup .popuptext {
visibility: hidden;
width: 160px;
background-color: #555;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 8px 0;
position: absolute;
z-index: 1;
bottom: 100%;
left: 0;
margin-left: -108px;
}
.popup .popuptext::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #555 transparent transparent transparent;
}
span.popuptext.show {
visibility: visible;
}
<p>This is just example text used to fill this element. This text has no meaning and only serves as placeholder content.</p>
<button type="button" class="class class2 class3"><i class="fas fa-check fa-fw"></i> Button 1</button>
<button type="button" class="class class2 class3" data-overwrite-fields="1"><i class="fas fa-check fa-fw"></i> Submit</button>
<p>This is just example text used to fill this element. This text has no meaning and only serves as placeholder content.</p>
<button type="button" class="class class2 class3" onclick="_ReplaceButton()">Swap Button</button>
Initially the button will do nothing (it likely has an event listener already attached to it, which is irrelevant here as that is removed when the element is cloned). After clicking Swap Button, the old button is removed and the new one runs myFunction() and displays the popup.

Show hover menu on tab key press

On this website, I have images that you can hover over with your mouse and it will display two buttons. I want keyboard-only users to be able to tab through the site, so when they tab, the hoverable menu shows up. I've read a lot of solutions involving :focus and tabindex=0 but I can't seem to make it work. I have attempted to put tabindex=0 on the <a> tags to see if that would do it, but it doesn't. I believe the buttons will be tabbed through just fine if I could just get the hover menu to show up using the tab key. I might be missing something obvious, but I'm a beginner with all of these things. If it's not possible via CSS, can someone suggest a JS solution?
HTML
<div class="thumbnail thumbnail-medium-short">
<div class="nqspCover-container">
<img src="img/stuff.jpg" alt="Front cover" width="180px" height="233px">
<div class="overlay">
<div class="read-button">Read</div>
<div class="buy-button">Buy</div>
</div>
</div>
<div class="nqsp-caption">
<p>stuff</p>
</div>
</div>
CSS
.nqspCover-container {
position: relative;
width: 180px;
height: 233px;
margin: 0 auto;
}
.overlay {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0);
transition: background 0.5s ease;
}
.nqspCover-container:hover .overlay {
background: rgba(0,0,0,.3);
}
.buy-button{
margin-top: 40px;
}
.read-button, .buy-button{
position: absolute;
width: 65px;
padding: 5px 15px;
border: solid 2px white;
opacity: 0;
transition: opacity .35s ease;
}
.read-button a, .buy-button a{
text-decoration: none;
text-align: center;
color: white;
}
.nqspCover-container:hover .read-button,
.nqspCover-container:hover .buy-button{
opacity: 1;
}
.read-button a:hover, .buy-button a:hover{
text-decoration: underline;
}
.read_button a:focus, .buy-button a:focus{
display: block;
}
Example of the hover menu I need to pop up when they tab to it (don't worry, the background img and buttons definitely won't look like that when it's done):
Only one element can have focus at a time, so you can not do this using :focus alone. That's what the :focus-within pseudo class was made to solve - but be aware of browser compatibility; MicroSofts two current browsers don't support it yet.
You'll need a JS solution or at least a polyfill for :focus-within
(FYI, div elements can't receive focus by default, so you'd need to start by adding the tabindex attribute. tabindex="0" is usually what you want to make an element focus-able in normal DOM order.)
I don't know if "focus" really does what I need it to do at all.
It does what the other pseudo classes do, too - no more or less: Identify/react to an element being in a specific state. What you do with it, or it's descendants/siblings, is up to you - by writing the selectors that target those elements, based on that parent/siblings state.
https://www.google.com/search?q=menu+with+focus-within gets you more detailed explanations & examples, f.e. http://www.scottohara.me/blog/2017/05/14/focus-within.html That one explains the topic pretty well, and also mentions a polyfill, https://allyjs.io/api/style/focus-within.html

IE issue: wrong tab focus

I have a link at the very top of the page called "Skip Navigation", that appears on the screen every time user presses Tab, and if he presses Enter while "Skip Navigation" is in focus, it takes him to the #main part of the page, so that he skips top navigation and goes directly into the main area. It all works perfect in Chrome, Firefox, Safari. The issue appears in IE (I tested both ie9 and ie11).
Scenario in IE:
Presses Tab - "Skip Navigation" appears on the page - presses Enter -
refreshes the page with #main added into the url - presses Tab - "Skip
Navigation" appears on the page
Does anyone know any solution for IE to force skipping navigation and going to the main part of the page? Any help will be highly appreciated.
#skip a {
position: absolute;
left: -10000px;
top: auto;
width: 1px;
height: 1px;
overflow: hidden;
}
#skip a:focus {
left: auto;
font-size: 20px;
position: static;
width: auto;
height: auto;
}
nav {
background: #847577;
color: white;
padding: 1em;
text-align: center;
}
nav a {
color: white;
}
#main {
background: #E5E6E4;
padding: 1em;
}
#main a {
color: black;
}
<div id="skip">Skip navigation</div>
<nav>
Home
About Us
</nav>
<div id="main">
Main Content On The Page Link
</div>
jsfiddle: https://jsfiddle.net/13p0eo43/
I think you have two options if it doesn't work with the standard way as you describe:
Focus the first focusable element following #main using JavaScript .focus() method. Your difficulty here will be determining which element must be focused, as it might not always be so simple.
Set tabindex=-1 on #main and focus #main using JavaScript .focus() method upon clicking on the link. The next time the user press tab, the next focusable element will take focus, and #main can't be focused again when pressing shift+tab (because of the value -1).
Add tabindex="-1" to the div, no need for javascript.
The following is working for me in IE11.
#skip a {
position: absolute;
left: -10000px;
top: auto;
width: 1px;
height: 1px;
overflow: hidden;
}
#skip a:focus {
left: auto;
font-size: 20px;
position: static;
width: auto;
height: auto;
}
nav {
background: #847577;
color: white;
padding: 1em;
text-align: center;
}
nav a {
color: white;
}
#main {
background: #E5E6E4;
padding: 1em;
}
#main a {
color: black;
}
<div id="skip">Skip navigation</div>
<nav>
Home
About Us
</nav>
<div id="main" tabindex="-1">
Main Content On The Page Link
</div>

Close modal by clicking outside the box

Can I use simple css to close modal by clicking outside the box? I have seen examples of how to do it using jQuery/JavaScript. I have it set up right now so that it closes when clicking the 'x' and no JavaScript is being used:
<div>X</div>
And then in my css file:
.close {
opacity: 10px;
background-color: darkblue;
color: #FFFFFF;
line-height: 25px;
position: absolute;
right: -12px;
text-align: center;
top: -10px;
width: 24px;
text-decoration: none;
font-weight: bold;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
border-radius: 12px;
-moz-box-shadow: 1px 1px 3px #000;
-webkit-box-shadow: 1px 1px 3px #000;
box-shadow: 1px 1px 3px #000;
}
.close:hover {
background: #00d9ff;
}
This can't be accomplished with just plain CSS.
Javascript is there to make your page dynamic and reactive, so you should be using it to listen for events and for manipulating what is shown to the user.
Rather than using CSS you could use a button that calls a Javascript function to open the modal like so:
jQuery:
<button id="modal-button" onclick="openModal();">Open Modal</button>
HTML:
<script>
function openModal()
{
$('#myModal').modal('show');
}
</script>
Using this method you will be able to click off the modal to close it.
If you can alter the html and place a hidden checkbox and an extra overlay before the modal, then yes, I have a solution for you.
HTML
<input type="checkbox" id="modal-toggle" class="modal-toggle" />
<label for="modal-toggle" class="modal-overlay"></label>
<div class="modal">
<label for="modal-toggle" class="modal-close-button">X</label>
</div>
CSS
.modal-toggle,
.modal-overlay,
.modal {
display: none;
}
.modal-toggle:checked + .modal-overlay,
.modal-toggle:checked + .modal-overlay + .modal {
display: block;
}
.modal-overlay {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1;
}
.modal {
position: absolute;
/* I've used absolute here to note that the modal can't be static */
/* add other properties to position this div */
z-index: 2;
}
From w3schools.com:
Note: z-index only works on positioned elements (position:absolute, position:relative, or position:fixed).
How does it work? We have a hidden overlay and modal right after an input. When this input gets checked the overlay and modal will be shown.
The overlay and the close button are the labels of the checkbox so clicking on these will uncheck the input, thus hides the modal. You will need another label somewhere in your html which will bring up the modal of course.
You can read about the "+" css selector here.
Full list of css selectors
You can use multiple modals on the same page, just make sure every modal has its own unique id and for attribute value. The question didn't mention if the modal has to be animated on show/hide, that is possible too.
you can close the div by clicking out side
add this code to your js file or inside your <script> </script> tag
replace the ID_OF_DIV with id of the div you want to close
document.body.addEventListener("click", function() {
var element = document.getElementById("ID_OF_DIV");
if (element) {
element.style.display = "none";
}
});

Toggle needs to work only on parent div, not child div

I am simulating a pop up window that fades the background out. I do this by simply toggling a div that fills the whole screen. I would like to be able to close the pop up by clicking the outside background, but not when you click on the new content area, which is what is currently happening. My code:
JS:
function popbox() {
$('#overbox').toggle();
}
HTML:
<div class="popbox" onclick="popbox()"> Click Here </div>
<div id="overbox" onclick="popbox()">
<div id="infobox1">
<p>This is a new box</p>
<br />
<p>hello </p>
<br/><br/>
<p style="color:blue;text-align:center;cursor:pointer;" onclick="popbox()">close</p>
</div><!-- end infobox1 -->
</div> <!-- end overbox -->
CSS:
#overbox {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background: rgba(64, 64, 64, 0.5);
z-index: 999999;
display: none;
}
#infobox1 {
margin: auto;
position: absolute;
left: 35%;
top: 20%;
height: 300px;
width: 400px;
background-color: white;
border: 1px solid red;
}
.popbox {
cursor: pointer;
color: black;
border: 1px solid gray;
padding: 5px; 10px;
background: ghostwhite;
display: inline-block;
}
JSFiddle link: http://jsfiddle.net/RrJsC/
Again, I want it to toggle only when you click the faded background or "close" (which isnt working in the jsfiddle but is on my site), but not when you click inside the white box that it contains.
After some research it seems like I might be looking for .stopPropagation(), but I haven't been able to get it to work at all.
I got it to work using jQuery's event handlers:
$('#container').on('click', '.popbox, #overbox', function(e){
$('#overbox').toggle();
});
$('#container').on('click', '#infobox1', function(e){
e.stopPropagation();
});
I replaced document with '#container' for better performance. You should wrap all your divs in <div id="container">...</div> so the the callback doesn't fire on the dom every time there is a click (even thought that callback is only called when the selector matches).
You'll also need to get rid of your onclick html attributes, because they will throw an error if that function is not defined.
I hope I understand well your problem.
If it is the case, you should have this:
<div id="overbox">
instead of this:
<div id="overbox" onclick="popbox()">
here is the updated jsfiddle

Categories