React - dropdown menu hover closes too fast - javascript

I have this dropdown menu and it has a gap between parent and child selector. which is causing it to close fast.
Fiddle
render() {
return (
<div class="dropdown-wrapper">
<div class="image">Image</div>
<ul class="dropdown-container">
<li class="dropdown-list">Nothing</li>
<li class="dropdown-list">Help</li>
<li class="dropdown-list">Settings</li>
<li class="dropdown-list">Logout</li>
</ul>
</div>
);
}
I tried few things.
using react onMoverOver and onMouseOut, which results in same behaviour
Changing css
Tried using jquery
How can I solve this problem. Any indication what i am doing wrong?

margin-top: 0; on .dropdown-container -- Because you have a margin on the .dropdown-container div, as soon as you move off the .image div you are no longer hovering over it... so the dropdown closes.
Fiddle update
If you want space.. add it to the .image class...
.dropdown-wrapper > .image { padding-bottom: 15px; }
Fiddle Update

Related

Position sub-menu item relative to main menu item, but in an outside div

I'm trying to change the sub-menu behavior of a site. The original sub-menu appears as a drop-down, and instead I'd like it to appear in a separate full horizontal div.
So far I've done this:
jQuery(document).ready(function( $ ){
$(".header").append("<div class='subber'><div class='sub-menu'></div></div>");
$(".main-navigation ul li.menu-item-has-children").mouseover( function() {
var a = $(this).find(".sub-menu").html();
$(".subber .sub-menu").html(a);
});
});
... with some css, and it works well. the original sub-menu HTML is copied to the subber sub-menu.
I'd like each subber sub-menu to be positioned relatively to the original menu item, even though they occur in separate areas of the HTML. Can I somehow bind the two?
My HTML code:
<div class="header">
<div id="navigation">
<div class="site-navigation">
<nav class="main-navigation">
<ul class="menu-main-menu">
<li class="menu-item">
some text
</li>
<li class="menu-item menu-item-has-children">
some text
<ul class="sub-menu">
<li class="menu=item">
sub item text
</li>
</ul>
</li>
<li class="menu-item">
some text
</li>
</ul>
</nav>
</div>
</div>
<div class="subber">
<div class="sub-menu"></div>
</div>
</div>
Since there's no actual parent-child relationship in the HTML structure, there's no CSS-way of positioning your new sub-menu relative to a top-level menu item.
Instead, you'll have to manually position the new sub-menu with JS, using the coordinates of the original menu item.
Keep in mind this basic positioning won't create a "stickyness" between the two, so if your main menu moves (e.g. a sliding menu bar with up/down toggle states), you'll have to trigger an update to the sub-menu positioning using a listener and function.
Codepen
$("#menuItem1").mouseover( function() {
/* get original menu */
var origMenu = $(this);
/* grab content out of original sub-menu */
var myContent = origMenu.find(".sub-menu").html();
/* copy content over to new sub-menu outside of navigation */
$(".subber .sub-menu").html(myContent);
/* get the coordinates of the original menu item */
var subberLeftOffset = origMenu.offset().left;
var subberTopOffset = origMenu.offset().top + origMenu.innerHeight(true);
/* re-position the new sub-menu so it appears below the original menu */
$(".subber").offset({top: subberTopOffset, left: subberLeftOffset});;
});
#origNavigation .sub-menu {
visibility: hidden;
height: 0px;
}
#menuItem1 {
margin-top: 8em;
margin-left: 8em;
padding: 1em;
width: 200px;
border: 1px solid black;
}
<div id="origNavigation">
<div id="menuItem1">
Hello
<div class="sub-menu">Sub-menu</div>
</div>
</div>
<div class="subber">
<div class="sub-menu"></div>
</div>

How to use css bootstrap list-group with affix to create a sticky menu in a column?

