What is wrong with this code, trying a click menu? - javascript

So there is a left side vertical menu. And it has a small options button. When clicked, it should open a div which will have various filter options. Now, i need it to appear when clicked, and disappear when either the options button is clicked again, or the user clicks anywhere outside the div.
So i have the following code.
//options filter menu animation
$('#optionsmenu').hide(); //hides the menu
$('.optionsfilters').click(function(e){
var $this = $('#optionsmenu');
$this.show();
var left = $('#sidebar').css('width'),
top = $(this).offset().top;
$this.css('top', top);
$this.css('left', left);
});
$(':not(.optionsfilters)').click(function(e){
$('#optionsmenu').hide();
});
The HTML is
<div id="sidebartitle">
<h2>Organisation</h2>
<a id="optionsfilters" class="optionsfilters">Options</a>
</div>
<div id="optionsmenu" class="optionsfilters">
<h3>Add New</h3>
<ul>
<label>Year</label>
<select>
<option>2000</option>
<option>2001</option>
<option>2002</option>
<option>2003</option>
<option>2004</option>
<option>2005</option>
</select>
</ul>
</div>
Its not working together, i.e. the two javascript functions, the first one works alone, when the second one is commented out. The second one works, if i comment out the hide part, and add an alert message. But together, they don't work.
Whats the conflict?

Ok there are a few things you will want to do:
1) If you want the original button to close the menu you will want to use .toggle() rather than .show()
2) You will want to detect a click on the document, to hide the options menu. Which will not be called if it is the options menu that is clicked due to the e.stopPropagation(); (point 4 below).
$(document).click(function() {
$('#optionsmenu').hide();
});
3) You also want to check (as both have the same class) that the .optionsfilters that was clicked was not the filters themselves (otherwise this will stop you clicking an option).
if( e.target !== this ) {
return;
}
4) Use e.stopPropagation(); to stop the event bubbling up to the parents (or document).
This should be what you are looking for:
$('#optionsmenu').hide(); //hides the menu
$('.optionsfilters').click(function(e){
e.stopPropagation();
if( e.target !== this ) {
return;
}
var $this = $('#optionsmenu');
$this.toggle();
var left = $('#sidebar').css('width'),
top = $(this).offset().top;
$this.css('top', top);
$this.css('left', left);
});
$(document).click(function() {
$('#optionsmenu').hide();
});
Here is the working fiddle: http://jsfiddle.net/lee_gladding/pny4vq26/

Here you go
//options filter menu animation
var filters = $('.optionsfilters');
var options = $('#optionsmenu');
options.hide(); //hides the menu
filters.click(function(e){
$('#optionsmenu').toggle();
var left = $('#sidebar').css('width'),
top = $(this).offset().top;
_this.css('top', top);
_this.css('left', left);
});
$(document).click(function(e) {
if (!filters.is(e.target) && filters.has(e.target).length === 0) {
options.hide();
}
});
http://jsfiddle.net/6e86hdwc/

