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.
Related
in html, sometimes I have elements that I display only when another one gain focus : you click on a button, to make another one appear.
If then you click on this newly displayed element, it disappears immediately because the focus gets away from the first one.
EDIT : And this is what I want. That could be a drop down menu for example, and I want the list to appears when clicking the title, and I want it to disappear when clicking on an element in the list.
but I also want to capture the click event before the element go away, and I can't do that ! example :
function make_action(element) {
console.log(element);
document.getElementById("output").innerHTML += `<p>detected ${element.innerHTML}</p>`;
};
#buttons {
width: 100px;
padding: 10px;
border: 1px solid black;
}
#buttons:focus p {
display: block;
}
#buttons p {
border: 1px solid blue;
display: none;
}
p {
margin: 5px;
padding: 0px;
}
<div id="buttons" tabindex=0>
<p onclick="make_action(this)" tabindex=0>onclick</p>
<p onfocus="make_action(this)" tabindex=0>onfocus</p>
<p onfocusin="make_action(this)" tabindex=0>onfocusin</p>
</div>
<div id="output">
</div>
I can workaround with the use of opacity and visibility with transition :
opacity to have the ux of the instantaneous hide of the element but it's still present so you can click on it
visibility is being delayed (sort of) with the transition, so for a moment you still have the element because it's still 'visible', but for human eyes it's not visible anymore
like that :
function make_action(element) {
console.log(element);
document.getElementById("output").innerHTML += `<p>detected ${element.innerHTML}</p>`;
};
#buttons {
width: 100px;
padding: 10px;
border: 1px solid black;
}
#buttons:focus p {
/*
display: block;
*/
visibility: visible;
opacity: 1;
}
#buttons p {
border: 1px solid blue;
/*
display: none;
*/
opacity: 0;
visibility: hidden;
transition: visibility 0.5s;
}
p {
margin: 5px;
padding: 0px;
}
<div id="buttons" tabindex=0>
<p onclick="make_action(this)" tabindex=0>onclick</p>
<p onfocus="make_action(this)" tabindex=0>onfocus</p>
<p onfocusin="make_action(this)" tabindex=0>onfocusin</p>
</div>
<div id="output">
</div>
but, I'm not sure it's a good practice because the element is actually still on the page, so it can impact accessibility and maybe other things.
do you know a way to capture the click on the element, before it disappears ?
what I don't understand, is the following : the buttons disappears because the div lose it's focus. But, it loses it's focus BECAUSE a click occurred on one button, so why isn't this click on the button detected ? or how is it detectable ?
You can replace you :focus with :focus-within which was created specially for this purpose.
And to do so that when clicked the elements loses focus, you can use the blur method to do so :
function make_action(element) {
console.log(element);
element.blur()
document.getElementById("output").innerHTML += `<p>detected ${element.innerHTML}</p>`;
};
#buttons {
width: 100px;
padding: 10px;
border: 1px solid black;
}
/* there is the change */
#buttons:focus-within p {
display: block;
}
#buttons p {
border: 1px solid blue;
display: none;
}
p {
margin: 5px;
padding: 0px;
}
<div id="buttons" tabindex=0>
<p onclick="make_action(this)" tabindex=0>onclick</p>
<p onfocus="make_action(this)" tabindex=0>onfocus</p>
<p onfocusin="make_action(this)" tabindex=0>onfocusin</p>
</div>
<div id="output">
</div>
I'm trying to create my own product tour handling (after trying some like intro.js).
Here is a JSFiddle that I've just created.
What I have is a div with CSS:
.highlight {
position: fixed;
top: 14px;
left: 16px;
width: 54px;
height: 40px;
z-index: 1000;
pointer-events: none;
}
.highlight__overlay {
width: 100%;
height: 100%;
position: absolute;
z-index: 12;
top: 0;
left: 0;
border-radius: 5px;
transition: all .5s ease;
border: 2000px solid rgba(0 ,0 ,0 ,0.85);
margin: -1000px;
box-sizing: content-box;
transform: translate3d(-1000px, -1000px, 0);
pointer-events: none;
}
As you can see, the button is highlighted, and clickable, but other two button can also be clicked.
How can I make only the element in the highlighted area clickable?
Also - are there any product tour/tutorial JS libraries that I should be aware of? Those, that will basically have the functionality that I need.
I have updated your jsfiddle Here
I added pointer-events: none to the button section of your css and gave button One a class of enabledButton.
Then I added pointer-events: auto to the .enabledButton section of your css
With a single line of jquery you can remove the enabledButton class from all buttons:
$("button").removeClass("enabledButton");
You then add the enabledButton class only to the button you highlight.
Now, the button with the class of enabledButton will be clickable while all others are not. This way you explicitly enable the button you want the user to click while all other buttons are disabled by default.
You can use css to do something like
. disabled{
pointer-events : none;
}
And add this class to the other non-highlighted buttons.
Another solution that requires some Javascript, is to add a default Html disabled attribute to your buttons, and remove it only for the highlighted button using innerHTML of something similar.
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";
}
});
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.
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