How to remove conflict between click event and programmatically triggered click event - javascript

I am trying to remove ul element on click of body element and ignore if the click target is on the ul element itself otherwise click execute and ul get removed.
Every thing works well but a programmatic click from another js removes ul after its execution which is a problem.The ul should be removed by the user interaction only. Please help me to solve this conflict.
<div class="search-input">
<ul>
<li><a href='#'>1</a></li>
<li><a href='#'>2</a></li>
</ul>
</div>
$(document).on('click','body', function(e) {
if(!$(e.target).closest(".search-input").find('ul').length > 0) {
$('.search-input ul').remove();
}
});
// programmatic click trigger
$(hotspot).trigger("click", true);
The above programmatic click event execute the body click event which is not required.

Put this condition.
is_click = true;
$(document).on('click','body', function(e) {
if(is_click){
if(!$(e.target).closest(".search-input").find('ul').length > 0) {
$('.search-input ul').remove();
}
if(!$(e.target).closest(".input-search").find('ul').length > 0) {
$('.input-search ul').remove();
}
}
});
and for programmatic click trigger
is_click = false;
$(hotspot).trigger("click", true);
is_click = true;

Related

Click outside menu to close it

Here's my function,
$(document).ready(function () {
$('.a').click(function () {
var here = $(this).next('.b');
if (here.is(":visible")) {
here.hide();
} else {
here.show();
}
return false;
});
});
So, whenever I click the button it opens a small tab on same webpage & whenever I click it again it closes it. But once I open the tab I can't close it by just clicking somewhere on webpage apart from tab. I have to click the button again to close it.
How can I close tab just by clicking somewhere on webpage also by on the button?
I end up searching for this on almost every project, so I made this plugin:
jQuery.fn.clickOutside = function(callback){
var $me = this;
$(document).mouseup(function(e) {
if ( !$me.is(e.target) && $me.has(e.target).length === 0 ) {
callback.apply($me);
}
});
};
It takes a callback function and passes your original selector, so you can do this:
$('[selector]').clickOutside(function(){
$(this).removeClass('active'); // or `$(this).hide()`, if you must
});
Nice, chainable, elegant code.
On document click, the closest helps to check whether the tab has been clicked or not:
$(document).click(function (e) {
if($('.b').is(':visible')&&!$(e.target).closest('.b').length){
$('.b').hide();
}
});
You want to check for a click on the body :
$("body").click(function(e) {
if(e.target.id !== 'menu'){
$("#menu").hide();
}
});
menu would be the id of the menu.
If the body is clicked and the id of the div clicked doesn't equal that of the menu, then it closes.
Check this implementation
jQuery(document).ready(function() {
$(document).on('click','body, #btn',function(ev){
ev.stopPropagation()
if(ev.target.id== "btn"){
if($('#modal').is(':visible')) {
$('#modal').fadeOut();
} else{
$('#modal').fadeIn();
}
} else {
$('#modal').fadeOut();
}
});
});
html, body {
height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">
Click Me!
</button>
<div id="modal" style="background-color:red;display:none;">
BLA BLA BLA
</div>
To check if the clicked element is outside of a given container, i.e. a menu, we can simply check if the event target is a child of the container. Using JQuery -
$('body').click(function(e) {
if ( 0 === $(e.target).parents('#container-id').length ) {
/// clicked outside -> do action
}
})
you have to add a click listener to the parent element, like here:
$('.parent-div').click(function() {
//Hide the menus if visible
});
Also because click events bubbled up from child to the parent,
you can exclude the click on the child element to get bubbled up and count as the parent click too. you can achieve this like below:
//disable click event on child element
$('.child-div').click(function(event){
event.stopPropagation();
});

Enable click on only one child jquery

So I have the following html
<li clas='k-item'>
<input type='checkbox'>
<span>ABC</span>
</li>
Is there any way I can bind click to only input and disable for span and li?
This is what I tried, but it doesn't seem to work
$('.k-item').on('click', function (e) {
$(this).unbind('click');
if ($(e.target).is('input')) {
$('input').bind('click');
}
});
I do not have much experience with jquery
You need to use:
$('.k-item input').click(function(){
//modify the rest handler code...
});
Update: if click is defined for li, and you don't want that to be triggered on child span then you will need to stop event propagation.
$('.k-item span').click(function(e){
e.stopPropagation();//do not trigger parent click on child span
});
Why not just target the input to begin with? You can then use e.stopPropagation() to prevent the LI from getting the click event (which is I gather your aim):
$('.k-item input').click(function (e) {
// Stop the LI from firing a click event
e.stopPropagation();
// input is clicked
});
You need only this:
$('.k-item').on('click', function (e) {
if ($(e.target).is('input')) {// or event.target.type
//do stuff
}
});
Just select the desired element and apply the event listener:
$('.k-item > input').on('click', function() { // ... });

jQuery: Element with stopPropagation Going to Its Link

I'm using stopPropagation to make a parent menu item that links to /# to show a dropdown child menu when clicked. It does show the child menu when clicked, but it first goes to url/# before showing the child menu. I'd like it to ignore its link and just show the dropdown menu. My code is below:
$(document).on('click', '#navpanel .mainnav a[href^="/#"]', function(e){
if($(this).parent('li').hasClass('expanded')) {
$(this).siblings('ul').css('display', 'block').slideDown('linear', function(){
$(this).parent('li').toggleClass('expanded');
});
} else {
$(this).siblings('ul').css('display', 'none').slideUp('linear', function(){
$(this).parent('li').toggleClass('expanded');
});
}
var objHeight = 0;
$.each($('ul.tier1').children(), function(){
objHeight += $(this).height();
});
$('ul.tier1').height(objHeight);
e.stopPropagation();
});
If i understood you right you need not stopPropagation but prevent default. Add this to your link click event. It will disable default action, which in your case is redirect.
e.preventDefault();
stopPropagation just prevents your event from bubling in the DOM tree

Styled Select Fields with jquery and HTML Listelements

i have a little problem with my styled Selectfield. I used for this unordered list elemnts (UL / LI) and a H3.
The problem is to close the "Selectfield" by clicking anywhere on the page.
When i bind a click event to the "document", then don't open the SelectField with the current jQuery code.
I have hidden the UL Element by using CSS (display:none).
To open the Select Fields is not the problem. But only without the $(document).bind('click') [...] code.
I hope anyone have a resolution for my.
Thanks.
And here my HTML Code:
<div class="select_container">
<h3 class="reset">Select Items</h3>
<ul class="select_elements">
<li>Select Item 01</li>
<li>Select Item 02</li>
<li>Select Item 03</li>
</ul>
</div>
And here the jQuery Code:
$(document).ready(function(){
var selectFields = {
init: function(){
$('.select_container').on('click',function(){
$(this).find('ul.select_elements').toggle();
$(this).find('ul.select_elements').toggleClass('active');
});
$(document).bind('click',function(){
if( $('.select_elements').is(':visible')){
$('.select_elements.active').hide();
}
else if( $('.select_elements').is(':hidden')){
console.log('visible false ...');
}
});
}
};
$(selectFields.init);
});
You need to use .stopPropagation in $('.select_container').on('click') function to prevent triggiring $(document).on('click')
You need to use toggleClass in $(document).on('click') too
$('.select_container').on('click',function(e){
$(this).find('ul.select_elements').toggle();
$(this).find('ul.select_elements').toggleClass('active');
e.stopPropagation();
});
$(document).on('click',function(){
if( $('.select_elements').is(':visible')){
$('.active').hide();
$('.select_elements').toggleClass('active');
}
else {
console.log('visible false ...');
}
});
FIDDLE
In jquery and javascript an event bubbles up so you have to use e.stopPropagation() on your container click.
check theese pages linki1 or link2 and a possible solution to your problem could be
<script type="text/javascript">
$(document).ready(function(){
var selectFields = {
init: function(){
$(document).bind('click',function(e){
if( !$('ul').hasClass('active')){
$('ul').hide()
$(this).find('ul.select_elements').toggleClass('active');
}
});
$('.select_container').on('click',function(e){
e.stopPropagation()
if( $('ul').hasClass('active')){
$('ul').show()
}else{ $('ul').hide() }
$(this).find('ul.select_elements').toggleClass('active');
});
}
};
$(selectFields.init);
})
</script>
With stopPropagation prevent the event from bubbling and being caught by the document when you click on the list
in some cases you can also use stopImmediatePropagation, for understand differences between stopPropagation and stopImmediatePropagation check this post Post
The only drawback to similar code and to and Batu Zet code, is that If you want the items in the list can be clicked without disappearing, you have to add another stopPropagation on ul tag
Tis is the final Fiddle

How to simulate editable click on content editable element

Here is my html code
<ul class="options-list">
<li contenteditable="true">Customer List</li>
<li contenteditable="true">Product List</li>
</ul>
When user click on first li, content becomes editable, same happens on second div. Now requirement is, while editing on first li, if user presses enter key, I need to stop editing first li and move to second li and auto initiate edit mode.
Here is my JS code
$('.options-list').on('keypress', 'li', function (e) {
if (e.keyCode === 13) {
$(e.currentTarget).blur(); //this works
$(e.currentTarget).siblings('li').click(); // this doesn't work
return false;
}
})
Any help would be appreciated
Instead of .click(), you can use .focus().
For example:
$('.options-list').on('keypress', 'li', function (e) {
if (e.keyCode === 13) {
$(e.currentTarget).blur();
$(e.currentTarget).siblings('li').focus();
return false;
}
})
A jsfiddle demo is here.
Change $(e.currentTarget).siblings('li').click(); to $(e.currentTarget).next('li').focus();
Instead of using .siblings('li').click();
you can use .next('li').focus();
This would help you to move the focus to next li element,
also .siblings('li') would move it last li element of the list,
but .next() would move the focus to next li element consecutively.
Try this jsfiddle demo example
Thanks.

Categories