I am trying to create a sticky menu using CSS Bootstrap affix and list-group menu.
I manage to get most of it to work except for when the user scrolls down.
When the user scrolls down, the menu seems to take the entire with of the page.
I tried to set it up via data attributes
using something like this
<div class="container">
<div class="row">
<div class="col-md-3" id="leftCol">
<div data-spy="affix">
<div class="list-group list-group-root well">
<a class="list-group-item" href="#introduction">Introduction</a>
<a class="list-group-item" href="#features">Features</a>
<a class="list-group-item" href="#dependencies">Dependencies</a>
</div>
</div>
</div>
<div class="col-md-9" id="mainCol">
Some long text for the body along with some tables.
</div>
</div>
</div>
But the data attribute did not make the menu stick! it just kept it on the top.
So I tried to use JS to get the job done like this
$(function(){
$('#leftCol').affix({
offset: {
top: 100,
bottom: function () {
return (this.bottom = $('.footer').outerHeight(true))
}
}
});
});
I created jsFiddle to show you the current behavior.
How can I fix this affix so when the user scrolls down the menu maintain the same shape?
First of all, you should use either data-attributes or JS.
I updated your jsFiddle. The position of id="leftCol" was changed:
<div class="col-md-3" >
<div id="leftCol">
...
</div>
</div>
and style was added:
#leftCol {
width: 220px;
}
Also, you should add media queries to remove affix from mobile view.
As an "unacceptable" workaround, I set a max width of the menu to 250px like so
.list-group.list-group-root {
padding: 0;
max-width: 250px;
}
I am not sure how to get it to work without adding a max-with the max with should be defined by the parent. In this case class="col-md-3"
UPDATED
javascript to the rescue!
I added the following JS code to solve this problem once an for all.
It basically resize the menu everytime affix.bs.affix event is fired
$(document).on('affix.bs.affix', '#docs-menu', function() {
$(this).width($(this).width());
});
From the docs
affix.bs.affix => This event fires immediately before the element has
been affixed.
Ok I believe I got most of the code working like you want it to. The main changes I made were adding this CSS:
#leftCol {
display: block;
height: auto;
padding: 0;
width: 100%;
}
.navbar-fixed-top-again {
position: static;
top: 60px;
z-index:1031;
}
.navbar-inner {
background: red;
padding: 5px;
}
.affix {
position: fixed !important;
}
and I changed up some of the structure on your HTML:
<div class="container body-content">
<div>made up content to allow the navigation to scroll more before it becomes sticky. This height will need to be set in the data-offset-top which is in the leftCol DIV just below this content. The same will apply if you need to set it for a footer offset.</div>
<!-- new nav section -->
<div class="col-md-3 navbar-fixed-top-again" id="leftCol" data-spy="affix" data-offset-top="80">
<div class="navbar-inner">
<div class="list-group list-group-root well">
*the rest of your code*
</div>
</div>
</div>
</div>
The main problem now is having a sticky navigation menu with variable height. If you notice when you scroll your reading content underneath jumps up and gets hidden. It seems that it is possible to fix this using JavaScript (link to SO question).
Heres the link to your updated Fiddle. Hope that helps.

Looking for a dropup directive for Angular.js

I would like to implement a dropup menu (menu that opens above the button) in Angular.js that would behave similarly to the ".dropup" class in Boostrap.
Is there a directive that does this or simple instructions to create one?
If you're using a dropdown directive that actually uses Bootstrap (like the UI Bootstrap Dropdown directive), there's no reason you can't apply the .dropup class itself to that dropdown and have it work as expected.
<div class="btn-group dropup" dropdown> <!-- note the dropup class -->
<button type="button" class="btn btn-primary dropdown-toggle" ng-disabled="disabled">
Button dropup <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>Stuff</li>
...
</ul>
</div>
Here's a plunker to demonstrate: http://plnkr.co/edit/pzoRuVOjHHaBLryCv7RA
If you're talking about a navigation bar-type thing, rather than a <select> element, I'd go with the following CSS:
.nav ul li {
position: relative;
}
.nav ul ul {
display: none;
postion: absolute;
bottom: 100%;
width: 100%;
}
Adding in your own CCS flavorings and supplement that with jQuery animation:
$('.nav ul li').hover(function() {
$(this).children('ul').stop().slideDown();
}, function() {
$(this).children('ul').stop().slideUp();
});
The stop() prevents the animations from stacking up in an obnoxious queue. Despite the naming, slideDown() will open the submenu upwards and slideUp() will close it downwards because you've affixed the bottom of the element with your CSS.