a classic demonstration of stopPropagation in jQuery (http://api.jquery.com/event.stoppropagation/)
here is a fiddle that simplify this: http://jsfiddle.net/ymzrocks/98082xk7/1/
in short:
$('.optionsfilters').click(function(e)
{
e.stopPropagation(); // or elese it will fire the parent event
var $this = $('#optionsmenu');
$this.show();
var left = $('#sidebar').css('width'),
top = $(this).offset().top;
$this.css('top', top);
$this.css('left', left);
});

The problem is mainly that both your click handlers run and one shows the menu then the other one hides it.
Why? Because that's not a good selector. Until you reach the element with the class .optionsfilters your click goes through body, #sidebartitle and then it reaches the element a. And since the parents of that element don't have the class .optionsfilters, it will hide the menu.
So I changed the code a little. First of all don't use the class as a click handler. Use the IDs
$('#optionsfilters').click(function (e) { // ID of options
var $this = $('#optionsmenu');
$this.toggle(); // toggle show/hide when click on it
var left = $('#sidebar').css('width'),
top = $(this).offset().top;
$this.css('top', top);
$this.css('left', left);
});
The you need to check when you click outside of the #optionsmenu. For that you attach a click handler on document and check the e.target
$(document).click(function (e) {
if (!$(e.target).closest('.optionsfilters').length)
$('#optionsmenu').hide();
});
If the e.target itself is not .optionsfilters and is not a child of a parent with that class then you hide the menu.
Working example below.
//options filter menu animation
$('#optionsmenu').hide(); //hides the menu
$('#optionsfilters').click(function (e) {
var $this = $('#optionsmenu');
$this.toggle();
var left = $('#sidebar').css('width'),
top = $(this).offset().top;
$this.css('top', top);
$this.css('left', left);
});
$(document).click(function (e) {
if (!$(e.target).closest('.optionsfilters').length) $('#optionsmenu').hide();
});
#optionsmenu{
background:lightblue;
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="sidebartitle">
<h2>Organisation</h2>
<a id="optionsfilters" class="optionsfilters">Options</a>
</div>
<div id="optionsmenu" class="optionsfilters">
<h3>Add New</h3>
<ul>
<label>Year</label>
<select>
<option>2000</option>
<option>2001</option>
<option>2002</option>
<option>2003</option>
<option>2004</option>
<option>2005</option>
</select>
</ul>
</div>

Be careful using :not for any other elements, because if - for example - you click the dropdown, the sidebar hides again, which I doubt you want to happen.
It'd be better to define areas you want to make the sidebar hide when clicked, like the main content area.
Also since you use the class .optionsfilters on your sidebar menu, when you click in there the sidebar will hide again.
Try this
JS Fiddle.

I can't understand, but if your menu is hide (first instruction in your js), how can you click on it for show it?
EDIT: Didn't noticed the class attriute on previous div. My fault.

Related

Show hide bubble div jquery click function

I have one question about my script.
I have created this DEMO from codepen.io
I'm trying to make a bubble pop-up clicked on the link. My onclick function is working now.
My question is, if you click my DEMO page then you see there are two image and when you hover over that image then you see black color div.
So if you click this div then you see .bubble will open but if you mouse live on this div bubble will still stay open. Ok it should be stay opening but the black div automatically getting display:none => I don't want it (How can i do this.)
Also if you click right side black color div then you see left .bubble still stay open so i want when i click other black div then i want other bubble will automatically hide.
Anyone can help me in this regard ?
This is my jquery function :
$(document).ready(function() {
$('.nav-toggle').click(function(){
var collapse_content_selector = $(this).attr('href');
var toggle_switch = $(this);
$(collapse_content_selector).toggle(function(){
if($(this).css('display')=='none'){
toggle_switch.html('x');
}else{
toggle_switch.html('x');
}
});
});
});
You could just modify this piece of css :
.imgar:hover .delete, .imgar.selected .delete{
display: block;
}
Notice, I added the class selected so when you do the js event click add the class event to imgar like so :
$('.imgar').addClass('selected');
And don't forget to remove the class when he click back to the element :
$('.imgar').removeClass('selected');
EDIT
JS
$(document).ready(function() {
$('.nav-toggle').click(function(){
var collapse_content_selector = $(this).attr('href');
var toggle_switch = $(this);
$('.imgar').removeClass('selected'); // Remove the X before openning a second
if($(collapse_content_selector).css('display')=='none'){
$('.bubble').hide();
}
$(collapse_content_selector).toggle(function(){
if($(this).css('display')=='none'){
toggle_switch.parent().parent().removeClass('selected');
toggle_switch.html('x');
}else{
toggle_switch.parent().parent().addClass('selected');
toggle_switch.html('x');
}
});
});
});
CSS
.imgar:hover .delete, .imgar.selected .delete{
display: block;
}
Codepen
http://codepen.io/SebastienBeaulieu/pen/RNPzzL

On mouseup get target of div below element

Say I have some markup like this:
<div class="something1">
Content 1
</div>
<div class="something2">
Content 2
</div>
<div class="drag">
Draggable div
</div>
Now, I've written some jQuery to allow the .drag div to be dragged. At the end of the drag I do something like this:
$(document).on('mouseup',function(e){
console.log(e.target);
});
When I drag the div over .something1, the answer to e.target I would like is .something1. Instead, because .drag is being dragged under the mouse, when the mouseup function executes, the target is still the .drag div.
How do I see what div the mouse is over during the mouseup, ignoring the div being dragged? Equally, how do I use this method to see what div is being hovered over whilst the dragging is happening?
(If it helps to know, I'm trying to build drag and drop functionality)
You cannot fire a mouseup event because .drag isn't a child node of something1 or something2, then, always you will get e.target = .drag
But you have another options
If you write your own code:
I added an id attribute to each div for search reasons. (see js below)
<div class="something1" id="something">
Content 1
</div>
<div class="something2" id="something">
Content 2
</div>
<div class="drag">
Drag me
</div>
To know which div you are, is necessary to know the mouse position and the div's area. See the next
function getHoverElement(x,y){
element = "none";
$('div#something').each(function(i){
el = this;
el_left = $(el).offset().left;
el_right= $(el).offset().left + $(el).width();
el_top = $(el).offset().top;
el_bottom = $(el).offset().top + $(el).height();
if (x >= el_left && x <= el_right) {
if (y >= el_top && y <= el_bottom) {
element = $(el).attr('class');
return false;
}
}
});
return element;
}
x and y are passed from mouseup event. See the working example
Obviously, this solution is based on mouse position only and isn't considered the margins of draggable element. So, if you need to refine the code you need to look at the drag element borders.
Another solution is to use draggable/droppable methods from jquery-ui that cover this issue.
$(".something1, .something2").droppable({
drop: function(event, ui) {
console.log($(this).attr('id'));
}
});
See the working example

Bootstrap 3 Nav Tabs on Top and Bottom of Page?

I'm building a site in Bootstrap 3 and have figured out that you can indeed place both a top nav-tab and bottom nav-tab section on the same page. These two separate tab menus will trigger the same tab content areas to show/hide.
Doing this works just fine with one problem. The tabs work independently of one another. I need the top and bottom tabs to show the same active tab. Right now if you click tab 4 on the top tab menu, it will take you to tab 4 but the bottom menu still shows the active tab as tab 1.
So, can Javascript/Jquery handle this issue? Just need them to act as the same menu.
Thanks in advance for any help.
<div class="tabbable tabs-below">
Should match top nav tabs.
http://jsfiddle.net/UT6ex/1/
Instead of listening to raw clicks, listen to the events triggered by the Bootstrap Tab class: show.bs.tab and shown.bs.tab. That will ensure future versions of Bootstrap markup won't break your setup.
This code finds <li> elements after a shown event to add and remove classes (working JSFiddle):
$('a[data-toggle="tab"]').on('shown.bs.tab',
function(event) {
var $relatedTarget, $target;
if (event.relatedTarget != null) {
$relatedTarget = $(event.relatedTarget);
$('a[data-toggle="' +
$relatedTarget.attr('data-toggle') +
'"][href="' +
$relatedTarget.attr('href') +
'"]').parent('li').removeClass('active');
}
if (event.target != null) {
$target = $(event.target);
$('a[data-toggle="' +
$target.attr('data-toggle') +
'"][href="' +
$target.attr('href') +
'"]').parent('li').addClass('active');
}
}
);
Sth like this is ok i suppose:
$('.nav-tabs').find('li').on('click', function(){
var location = $(this).find('a').attr('href'),
children = $('.nav-tabs').find('li'),
links = children.find('a');
links.each(function() {
var mi = $(this),
miHrefs = mi.attr("href"),
miParents = mi.closest('li');
miParents.removeClass('active');
if(miHrefs == location)
{
miParents.addClass("active");
}
});
})
Ok this works fine. Have a look here http://jsfiddle.net/UT6ex/4/.

jQuery - have different events if element is on the same row

I have a page with a row of boxes that are responsive........
so the smaller you resize the window the amount of boxes on each row lessens
heres a fiddle to show you whats going on
http://jsfiddle.net/abtPH/6/
Right now the behavior is......if you click on a box then a div appears under it.....if you click on the next box the div slides up a bit then slides down revealing the new content...
I want it so that if the box is on the same row and the user clicks the next one it does not slide up then down but fades the content in
I only want it to slide up when the box is on a different row...like underneath
heres my jquery so far
$('li').on('click', function(e){
$(this).siblings('.active').toggleClass('active', 400).find('.outer').slideToggle();
$(this).find('.outer').slideToggle();
$(this).toggleClass('active', 400);
});
The trick is detecting what is on the same line. For that I think the position() function is what you need. When a list item is clicked, check to see if there is an active one already, if so, check to see if the current and active items have the same top value. If they do crossfade otherwise toggle.
$('li').on('click', function(e){
var active = $(this).siblings('.active');
var posTop = ($(this).position()).top;
if (active.length > 0) {
var activeTop = (active.position()).top;
if (activeTop == posTop) {
active.toggleClass('active', 400).find('.outer').fadeOut('slow');
$(this).find('.outer').fadeIn('slow');
} else {
$(this).siblings('.active').toggleClass('active', 400).find('.outer').slideToggle();
$(this).find('.outer').slideToggle();
}
} else {
$(this).find('.outer').slideToggle();
}
$(this).toggleClass('active', 400);
});
jsFiddle

Sub-menu navigation toggle bug

I have a main navigation menu with a sub-menu that appears on hover, the problem I have is that on hovering on and off the menu sub-menu flickers between the slide and fade states provided by its function (menuHover) - I have a fiddle which is viewable here
The function itself is:
///<summary>
///drop down menu navigation
///</summary>
var menuHover = {
//initialise our function
init: function(){
var menuItem = $(".navItem");
//each menu item
menuItem.each(function(){
//checks to see if we have sub-navigation items
var $this = $(this),
hasSub = $this.children(".subNav"),
isSub = hasSub.length > 0;
//toggle visibility on sub items when hovered
if(isSub){
$this.hover(
//on hover
function(){
hasSub.slideDown("fast");
},
// off hover
function(){
hasSub.fadeOut(350);
});
}
});
}
};
Any help would be gratefully appreciated!
Stop using JS for menus! Use CSS instead!
The basics: http://www.seoconsultants.com/css/menus/tutorial/
Example I made(Copyrighted, do not just copy it): http://tinkerbin.com/W0iL32hh

Categories