Toggle modal with vanilla javascript - javascript

I'm used to working with jQuery but I'm trying to get back to vanilla javascript. I have a link that when clicked will reveal an account modal.
I also want to change the class of the modal when clicked to 'modal-visible'. This works as expected, but then when I click the link again to close the modal, I need the class to change back to 'modal-hidden'.
I wondered if someone could help me with that. Perhaps it needs a toggle instead?
var accountModal = document.getElementById("account-modal");
document.querySelector('#account-photo').addEventListener('click', function(e) {
e.preventDefault();
accountModal.classList.add('modal-visible');
accountModal.classList.remove('modal-hidden');
accountModal.setAttribute('aria-hidden', 'false');
});
<a id="account-photo" href="/customer" tabindex="0" aria-expanded="false">Account</a>
<div id="account-modal" class="modal-visible" aria-label="Account Information" aria-hidden="false">Account Info</div>

Here's a way of doing it if we assume it always begins closed:
document.querySelector('#account-photo').addEventListener('click', function() {var is_visible = false; return function(e) {
e.preventDefault();
if(!is_visible) {
accountModal.classList.add('modal-visible');
accountModal.classList.remove('modal-hidden');
accountModal.setAttribute('aria-hidden', !is_visible);
is_visible = true;
} else {
accountModal.classList.remove('modal-visible');
accountModal.classList.add('modal-hidden');
accountModal.setAttribute('aria-hidden', !is_visible);
is_visible = false;
}
}});
This method basically acts as a manually coded toggle.

Related

Use jquery to hide custom modal when the user clicks outside of it

Duplicate:
Yes it is. Below is the references which I searched on stack overflow.
Reference 1
Reference 2
Reference 3
Reference 4
What I am looking for:
Actually I am making custom modal without using bootstrap. Overall my code is working fine and below is the live example of it:
$(window).click(function(e){
let classname = e.target.className;
if(classname == "ah-modal-wrapper") {
e.target.style.display = 'none';
}
});
Fiddle
Problem is when I select my inner text of modal and release my selection outside from modal its hide / close the modal. But my need is when I click outside of a modal then modal should closed immediately. Which is working fine. but I don't want that modal closed while releasing the mouse click outside from modal.
For more clearance please review below example:
Bootstrap Modal Example
Here is working code:
$('.ah-modal-wrapper').on('mousedown', function(e) {
$(this).hide();
});
$('.ah-modal').on('mousedown', function(e){
e.stopPropagation();
});
Also updated jsfiddle
Below is the code (answer) of my own question.
let istextSelected = false;
$(window).click(function(e){
let classname = e.target.className;
if(classname == "ah-modal-wrapper") {
if(istextSelected == false) {
e.target.style.display = 'none';
}
istextSelected = false;
}
});
$(".ah-modal").on('mousedown',function(e){
istextSelected = true;
});
Fiddle

Javascript function interacts with other function

I am completely new to javascript (and jquery) and have been experimenting with drop down menus the past couple of days. I found this one fancy notification menu, and I tried to see what happens when I have two of them on the page. Anyways, I made a quick example of my problem here:
http://jsfiddle.net/rgt03mu4/24/
The problem is that I can have both notification containers open up if I click on both.
If I am already clicked on one of the bells, then I click on the other, it should close the other one. Instead it keeps it open, and even when you click on the other container one, it still doesn't close it. You have to click off the page or click the notification bells. I am trying to make it to where you can only have one open at a time. So in order to do this, I tried changing the names of the functions:
As you can see:
$(function() {
var nContainer = $(".notification-popup-container");
//notification popup
$("#notification-link").click(function() {
nContainer.fadeToggle(300);
return false;
});
//page click to hide the popup
$(document).click(function() {
nContainer.hide();
});
//popup notification bubble on click
nContainer.click(function() {
return false;
});
});
I added the next function to be called test(), which you would think, since it's an entirely new function it would work differently. Instead, the error still persists.
What am I doing wrong? I even gave the the new bell it's own divs and link name. I also renamed container to container2.
Set the global variable for your container:
var nContainer = $(".notification-popup-container");
var nContainer2 = $(".notification2-popup-container");
$(function() {
var nContainer = $(".notification-popup-container");
//notification popup
$("#notification-link").click(function() {
nContainer.fadeToggle(300);
nContainer2.hide(); //hide the second container
return false;
});
//page click to hide the popup
$(document).click(function() {
nContainer.hide();
});
//popup notification bubble on click
nContainer.click(function() {
return false;
});
});
And you can do same with other function.
DEMO
There is no need to give the popup containers different classnames.
I would give the a-tags a common classname instead of an id. The href can be used to identify the target popup, so the binding between the link and the target popup is set in the origin of action. The JS part would be abstracted and could be reused.
<a class='notification-link' href='#firstpopup'>X</a>
<a class='notification-link' href='#secondpopup'>X</a>
<div class='notification-popup-container' id="firstpopup">
... firstpopup
</div>
<div class='notification-popup-container' id="secondpopup">
... secondpopup
</div>
The click handler first hides all the popups before opening a new one.
$(".notification-link").click(function () {
$(".notification-popup-container").hide();
var targetId = $(this).attr('href');
$(targetId).fadeIn(300);
return false;
})
working example: http://jsfiddle.net/qyLekdwk/
The problem here is how the event propgation is handled
$(function () {
var nContainer = $(".notification-popup-container");
//notification popup
$("#notification-link").click(function () {
nContainer.fadeToggle(300);
});
//page click to hide the popup
$(document).click(function (e) {
if (!$(e.target).closest('#notification-link, .notification-popup-container').length) {
nContainer.hide();
}
});
});
$(function test() {
var nContainer2 = $(".notification2-popup-container");
//notification popup
$("#notification2-link").click(function test() {
nContainer2.fadeToggle(300);
});
$(document).click(function (e) {
if (!$(e.target).closest('#notification2-link, .notification-popup-container').length) {
nContainer2.hide();
}
});
});
Demo: Fiddle