creating navigation bar with jquery

I am trying to create a navigation bar following is my code:
html:
This is Navigation baar
<div class="cat-set">
<div class="icon-wrap">
<div class="icons active" id="mobiles"><div class="bgimg mobiles"></div></div>
<div class="icons" id="laptops"><div class="bgimg laptops"></div></div>
</div>
</div>
on hover of each '.icons' class a division will be shown, so there are two boxes to show and hide, this is the code for this:
<div class="cat-demo" id="mobiles">
<p>This is for mobiles, if mouse is on .mobiles then this will be shown</p>
</div>
<div class="cat-demo" id="tablets">
<p>This is for tablets, if mouse is on .mobiles then this will be shown</p>
</div>
this is Jquery code for this:
$('.icons').hover(function(){
$('.icons').each(function(){$(this).removeClass("active");});
$(this).addClass("active");
var position = $(this).position();
$('.cat-demo').css({'left':(position.left-4)+'px'});
var showThis=$(this).attr("id")
$(".cat-demo:visible").hide()
$("'#"+showThis+".cat-demo'").show();
});
So till here everything is working fine, but problem is I want to hide the '.cat-demo'
if mouse pointer is out of out of '.icons' and if pointer is on .cat-demo then it should not hide this. please help me... If you want to change the html layout please go ahead.
this is the fiddle link for this http://jsfiddle.net/ndevJ/
Is it so necessary to use js for such types of menus?
If your menu has simple behavior, then use only CSS for show/hide menu's sub items.
For example:
<ul class="cat-set">
<li>
mobile
<p>
This is for mobiles, if mouse is on .mobiles then this will be shown
</p>
</li>
<li>
laptops
<p>
his is for tablets, if mouse is on .mobiles then this will be shown
</p>
</li>
</ul>
And CSS:
ul.cat-set > li {display: inline-block; margin: 10px;}
ul.cat-set > li p {display: none; position: absolute;}
ul.cat-set > li:hover p {display: block;}

How to increase the height of my dropdown?

I have a dropdown in HTML. When I hover on it, it expands. I added a new entry in the dropdown, and when I hover on it, I want my new entry visible completely (I added Comp3 in dropdown. I can see the upper part of it, but not completely Comp3). I tried various things like giving height to divs, increasing the height of the component in css, but nothing helped. Viewing the source code of that in the browser, this is the small code snippet of that particular dropdown:
<div class="optionsDropDown">
<p class="optionsDropDown collapseTrigger" id="userMenu">
Hello<em> User </em><span class="closed"></span>
</p>
<ul class="optionsDropDown collapseContent closed" name="userMenu">
<li>
<a class="optionsDropDown" href="javascript:showHelp();">
<span id="0">Comp1</span>
</a>
</li>
<li>
<a class="optionsDropDown" href="myAction.do?actionCode=3&page=controlPanel" target="view">
<span id="1">Comp3</span>
</a>
</li>
</ul>
</div>
Below is the javascript function that expands the dropdown:
$.fn.openMenu = function(menuContent){
$(menuContent).slideDown(200,function() {
$(menuContent).children().fadeTo('fast',1);
});
$('span', this).removeClass('closed');
};
And here is the dropdown class:
div.optionsDropDown {
float: right;
font-size: 11px;
height: 25px;
margin: 12px 32px 0 0;
position: absolute;
top: 0px;
right: 10px;
width: 120px;
z-index: 10000;
}
Please let me know if somehow height can be increased. Thanks in advance.
I believe your <div> and <ul> heights needs to be set to auto and the heights of each <li> needs to be adjusted.
Often times CSS becomes the practice of hit or miss when dealing with issues like these. First set everything to auto then systematically experiment with every permutation.
Good luck!

Categories

Resources