Manipulate Bootstrap navbar elements using jquery - javascript

What I'm trying to do is to hide <li> elements from navbar to a dropdown menu on resize.
I tried and I've ended with this buggy menu. http://i.imgur.com/1uJ7hbG.gif
Here is the js:
$().ready(function () {
//we reconstruct menu on window.resize
$(window).on("resize", function (e) {
var parentWidth = $("#normal").parent().width() - 40;
var ulWidth = $(".menutohide").outerWidth();
var menuLi = $("#normal > li");
var liForMoving = new Array();
//take all elements that can't fit parent width to array
menuLi.each(function () {
ulWidth += $(this).outerWidth();
if (ulWidth > parentWidth) {
console.log(ulWidth);
liForMoving.push($(this));
}
});
if (liForMoving.length > 0) { //if have any in array -> move em to "more" ul
e.preventDefault();
liForMoving.forEach(function (item) {
item.clone().appendTo(".links-hidden");
item.remove();
});
}
else if (ulWidth < parentWidth) { //check if we can put some 'li' back to menu
liForMoving = new Array();
var moved = $(".links-hidden > li");
for (var i = moved.length - 1; i >= 0; i--) { //reverse order
var tmpLi = $(moved[i]).clone();
tmpLi.appendTo($("#normal"));
ulWidth += $(moved[i]).outerWidth();
if (ulWidth < parentWidth) {
$(moved[i]).remove();
}
else {
ulWidth -= $(moved[i]).outerWidth();
tmpLi.remove();
}
}
}
if ($(".links-hidden > li").length > 0) { //if we have elements in extended menu - show it
$(".menutohide").show();
}
else {
$(".menutohide").hide();
}
});
$(window).trigger("resize"); //call resize handler to build menu right
});
And here is the html:
<nav class="navbar navbar-default" role="navigation">
<ul class="nav navbar-nav" id="normal">
<li>Home</li>
<li>News</li>
<li>Download</li>
<li>Twitch Live</li>
<li class="disabled">Ranking</li>
</ul>
<ul class="nav navbar-nav menutohide">
<li class="dropdown hidden-dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="true">
<i class="fa fa-bars fa-fw"></i>
</a>
<ul class="dropdown-menu links-hidden" role="menu">
<!--Hidden links here-->
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
<h6 class="hidden-xs">Bambini</h6>
<img src="http://placehold.it/250x250/000000"/>
<span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li>Account info</li>
<li>Logoff</li>
</ul>
</li>
</ul>
</nav>

I think you can accomplish this with a CSS #media query. Just give whatever you want to hide some sort of id, and then you can use display: none to hide it.
#media (max-width: 767px) {
#contact-nav-link {
display: none;
}
}
Here's a JSFiddle - the <li> element that says 'Contact' will display in the navbar, but when the window is resized (and the navbar collapses), it disappears from the dropdown list.

Related

Jquery, can't update attribute previously created