Javascript - Click Button to FadeIn, FadeOut by clicking anywhere

I want my navigation to fade-in when a special button is clicked, and to fade away when the user is clicking somewhere else - doesn't matter where.
My Script looks like this:
function showText() {
var spoiler = document.getElementById('spoiler');
var button = document.getElementById('navicon');
if (spoiler.style.display == 'block') {
spoiler.style.display='none';
button.value = 'Text einblenden';
} else {
spoiler.style.display='block';
button.value = 'Text ausblenden';
}
return false;
}
My workaround was to give every navigation element the following code snippet.
onclick="$('#thedivlayeriwanttofadeout').fadeOut('slow');"
Can anybody help me?
Use bubbling to attach a single click handler to a common parent element (for example, body).
Here's a simple example:
$(function () {
$("#myButton").click(function (e) {
$("#hidden").fadeIn();
return false;
});
$("#parent").click(function() {
$("#hidden").fadeOut();
});
});
Clicking the button will fade in the element with id hidden. Clicking anywhere in parent will fade it out again.

X-Editable: stop propagation on "click to edit"

I have an editable element inside a div which itself is clickable. Whenever I click the x-editable anchor element, the click bubbles up the DOM and triggers a click on the parent div. How can I prevent that? I know it's possible to stop this with jQuery's stopPropagation() but where would I call this method?
Here's the JSFiddle with the problem: http://jsfiddle.net/4RZvV/ . To replicate click on the editable values and you'll see that the containing div will catch a click event. This also happens when I click anywhere on the x-editable popup and I'd like to prevent that as well.
EDIT after lightswitch05 answer
I have multiple dynamic DIVs which should be selectable so I couldn't use a global variable. I added an attribute to the .editable-click anchors which get's changed instead.
editable-active is used to know if the popup is open or not
editable-activateable is used instead to know if that .editable-click anchor should be treated like it is
$(document).on('shown', "a.editable-click[editable-activateable]", function(e, reason) {
return $(this).attr("editable-active", true);
});
$(document).on('hidden', "a.editable-click[editable-activateable]", function(e, reason) {
return $(this).removeAttr("editable-active");
});
The check is pretty much like you've described it
$(document).on("click", ".version", function() {
$this = $(this)
// Check that the xeditable popup is not open
if($this.find("a[editable-active]").length === 0) { // means that editable popup is not open so we can do the stuff
// ... do stuff ...
}
})
For the click on the links, simply catch the click event and stop it:
$("a.editable-click").click(function(e){
e.stopPropagation();
});
The clicks within X-editable are a bit trickier. One way is to save a flag on weather the X-editable window is open or not, and only take action if X-editable is closed
var editableActive = false;
$("a.editable-click").on('shown', function(e, reason) {
editableActive = true;
});
$("a.editable-click").on('hidden', function(e, reason) {
editableActive = false;
});
$("div.version").click(function(e) {
var $this;
$this = $(this);
if(editableActive === false){
if ($this.hasClass("selected")) {
$(this).removeClass("selected");
} else {
$(this).addClass("selected");
}
}
});
Fixed Fiddle
It's not pretty, but we solved this problem with something like:
$('.some-class').click(function(event) {
if(event.target.tagName === "A" || event.target.tagName === "INPUT" || event.target.tagName === "BUTTON"){
return;
}
We're still looking for a solution that doesn't require a specific list of tagNames that are okay to click on.

Popovers not showing up on first click but show up on second click

I found a related post which did not help:
Twitter bootstrap:Popovers are not showing up on first click but show up on second click
The difference is in my page I have several elements which require popover (several tips-icon), so I need to loop over them..
My markup:
<img class="help_icon" src="http://media.mysite.com/pub/images/help/tips-icon.png">
This is my javascript:
var h=document.getElementsByName("click_help_container");
for (i=0;i<h.length;i++)
{
$('#'+h[i]['id']).click(
function ()
{
var id=$(this).attr("id");
getHelp(id,$(this),function(t,elem)
{
var isVisible = false;
var clickedAway = false;
$(elem).unbind('click');
$(elem).popover(
{
"title":t.title,
"content":"<p class='popover_body_text'>"+t.content+"</p>",
"html":true,
"animation":true,
"placement":"bottom",
"trigger":"manual"
}).click(function(e)
{
$(this).popover('show');
clickedAway = false;
isVisible = true;
e.preventDefault();
});
$(document).click(function(e) {
if(isVisible & clickedAway)
{
$(elem).popover('hide')
isVisible = false;
clickedAway = false;
}else
{
clickedAway = true;
}
});
//$(elem).popover('show');
});
});
}
The problem is when I click on the tips-icon.png button, the popover doesn't show up on first click (I guess it's because I have 2 .click() calls When I click on the button the second time popover shows up and it then maintains it's toggle behavior from there onwards.
You don't need to loop through all elements and initialize popovers one by one, you can apply popover to all items with this name at once (same as you're doing in loop).
And you don't need to show/hide popovers manually by yourself, bootstrap can do it for you.
I think this should work for you:
$("a[name='click_help_container']").popover(
{
"title":t.title,
"content":"<p class='popover_body_text'>"+t.content+"</p>",
"html":true,
"animation":true,
"placement":"bottom",
"trigger":"click"
});

Categories

Resources