On clicking on a specific child a different jQuery should run - javascript

I developed a UI where you will click a card it will pop up but inside that card there are two links on which when I click it should not pop back. I know that those links are part of that card and I put an event on the card selector.
So I want to achieve this scenario:
When user clicks on a card no matter where ... it should pops up.. (Its doing it right now) but when user clicks on those two links it should not pop back ... it should show tabs which I will handle myself ... Just need a way that it should not pop back on clicking on those links because I want to fire another event to display tabs on those links.
I tried it with :not but it didn't work for me.
var card = $('.card');
card.click(function() {
if ($(this).hasClass('gravitate')) {
$(this).removeClass('gravitate');
$(this).addClass('levitate');
} else {
$(this).addClass('gravitate');
$(this).removeClass('levitate');
}
});
* {
padding: 0;
margin: 0;
}
body {
padding: 30px;
}
.card {
border: #ececec 1px solid;
padding: 10px;
width: 200px;
margin-bottom: 10px;
}
.tab-pane {
display: none;
}
.transition {
transition: all 500ms
}
.gravitate {
box-shadow: 0 0 18px 3px rgba(0, 0, 0, 0);
width: 200px;
transform: translate(0, 0);
}
.levitate {
box-shadow: 0 0 18px 3px rgba(0, 0, 0, 0.3);
width: 220px;
transform: translate(-10px, 5px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="card gravitate transition">
<h4>Sample Card</h4>
First Name | Last Name
<div class="tab-pane first-name">Omer</div>
<div class="tab-pane last-name">Hussain</div>
</div>
<div class="card gravitate transition">
<h4>Sample Card</h4>
First Name | Last Name
<div class="tab-pane first-name">Usman</div>
<div class="tab-pane last-name">Ali</div>
</div>

You can add an event handler to your links to check if the parent card has the levitate class and if so, stop the click event from bubbling up the DOM and triggering your other event handler:
$('a.tab').click(function(e) {
if ($(this).parent().hasClass('levitate')) {
e.stopPropagation();
}
})
var card = $('.card');
card.click(function() {
if ($(this).hasClass('gravitate')) {
$(this).removeClass('gravitate');
$(this).addClass('levitate');
} else {
$(this).addClass('gravitate');
$(this).removeClass('levitate');
}
});
$('a.tab').click(function(e) {
if ($(this).parent().hasClass('levitate')) {
e.stopPropagation();
}
})
* {
padding: 0;
margin: 0;
}
body {
padding: 30px;
}
.card {
border: #ececec 1px solid;
padding: 10px;
width: 200px;
margin-bottom: 10px;
}
.tab-pane {
display: none;
}
.transition {
transition: all 500ms
}
.gravitate {
box-shadow: 0 0 18px 3px rgba(0, 0, 0, 0);
width: 200px;
transform: translate(0, 0);
}
.levitate {
box-shadow: 0 0 18px 3px rgba(0, 0, 0, 0.3);
width: 220px;
transform: translate(-10px, 5px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="card gravitate transition">
<h4>Sample Card</h4>
First Name | Last Name
<div class="tab-pane" class="first-name">Omer</div>
<div class="tab-pane" class="last-name">Hussain</div>
</div>
<div class="card gravitate transition">
<h4>Sample Card</h4>
First Name | Last Name
<div class="tab-pane" class="first-name">Usman</div>
<div class="tab-pane" class="last-name">Ali</div>
</div>

If I understand it right, you want that any click on the card expands/retracts it, but not if the user clicks any of the links. If so, it's as simple as handling the hyperlinks click function separately and preventing the event to propagate. Just add this to your JavaScript:
var cardTabs = $('.tab');
cardTabs.click(function() {
alert("your handler");
return false;
});
You can also use prevent default and stop propagation methods of the click event, which are equivalent (see: event.preventDefault() vs. return false)
var cardTabs = $('.tab');
cardTabs.click(function(e) {
alert("your handler");
e.preventDefault();
e.stopPropagation();
});

Related

double event when opening modal more than once

I have a modal that when I open it, it detects a single click, until there everything is correct, the problem is when I close it and open it again, it begins to detect a double event (click) and if I close and open it again detects 3 events (clicks), it is made in vanilla js
HTML:
<div id="modal-container-gestion-documental" class="modal-container-gestion-documental">
<div class="modal-gestion-documental">
<div class="cabecera-modal">
<h3 class="">Gestión Documental</h3>
CERRAR
</div>
<br>
<div class="div-padre-gestor">
</div>
</div>
</div>
Javascript:
const modalContainerGestionDocumental = document.getElementById(
"modal-container-gestion-documental"
);
document.addEventListener("click", (e) => {
if (e.target.matches(".abrir-gestion-documental")) {
e.preventDefault();
modalContainerGestionDocumental.classList.add("show-modal");
}
if (e.target.matches(".cerrar-gestion-documental")) {
e.preventDefault();
modalContainerGestionDocumental.classList.remove("show-modal");
}
}
Css:
.modal-container-gestion-documental {
z-index: 2;
margin: 0 auto;
display: flex;
background-color: rgba(0, 0, 0, 0.3);
align-items: center;
justify-content: center;
position: fixed;
pointer-events: none;
top: 0;
left: 0;
height: 100vh;
width: 100vw;
opacity: 0;
}
.modal-gestion-documental{
margin-top: 75px;
padding: 3rem;
background-color: #fff;
width: 85%;
height: 88%;
border-radius: 5px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.show-modal {
pointer-events: auto;
opacity: 1;
}
Depends on where you have this document.addEventListener("click.. part of the code. Based on your description, it seems like that listener is being triggered every time the modal opens/closes.
Make sure to get the listener to be triggered only once on page load. If it's unavoidable, you can removeEventListener whenever the modal closes.

How can I keep onClickOutside() method disabled until I use onClick()?

When I click on my element with an event listener I supposed to get my popup shown, which works just fine until I introduce onClickOutside(). Using ng-click-outside
export class Component {
private isPopupDisplayed: boolean = false;
onClick() {
console.log('Clicked');
this.isPopupDisplayed = true;
}
onClickedOutside(event) {
this.isPopupDisplayed = false;
}
}
.popup{
position: absolute;
z-index: 3;
width: 200px;
height: 94px;
background-color: $secondary-color;
left: 0%;
bottom: 0%;
padding: 15px 0px;
margin: 12px;
border: 1px solid $modal-border-color;
border-radius: 4px;
box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.25);
li:hover {
background-color: $accent-color;
}
li {
padding-top: 5px;
height: 32px;
}
}
<div *ngIf="isPopupDisplayed" >
<ul class="popup" (clickOutside)="onClickedOutside($event)">
<li><a>My Details</a></li>
<li><a>Sign out</a></li>
</ul>
</div>
<div class="presenter-menu_avatar" (click)="onClick()" >
<img [src]="avatarUrl">
</div>
When I am trying to introduce onClickOutside() method, I can see that both methods are triggered at the same time as my popup still not there and that automatically triggers not even showing it up.
My aim is to simply show the popup when onClick() and hide it when clicked outside of it.
Add stopPropagation event in click function
onClick(event) {
event.stopPropagation()
console.log('Clicked');
this.isPopupDisplayed = true;
}
<div class="presenter-menu_avatar" (click)="onClick($event)" >
<img [src]="avatarUrl">
</div>

onblur event is not firing

I need to fire onblur event when I click outside "aside panel", in order to make the panel close if user clicks outside navigation panel.
Though I'm using React JS - but for simplicity I've written example in pure JavaScript.
Lately I've written something similar and everything works fine, but in this case it's not working, may be because of position fixed.
var d = document.getElementById("fname");
d.addEventListener("blur", myFunction);
function myFunction() {
alert("Input field lost focus.");
}
var state = true;
function myFunction2() {
state = !state;
if (state) {
d.className = "header__aside";
} else {
d.className += " header__aside--open";
}
}
.main {
background-color: violet;
padding: 50px;
}
.header__aside {
background-color: #cfcfcf;
box-shadow: 0 19px 38px rgba(0, 0, 0, 0.3), 0 15px 12px rgba(0, 0, 0, 0.22);
font-size: 1.2rem;
height: 100%;
opacity: 0.9;
position: fixed;
right: -30%;
top: 0;
transition: right 0.5s ease-out;
width: 30%;
z-index: 10;
}
.header__aside--open {
right: 0;
}
<p class='main'>This example</p>
<button type="button" onClick="myFunction2()">
☰
</button>
<div class="header__aside" id="fname">
<div class="aside-nav">
<div class="aside-nav__header">
<button type="button" class="aside-nav__header-button" onClick="myFunction2()">x</button>
</div>
<nav class="nav nav__aside">
<a class="nav__aside-link active" aria-current="true" href="/">Main</a>
</nav>
</div>
</div>
To have Onblur on an element it should receive focus first, Div elements don't receive focus by default. You can add tabindex="0"
<div tabindex="0" ....
Thanks to Emil, for react you can use
tabIndex={0}
You will have to set a tabindex on the div and manually focus it to get the blur handler invoked
var d = document.getElementById("fname");
d.addEventListener("blur", myFunction);
function myFunction() {
alert("Input field lost focus.");
}
var state = true;
function myFunction2() {
state = !state;
d.focus();
if (state) {
d.className = "header__aside";
} else {
d.className += " header__aside--open";
}
}
.main {
background-color: violet;
padding: 50px;
}
.header__aside {
background-color: #cfcfcf;
box-shadow: 0 19px 38px rgba(0, 0, 0, 0.3), 0 15px 12px rgba(0, 0, 0, 0.22);
font-size: 1.2rem;
height: 100%;
opacity: 0.9;
position: fixed;
right: -30%;
top: 0;
transition: right 0.5s ease-out;
width: 30%;
z-index: 10;
}
.header__aside--open {
right: 0;
}
<p class='main'>This example</p>
<button type="button" onClick="myFunction2()">
☰
</button>
<div class="header__aside" id="fname" tabindex="0">
<div class="aside-nav">
<div class="aside-nav__header">
<button type="button" class="aside-nav__header-button" onClick="myFunction2()">x</button>
</div>
<nav class="nav nav__aside">
<a class="nav__aside-link active" aria-current="true" href="/">Main</a>
</nav>
</div>
</div>
Add tabindex=0 to the panel-html and focus() to the JS opening the panel:
<div id=panel tabindex=0></div>
document.getElementById('panel').onclick = function(){
document.getElementById('panel').style.display = 'block';
document.getElementById('panel').focus();
document.getElementById('panel').onblur = function(){
document.getElementById('panel').style.display = 'none';
}
}

Switch Div on button Click

I am trying to create a carousel like effect on divs such thta when i click on a but, the next div displays and the previous one fadeOut. Below is my code
var oCurImage = $(".webTut div.current");
var oNxtImage = $(oCurImage).next();
var leftBtn = $('.tutLeft'), rightBtn = $('.tutRight');
$(rightBtn).click(function() {
oCurImage.fadeOut().removeClass('current');
oNxtImage.fadeIn().addClass('current').animate({opacity: 1.0}, 1000);
if (oNxtImage.length == 0) {
oNxtImage = $(".webTut div:first-child");
}
});
HTML
<div class="webTut">
<span class="tutBtn"><a class="tutLeft"><i class="fa fa-angle-left"></i></a><a class="tutRight"><i class="fa fa-angle-right"></i></a></span>
<div class="current">
<img src="images/egold.png">
<h1>cname</h1>
<h3>Welcome to nigeriaeexport.com</h3>
<p>Your one stop platform for everything export</p>
</div>
<div style="background: #fff;"></div>
<div style="background: #dd0d0d;"></div>
</div>
css
.webTut div {
width: 60%;
height: 80%;
background: #28bc88;
margin: 6.5% auto 0 auto;
border-radius: 4px;
box-shadow: 0 0 4px rgba(0,0,0,.5);
-webkit-box-shadow: 0 0 4px rgba(0,0,0,.5);
text-align: center;
display: none;
/*854 x 720*/
}
.webTut div.current {
display: block;
z-index: 1;
}
The thing is i have used this same method with setInterval for an image slider but here when i click on the button the first time, it shows the next div (the white one) but when i click again, it doesn't change to the next div (the red one #dd0d0d). What could be the issue and how do i fix. Thanks.
Once you click on right anchor tag you should change value of oCurImage and oNxtImage and for getting first div inside div with class .webTut you should use $(".webTut div:first");
You can run below code snippet.
var oCurImage = $(".webTut div.current");
var oNxtImage = $(oCurImage).next();
var leftBtn = $('.tutLeft');
var rightBtn = $('.tutRight');
$(rightBtn).click(function() {
oCurImage.fadeOut().removeClass('current');
if (oNxtImage.length == 0) {
oNxtImage = $(".webTut div:first");
}
oNxtImage.fadeIn().addClass('current').animate({opacity: 1.0}, 1000);
oCurImage = $(".webTut div.current");
oNxtImage = $(oCurImage).next();
});
.webTut div {
width: 60%;
height: 80%;
background: #28bc88;
margin: 6.5% auto 0 auto;
border-radius: 4px;
box-shadow: 0 0 4px rgba(0,0,0,.5);
-webkit-box-shadow: 0 0 4px rgba(0,0,0,.5);
text-align: center;
display: none;
/*854 x 720*/
}
.webTut div.current {
display: block;
z-index: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="webTut">
<span class="tutBtn"><a class="tutLeft">left</a> <br/><br/><a class="tutRight">right</i></a></span>
<div class="current">
<h1>cname</h1>
<h3>Welcome to nigeriaeexport.com</h3>
<p>Your one stop platform for everything export</p>
</div>
<div style="background: #fff;">First Div</div>
<div style="background: #dd0d0d;">Second Div</div>
</div>

jQuery - Click registered twice

I am making a web app that utilizes several pop ups. Inside the pop up, I have customized buttons (wrapped in <label>) that upload files. When I click on the button, it fires twice. I can solve the firing twice issue with e.preventDefault(); but obviously, it doesn't open the window for the user to upload a file.
if (document.getElementById("addItemModal").style.display !== 'none'){
$("#uploadImg").on('click', function(e) {
e.preventDefault();
console.log("I clicked upload image button.");
});
$("#uploadData").on('click',function() {
console.log("I clicked upload data button.");
});
}
So it seems that the first click is what opens the window to upload files and the second click is still a mystery. Where could this second click be coming from? I've tried .unbind as well and nothing seems to work.
EDIT: Added Code - Sorry for the wait, had to take out a lot but keep it functional and true to my problem.
var modal = document.getElementById('myModal');
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
// Click Add Icon to make pop up appear
$("#myBtn").click(function() {
$("#myModal").fadeIn("fast");
$("#addModal").fadeIn("fast");
});
// Click 'x'
$("#close1").click(function() {
$("#myModal").fadeOut("fast");
});
if (document.getElementById("myModal").style.display != 'none') {
console.log("Pls don't be running twice.");
$("#upImgBtn").on('click', function(evt) {
evt.preventDefault();
console.log("I clicked upload image button.");
});
document.getElementById("upDataBtn").addEventListener('click', function() {
console.log("I clicked upload data button.");
});
}
html,
body {
height: 100%;
padding: 0;
margin: 0;
overflow: hidden;
}
/* -- Edited Headers ----------------------- */
h4 {
color: #333;
display: inline-block;
font-size: 1.6em;
letter-spacing: 3px;
font-weight: 500;
}
/* ---------------------------------------- */
.sideBar {
position: relative;
width: 18%;
height: 90%;
float: left;
z-index: 100;
border-right-style: solid;
border-right-width: thin;
border-right-color: #333;
background-color: white;
}
/* -- Header & Location ------------- */
.headbar {
height: 7%;
background-color: ghostwhite;
margin-bottom: 20px;
box-shadow: 0 3px 10px 1px #888888;
}
#myBtn {
float: right;
position: relative;
padding: 9px 3px 0 0;
cursor: pointer;
display: inline-block;
}
.uploadBtns {
padding: 10px 15px 10px 15px;
background-color: blue;
color: white;
border-radius: 5px;
cursor: pointer;
box-shadow: 0 1px 5px 0 #888;
}
#myModal {
display: none;
position: fixed;
z-index: 1000000;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.5);
}
/* Modal Content */
#addModal {
background-color: #fefefe;
margin: auto;
padding: 20px;
border: 1px solid #888;
width: 800px;
border-radius: 15px;
color: #404040;
}
/* -- Add Location Pop Up CSS ------ */
#addTable {
width: 100%;
height: 200px;
background-color: transparent;
border-collapse: collapse;
}
td {
background-color: transparent;
border-bottom: 1px solid #333;
}
tr {
height: 100px;
}
.gridTitle {
padding-left: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sideBar" class="sideBar">
<div id="headbar" class="headbar">
<h5> Home</h5>
<div id="myBtn"><span id="addIcon">+</span>
</div>
</div>
</div>
<div id="myModal">
<div id="addModal">
<h4 id="header">ADD ITEM</h4>
<span class="myClose" id="close1">×</span>
<hr>
<table id="addTable">
<tr id="step1">
<td class="gridTitle">UPLOAD</td>
<td></td>
<td colspan="2">
<label class="btn btn-file uploadBtns" id="upImgBtn">
Upload Image
<input type="file" accept="image/*" style="display: none;" id="upImg">
</label>
<label class="btn btn-file uploadBtns" style="margin-left:120px;" id="upDataBtn">
Upload Data File
<input type="file" style="display: none;" id="upData">
</label>
</td>
</tr>
</table>
</div>
</div>
EDIT2: I haven't included the script twice in my HTML either.
All this is happening because you are adding event to the label.
Here is your code in jsfiddle.
document.getElementById("upData").addEventListener('click', function() {
alert("I clicked upload data button.");
});
You can also make a control which element fired the event. You can put your event on label and alert only if the event was from label but this doesn't stop the click event to happen on the input button.
document.getElementById("upDataBtn").addEventListener('click', function(event) {
if( event.target.tagName === "LABEL" ) {
alert("I clicked upload data button.");
}
});
It is called once or twice cause of the bubbling because the input element is part of the label and is one union and therefor also received the event if the label is click (is is not bubbling, you can't do event.stopPropagation()).
If you make
document.getElementById("upDataBtn").addEventListener('click', function(event) {
console.log(event.target.tagName);
});
This will give you two tag names
LABEL
INPUT
Try this
$(document).on('click',"#upImgBtn", function(e) {
if (e.target !== this)
return;
console.log("I clicked upload image button.");
});
$(document).on('click','#upDataBtn', function(e) {
if (e.target !== this)
return;
console.log("I clicked upload data button.");
});

Categories

Resources