I'm just trying to work on new slider menu but I've a problem with Jquery.
I've a link. When I click on I use .css('left', -230) and all is okay but when i want to reverse by another clicked link like .css('left', 0) nothing happen.
I show you some code :
// The open part "target.width()" = 230
$('.nav-item').on('click', function () {
if( 0 < $(this).find('.navbar-nav__sub').length ) {
var target = $('.navbar-nav');
target.css('left', -target.width());
}
});
// The close part
$('.navbar-nav__sub .go-back').on('click', function () {
console.log('HERE');
var target = $('.navbar-nav');
console.log(target);
console.log(target.css('left'));
target.css('left', 0);
console.log(target.css('left'));
console.log('END');
});
A strange thing in this problem is that I've this in my console :
HERE
Object { 0: ul.navbar-nav.flex-column, length: 1, prevObject: […] }
-230px
0px
END
It seem that the code work well but in my page the left attribute is always to -230px.
Someone have an idea ?
Thank you.
PS: As asked the JSfiddle who reproduce my problem
https://jsfiddle.net/w7Lknsxg/
If you click on "Menu01" Color turn to red and when you click on "<=" in submenu you have the execution in the console but the color don't change.
You can see the class navbar-nav get new class "toto" but don't lost when I try to remove it in the second case.
Because the .go-back is nested within the .nav-item you are firing both event listeners due to event bubbling. You can stop this with event.stopPropagation(); from within the listener placed on the child item. (or be more specific in what you target as not to include subelements)
var ftl = window.ftl || {};
ftl.navbar = {
config: {
targetName: '.nav',
target: null,
},
init: function init() {
this.config.target = $(this.config.targetName);
$('.navbar-toggle').on('click', function () { ftl.navbar.toggle(); });
$('.nav-item').on('click', function () {
if( !ftl.navbar.config.target.hasClass('open') ) {
ftl.navbar.open();
}
// test la présence d'un sous menu
if( 0 < $(this).find('.navbar-nav__sub').length ) {
var target = $('.navbar-nav');
target.addClass('toto');
target.css('color', 'red');
}
});
$('.navbar-nav__sub .go-back').on('click', function (event) {
event.stopPropagation();
console.log('HERE');
var target = $('.navbar-nav');
console.log(target);
console.log(target.hasClass('toto'));
target.removeClass('toto');
target.css('color', "green");
console.log('END');
})
},
open: function open() {
this.config.target.addClass('open').one('transitionend', function () {
ftl.navbar.config.target.addClass('opened');
});
},
close: function close() {
this.config.target.removeClass('opened')
.removeClass('open');
},
toggle: function toggle() {
if( this.config.target.hasClass('open') ) {
this.close();
} else {
this.open();
}
}
}
$(document).ready(function() {
ftl.navbar.init();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav class="nav">
<nav class="navbar" role="navigation">
<div class="container-nav flex-column">
<div class="navbar__header">
<a href="#" class="no-style">
<i class="fa fa-comment-o fa-2x navbar__icon" aria-hidden="true"></i>
<span class="navbar__text"><strong class="text-primary">web</strong>tutu</span>
</a>
</div>
<div class="navbar__divider"></div>
<ul class="navbar-nav flex-column">
<li id="nav-item--one" class="nav-item">
<a href="#nav-item--one">
<i class="fa fa-user-circle-o navbar__icon" aria-hidden="true"></i>
<span class="navbar__text">Menu01</span>
</a>
<ul class="navbar-nav__sub">
<li>link 01</li>
<li>link 02</li>
<li><a class="go-back" href="#"> <= </a></li>
</ul>
</li>
<li id="nav-item--two" class="nav-item">
<a href="#nav-item--two">
<i class="fa fa-user-circle-o navbar__icon" aria-hidden="true"></i>
<span class="navbar__text">Menu02</span>
</a>
</li>
<li id="nav-item--three" class="nav-item">
<a href="#nav-item--three">
<i class="fa fa-user-circle-o navbar__icon" aria-hidden="true"></i>
<span class="navbar__text">Menu03</span>
</a>
</li>
<li class="mt-auto">
<i class="fa fa-angle-double-right fa-2x navbar-toggle" aria-hidden="true"></i>
</li>
</ul>
</div>
</nav>
</nav>

Change bootstrap nav element position on scroll (relative to page top)

I have a problem with changing the position of an element using margin-top property.Element is inside bootstrap navigation end the problem is that it changes the margin on scroll properly,but whan I scroll page back to top,it doesnt change margin-top back to hire value.Here is my code:
JS
$(".flags").css("margin-top", "24px");
$(window).scroll(function(){
var scrollingDiv = $(".flags").offset().top - $(window).scrollTop();
var menuMmainScroll = $(".navbar-nav>li>a").offset().top - $(window).scrollTop();
if(menuMmainScroll === 68) {
$(".flags").css("margin-top", "24px");
}
else /**if(menuMmainScroll < 10)**/ {
$(".flags").css("margin-top", "10px");
}
console.log(menuMmainScroll);
});
<div class="menu_main">
<div class="navbar yamm navbar-default">
<div class="navbar-header">
<div class="navbar-toggle .navbar-collapse .pull-right " data-toggle="collapse" data-target="#navbar-collapse-1" > <span>Menu</span>
<button type="button" > <i class="fa fa-bars"></i></button>
</div>
</div>
<div id="navbar-collapse-1" class="navbar-collapse collapse pull-right">
<nav>
<ul class="nav navbar-nav">
<li class="dropdown">Home
<ul class="dropdown-menu" role="menu">
<li>Forside</li>
<li class="active">Ny til Yoga</li>
<li><a href="#holdplan" data-scroll>Holdplan</a></li>
<li><a href="#priser" data-scroll>Priser</a></li>
<li><a href="#kontakt" data-scroll>Kontakt</a></li>
<li>Butik</li>
<li>Medlem log ind</li>
</ul>
</li>
<li>Holdplan</li>
<li>Priser</li>
<li>Ny til yoga</li>
<li class="dropdown">Om Yoga
<ul class="dropdown-menu" role="menu">
<li>Mysore metode</li>
<li>Om Astanga yoga</li>
<li>About</li>
<li>Services</li>
<li>Services</li>
<li>Services</li>
</ul>
</li>
<li>Mysore </li>
<li>Studiet</li>
<li>Butik</li>
<li><div class="dropdown-toggle flags"> !!!!!!!!!!!!!!!!!!!!!!
<a href="#" class="flag-link"><img src="UK_flag.png" alt="English">
</a>
<a href="#" class="flag-link"><img src="DK_flag.png" alt="Danish">
</a>
</div> !!!!!!!!!!!!!!!!!!</li>
</ul>
</nav>
</div>
</div>
I have put ! at the beginning and end of troublesome part in HTML
Basicly in the beggining there is another menu on top of this one(whan page isnt scrolled,but whan the scrolling starts this menu takes over top position and stays fixed at the top.Now the problem is that I am using div with to images inside two links that are not display properly inline,but inline with some 24px above others in its own field,hoping this makes any sence.
thanks for any help guys.
Try editing the code in your scroll function to the below:
var menuMmainScroll = $(window).scrollTop();
if(menuMmainScroll === 0) {
$(".flags").css("margin-top", "24px");
}
else {
$(".flags").css("margin-top", "10px");
}

Perform jQuery action when clicked again

I have the basis of my menu working, where when I click a menu element, it opens (similar to JQuery accordion), and when I click on another element in the menu, the previously opened menu closes and the newly clicked on opens. Here's what it looks like:
Now, I'm trying to implement functionality to close the currently opened menu if it is clicked again. I'm using the slideUp(); method, but having a hard time figuring out where to put the additional code for the 2nd click on the same element.
Here's what I have:
navigation.html.erb
<!-- menu links -->
<div id="sidebar-menu" class="main_menu_side hidden-print main_menu">
<div class="menu_section">
<h3>General</h3>
<ul class="nav side-menu">
<li><a><i class="fa fa-home"></i> Home <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu" style="display: none">
<li>Dashboard
</li>
</ul>
</li>
<li><a><i class="fa fa-edit"></i> Forms <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu" style="display: none">
<li>General Elements
</li>
</ul>
</li>
<li><a><i class="fa fa-bar-chart-o"></i> Data Presentation <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu" style="display: none">
<li>Chart JS
</li>
</ul>
</li>
</ul>
</div>
</div>
custom.js
var URL = window.location,
$BODY = $('body'),
$MENU_TOGGLE = $('#menu_toggle'),
$SIDEBAR_MENU = $('#sidebar-menu'),
$SIDEBAR_FOOTER = $('.sidebar-footer'),
$LEFT_COL = $('.left_col'),
$RIGHT_COL = $('.right_col'),
$NAV_MENU = $('.nav_menu'),
$FOOTER = $('footer');
var setContentHeight = function () {
// reset height
$RIGHT_COL.css('min-height', $(window).height());
var bodyHeight = $BODY.height(),
leftColHeight = $LEFT_COL.eq(1).height() + $SIDEBAR_FOOTER.height(),
contentHeight = bodyHeight < leftColHeight ? leftColHeight : bodyHeight;
// normalize content
contentHeight -= $NAV_MENU.height() + $FOOTER.height();
$RIGHT_COL.css('min-height', contentHeight);
};
$SIDEBAR_MENU.find('a').on('click', function(ev) {
var $li = $(this).parent();
if ($li.hasClass('.active')) {
$li.removeClass('active');
$('ul:first', $li).slideUp(function(){
setContentHeight();
});
} else {
$li.addClass('active');
$SIDEBAR_MENU.find('.side-menu li').not($li).removeClass('active');
$SIDEBAR_MENU.find('.side-menu li').not($li).find('.child_menu').removeClass('active').slideUp();
$('ul:first', $li).slideDown(function(){
setContentHeight();
});
}
});
Change if ($li.hasClass('.active')) to if ($li.hasClass('active')) and that should resolve the issue. Check this fiddle. I have created an empty setContentHeight function to make it work.

Dropdown submenu selection

My Javascript
var selectmenu = function(index, sub){
$('.main-navigation-menu li:nth-child('+index+')').addclass('active');
}
In my view there are two li tags to select main menu and sub menu; so because of the above JS, it is always selecting a 1st main menu and the 1st sub menu; even when clicking the 2nd sub menu of the 1st main menu... anyone knows how to correct this behavior? Here I wanted to use the 'sub' variable and do something like this:
$('.sub-menu li:nth-child('+index+')').removeClass('active');
$('.sub-menu li:nth-child('+sub+')').addClass('active');
HTML
<ul class="main-navigation-menu ">
#foreach (var menu in mainmenu) {
var sublist = userContext.Menus.Where(m => m.Id == menu.Id);
if (sublist.Count == 0){
<li class="active open">
<a href="#Url.Content(menu.MenuUrl)">
<span class="title"> #menu.Name </span>
<span class="selected"></span>
</a>
</li>
}
else {
<li class="main-menu-selection">
<a href="#menu.MenuUrl">
<span class="title">#menu.Name</span>
<i class="fa fa-chevron-down pull-right"></i>
<span class="selected"></span>
</a>
#if (sublist.Count > 0) {
<ul class="sub-menu">
#foreach (var sub in sublist) {
<li class="sub-menu-selection">
<a href="#Url.Content(sub.MenuUrl)">
<span class="title"> #sub.Name </span>
</a>
</li>
}
</ul>
}
</li>
}
count++;
}
</ul>
Try using stopPropagation:
$('.main-navigation-menu').on('click', '.sub-menu-selection', function(e){
var index;
e.stopPropagation();
$('.min-navigation-menu .active').removeClass('active');
$(e.currentTarget).addClass('active');
});
More info here

Unable to change dynamically updated data-id

I am trying to dynamically change the data-id of anchor #a-flop. The issue is that the data-id is only changed once. I am unable to change the dynamically updated value.
HTML
<ul class="nav navbar-nav navbar-center">
<li class="dropdown">
<a id="a-flip" href="javascript:void(0)" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-file-text m-r-10"></i>
Invoice
<span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li>
<a id="a-flop" data-id="1" href="javascript:void(0)">
<i class="fa fa-user m-r-10"></i>
Badge
</a>
</li>
</ul>
</li>
</ul>
JQUERY
<script>
$(document).ready(function(){
$(document).on('click', '#a-flop', function(){
$this = $(this);
alert($this.data('id'));
if ($this.data('id') == 0) {
$this.attr('data-id', 1);
} else {
$this.attr('data-id', 0);
}
});
});
</script>
FIDDLE LINK - http://jsfiddle.net/Lv37o8wu/
That is because you are setting the attribute value and not dom property. you should be using .data() to set the value as well:
$(document).on('click', '#a-flop', function(){
$this = $(this);
alert($this.data('id'));
if ($this.data('id') == 0) {
$this.data('id', 1);
} else {
$this.data('id', 0);
}
});
Working Demo

Categories

Resources