In my application I want to resize a window when user clicks on panel-heading, but that heading contains a child element- button which has another event handler binded on. What I need to do is, when user click on that button, no resize function will be called. I tried many variations, but none of them worked.
HTML:
<div class="panel-heading" style="cursor:pointer">
<div class="pull-right">
<button type="button" class="btn btn-danger btn-xs" id="btn-subject-remove"><span class="glyphicon glyphicon-remove"></span> Remove</button>
</div>
</div>
And my jq is:
$('#btn-subject-remove').on('click',btnRemoveSubjectsClick);
$('#subscribers-row .panel-heading').on('click',btnResizeClick);
What I have tried, but none of them worked:
$('#subscribers-row .panel-heading').off('click','#btn-subject-remove',btnResizeClick);
$('#btn-subject-remove').off('click',btnResizeClick);
$('#subscribers-row .panel-heading').on('click',btnResizeClick).children().click(function(e){return false});
I also tried checking in btnResizeClick function what element was clicked, and if it was remove button then return false, but the clicked element is still panel-heading
Any suggestions?
Bind a click event on the children and use e.stopPropagation() to block the parent click event.
In a simple example:
$(function() {
$('div').on('click', function() {
$(this).toggleClass('redBg');
});
$('div>*').on('click', function(e) {
e.stopPropagation();
});
});
div {
background: green;
width: 200px;
height: 200px;
}
span {
display: block;
height: 50px;
background: yellow;
}
.redBg {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
With some text
<span> in a span </span>
</div>
Related
I have a multiple buttons has show and hide class. Which is also activate the elements every toggle click. I want to make it a shorter code and make it globally. Please help me how to do it. All I want is to achieve a lesser code and same with the result.. Thank you.
$('.show').on('click', function () {
$(this).addClass('inactive');
$('.hide').removeClass('inactive');
$('.helloworld').removeClass('inactive')
})
$('.hide').on('click', function () {
$(this).addClass('inactive');
$('.show').removeClass('inactive');
$('.helloworld').addClass('inactive')
})
$('.ok').on('click', function () {
$(this).addClass('inactive');
$('.cancel').removeClass('inactive');
$('.thanks').removeClass('inactive')
})
$('.cancel').on('click', function () {
$(this).addClass('inactive');
$('.ok').removeClass('inactive');
$('.thanks').addClass('inactive')
})
<style>
.inactive{
display:none;
}
button{
padding:5px 25px;
color: #fff;
background-color:#1d9bf0;
margin-top: 10px;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="show"> + Show </button>
<button class="hide inactive"> - Hide </button>
<p class="helloworld inactive">Hello WOrld</p>
<br>
<button class="ok"> + Ok </button>
<button class="cancel inactive"> - Cancel </button>
<p class="thanks inactive">Thank you</p>
The technique you're looking for here is DRY, or Don't Repeat Yourself. To do this, look for the common patterns in the logic you have.
In this case each button has its text updated, and it changes the state of it's following sibling. Therefore you can place common class attributes on the elements so that the same JS logic can be applied to them all. From there you can use jQuery's DOM traversal methods to relate the elements to each other, and also data attributes to store custom metadata about the elements which can be used when the click event occurs.
Finally you can use toggleClass() to add/remove the classes to display/hide the elements as necessary.
Here's a working example:
$('.toggle').on('click', e => {
let $btn = $(e.target);
$btn
.text(() => $btn.data($btn.hasClass('show') ? 'hide-text' : 'show-text')).toggleClass('show') // update text
.next().toggleClass('inactive'); // toggle related content
})
<style>
.inactive {
display: none;
}
button {
padding: 5px 25px;
color: #fff;
background-color: #1d9bf0;
margin-top: 10px;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="toggle-container">
<button class="toggle show" data-show-text="+ Show" data-hide-text="- Hide">+ Show</button>
<p class="content inactive">Hello WOrld</p>
</div>
<div class="toggle-container">
<button class="toggle show" data-show-text="+ Ok" data-hide-text="- Cancel">+ Ok</button>
<p class="content inactive">Thank you</p>
</div>
I want to be able to click on a div, but not in the area of another div inside a div inside the outer div.
I tried to select my other div without the inner div using :not() in the selector, but it didn't work.
<div class=outer>
<div class=inner1>
<div class=inner2>
<div class=notClickable>
<div class=alsoNotClickable>
...
</div>
</div>
</div>
</div>
</div>
$("div.outer:not(div.notClickable)").click(function(){
...
});
I expect that I can click inside div class=outer, but not inside div class=notClickable and its childs.
One option is adding stopPropagation() on the non clickable divs.
The stopPropagation() method of the Event interface prevents further
propagation of the current event in the capturing and bubbling phases.
$("div.outer").click(function() {
console.log("click");
});
$("div.notClickable").click(function(e) {
e.stopPropagation();
});
$("div.alsoNotClickable").click(function(e) {
e.stopPropagation();
});
.outer {
width: 300px;
height: 300px;
background-color: green;
}
.notClickable {
width: 100px;
height: 100px;
background-color: red;
}
.alsoNotClickable {
width: 50px;
height: 50px;
background-color: pink;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class=outer>
<div class=inner1>
<div class=inner2>
<div class=notClickable>
<div class=alsoNotClickable>
</div>
</div>
</div>
</div>
</div>
To achieve this you can check the target property of the event. If it matches the element you hooked the event to then you know that the event has not bubbled up from a child. Try this:
$("div.outer").click(function(e) {
if ($(e.target).is('div.outer')) {
console.log('You clicked the outer div');
} else {
console.log('You clicked a child div');
}
});
div.outer,
div.outer div {
padding: 10px;
border: 1px solid #CCC;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="outer">
Outer
<div class="inner1">
Child
<div class="inner2">
Child
<div class="notClickable">
Child
<div class="alsoNotClickable">
Child
</div>
</div>
</div>
</div>
</div>
I think you can stop the propagation by adding this line to your function:
event.stopPropagation();
Eg:
$("div.outer:not(div.notClickable)").click(function(event) {
...
event.stopPropagation();
});
Please check this fiddle where i use the click function. Let me know if that would fits you :)
Assign an ID to the div you want to select. Then select the ID.
I have a web page with 2 sections, Search and Result.
Each section has a button in it.
When the user focus on Search section and presses enter button, the search button should trigger.
Similarly, focusing on Result section and pressing enter button should trigger Save Changes button.
I tried the following code but, I am not getting the expected behavior. Any suggestion / guidance will be much appreciated.
function SetDefaultButton(parentContainer, button) {
$(document).off('keydown', parentContainer).
on('keydown', parentContainer, function (event) {
var eventTarget = event.target;
if (event.keyCode == 13) {
event.preventDefault();
$(button).trigger('click');
}
});
};
SetDefaultButton('#DivSearchSection', '#BtnSearch');
SetDefaultButton('#DivResultSection', '#BtnSave');
$('#BtnSearch').on('click', function(){
alert('Search is triggered');
});
$('#BtnSave').on('click', function(){
alert('Save is triggered');
});
#DivSearchSection
{
min-height:50px;
border:1px solid green;
background-color:lightgreen;
}
#DivResultSection
{
min-height:50px;
border:1px solid red;
background-color:yellow;
}
button{
margin-top:40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="DivContainer">
<div id="DivSearchSection">
This is search section.
<button type="button" id="BtnSearch">Search</button>
</div>
<div id="DivResultSection">
This is result section.
<button type="button" id="BtnSave">Save Changes</button>
</div>
</div>
Attach an onfocus event handler to your sections. You will need to add an tabindex attribute to your sections for it to work.
When the section gets focus, trigger the focus on its child button.
$(function() {
$('#DivSearchSection, #DivResultSection').focus(function() {
// trigger focus on the section's button when the section is focused
$('button', this).focus();
});
$('#BtnSearch').on('click', function() {
alert('Search is triggered');
});
$('#BtnSave').on('click', function() {
alert('Save is triggered');
});
});
#DivSearchSection {
min-height: 50px;
border: 1px solid green;
background-color: lightgreen;
}
#DivResultSection {
min-height: 50px;
border: 1px solid red;
background-color: yellow;
}
button {
margin-top: 40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="DivContainer">
<!-- add tabindex -->
<div id="DivSearchSection" tabindex="-1">
This is search section.
<button type="button" id="BtnSearch">Search</button>
</div>
<!-- add tabindex -->
<div id="DivResultSection" tabindex="-1">
This is result section.
<button type="button" id="BtnSave">Save Changes</button>
</div>
</div>
Related: Is it possible to write onFocus/lostFocus handler for a DIV using JS or jQuery?
I have a list of DIVS that have buttons inside. By default, all buttons are hidden. When I click within a DIV area, the current button inside of this clicked DIV are should show (class='.db') AND all previously clicked/shown buttons should be hidden (class='.dn'). In other words, at any time there should be only one button (currently clicked) shown and all other should be hidden.
I want to use vanilla Javascript and tried this below, but it won't work. I feel there is some small error but don't know where.. Note - the DIVS and buttons don't have their own unique IDs (they only have the same CSS (.posted) classes.
PS - maybe it'd be better not to add this onClick="t();" to each DIV and use an 'addEventListener' function, but this is way too much for me ; )
CSS:
.dn {display:none}
.db {display:block}
.posted {
height: 50px;
width: 100px;
background-color: green;
border: 2px solid red;
}
HTML:
<div class="posted" onClick="t();">
<button class="dn">Reply</button>
</div>
<div class="posted" onClick="t();">
<button class="dn">Reply</button>
</div>
<div class="posted" onClick="t();">
<button class="dn">Reply</button>
</div>
JAVASCRIPT:
function t()
{
var x=document.getElementsByClassName("posted"),i,y=document.getElementsByTagName("button");
for(i=0;i<x.length;i++)
{
x[i].y[0].className="dn";
};
x.y[0].className='db';//make sure the currently clicked DIV shows this button (?)
}
You might want to read more about selector, how to select class, block level etc.
some link might be helpful:
CSS selector:
https://www.w3schools.com/cssref/css_selectors.asp
jQuery selector:
https://api.jquery.com/category/selectors/
Solution - Using jQuery:
$('.posted').on('click', function() {
//find all class called posted with child called dn, then hide them all
$('.posted .dn').hide();
//find this clicked div, find a child called dn and show it
$(this).find('.dn').show();
});
.dn {
display: none
}
.db {
display: block
}
.posted {
height: 50px;
width: 100px;
background-color: green;
border: 2px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="posted">
<button class="dn">Reply1</button>
</div>
<div class="posted">
<button class="dn">Reply2</button>
</div>
<div class="posted">
<button class="dn">Reply3</button>
</div>
Solution - Pure js version:
//get list of div block with class="posted"
var divlist = Array.prototype.slice.call(document.getElementsByClassName('posted'));
//for each div
divlist.forEach(function(item) {
//add click event for this div
item.addEventListener("click", function() {
//hide all button first
divlist.forEach(function(el) {
el.getElementsByTagName('button')[0].classList.add('dn');
});
//show button of the div clicked
this.getElementsByTagName('button')[0].classList.remove('dn');
}, false);
});
.dn {
display: none
}
.db {
display: block
}
.posted {
height: 50px;
width: 100px;
background-color: green;
border: 2px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="posted">
<button class="dn">Reply1</button>
</div>
<div class="posted">
<button class="dn">Reply2</button>
</div>
<div class="posted">
<button class="dn">Reply3</button>
</div>
You can do this with with plain JavaScript using Event Bubbling, querySelector and the element classList attribute like this.
Change your HTML to look like this:
<div class="posts">
<div class="posted">
<button class="dn">Reply</button>
</div>
<div class="posted" >
<button class="dn">Reply</button>
</div>
<div class="posted" >
<button class="dn">Reply</button>
</div>
</div>
Then use JavaScript like this:
var posts = document.querySelector('.posts');
var allPosted = document.querySelectorAll('.posted');
//clicks bubble up into the posts DIV
posts.addEventListener('click', function(evt){
var divClickedIn = evt.target;
//hide all the buttons
allPosted.forEach(function(posted){
var postedBtn = posted.querySelector('button');
postedBtn.classList.remove('db');
});
// show the button in the clicked DIV
divClickedIn.querySelector('button').classList.add('db')
});
You can find a working example here: http://output.jsbin.com/saroyit
Here is very simple example using jQuery .siblings method:
$(function () {
$('.posted').click(function () {
$('button', this).show();
$(this).siblings().find('button').hide();
});
});
https://jsfiddle.net/3tg6o1q7/
I have three buttons and I want to toggle between them. How can I add and remove the toggle and untoggle classes to have to toggle appropriately.
Right now, both buttons can be selected/toggled on. There should only be one button toggled at a time but I also want to be able to deselect/untoggle all of the buttons. So that I have
an option of not toggling the buttons on.
Here's the buttons in my view:
<div id="drawing">
<div style="margin-top: 12px; padding-left: 8px; margin-bottom: 8px">
<button class="small-button" onclick="Drawing.AngleClick()" data-val-btnname="Angle" style="width: 70px; height: 20px;"><span>#Culture.GetString("Angle")</span></button>
</div>
<div style="margin-top: 12px; padding-left: 8px;">
<button class="small-button" onclick="Drawing.PointClick()" data-val-btnname="Point" style="width: 70px; height: 20px;"><span style="font-size:10px !important">#Culture.GetString("Point")</span></button>
<button class="small-button" data-val-btnname="ClearAll" style="width: 70px;" onclick="Drawing.Delete()"><span>#Culture.GetString("ClearAll")</span></button>
</div>
</div>
Here's the js function so far for one of the buttons (I have the same if statement in my other button):
AngleClick: function () {
var button = $('body').find("button[data-val-btnname='Angle']");
if (button.hasClass('small-toggled-button')) {
button.removeClass('small-toggled-button').addClass('small-button');
} else {
button.removeClass('small-button').addClass('small-toggled-button');
}
}
This is an easy method for toggling buttons. Run the snippet to see it work. I simplified your HTML only for the sake of shortening the example--I'm not suggesting you change it.
$(document).ready(function() {
$("#drawing button").click(function(e) {
var isActive = $(this).hasClass('active');
$('.active').removeClass('active');
if (!isActive) {
$(this).addClass('active');
}
});
});
.active {
background: #555555;
color: #ffffff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="drawing">
<button class="small-button">Angle</button>
<button class="small-button">Point</button>
<button class="small-button">ClearAll</button>
</div>