Adding code to existing .js to collapse navbar when click outside menu - javascript

Currently I use .js for my sticky navbar in Bootstrap 4.1.3 which works as desired. I have tried to insert a function in the script, which makes the navbar bar collapse on mobile phones if you click outside the menu. However, without luck. https://biogenity.com/RC19/index.html
The code I am currently using is:
$(document).ready(function () {
var stickyToggle = function (sticky, stickyWrapper, scrollElement) {
var stickyHeight = sticky.outerHeight();
var stickyTop = stickyWrapper.offset().top;
if (scrollElement.scrollTop() >= stickyTop) {
stickyWrapper.height(stickyHeight);
sticky.addClass("is-sticky");
}
else {
sticky.removeClass("is-sticky");
stickyWrapper.height('auto');
}
};
$('[data-toggle="sticky-onscroll"]').each(function () {
var sticky = $(this);
var stickyWrapper = $('<div>').addClass('sticky-wrapper');
sticky.before(stickyWrapper);
sticky.addClass('sticky');
$(window).on('scroll.sticky-onscroll resize.sticky-onscroll', function () {
stickyToggle(sticky, stickyWrapper, $(this));
});
stickyToggle(sticky, stickyWrapper, $(window));
});
});
I want to be able to implement a similar function as the following. It is not certain that this is the best solution for "collapse when you click outside the menu".
$(document).on('click', function(event){
var $clickedOn = $(event.target),
$collapsableItems = $('.collapse'),
isToggleButton = ($clickedOn.closest('.navbar-toggle').length == 1),
isLink = ($clickedOn.closest('a').length == 1),
isOutsideNavbar = ($clickedOn.parents('.navbar').length == 0);
if( (!isToggleButton && isLink) || isOutsideNavbar ) {
$collapsableItems.each(function(){
$(this).collapse('hide');
});
}
});
Thanks in advance.

Based on your code, try this:
$(document).click(function (event) {
var clickedOn = $(event.target),
isNavbar = clickedOn.hasClass('navbar'),
// Target only nav links not all links
isNavbarLink = clickedOn.closest('.nav-link').length == 1,
navbarCollapse = $('.navbar-collapse'),
isNavbarOpen = navbarCollapse.hasClass('show');
// if its not navbar and navbar is opened
if (!isNavbar && isNavbarOpen) {
// if the user is not cliking on the nav links
if (!isNavbarLink) {
// thes close the navbar
navbarCollapse.collapse('hide');
}
}
});

Related

jQuery Cookies: Remember Sate of Bootstrap Panel Heading

I would like to use jQuery Cookies to retain the state of my Bootstrap accordion. So far, this code is working well, but it only retains the state of the .panel .panel-collapse element.
jQuery(document).ready(function () {
//when a group is shown, save it as the active accordion group
jQuery("#checkout-accordion").on('shown.bs.collapse', function () {
var active = jQuery("#checkout-accordion .in").attr('id');
jQuery.cookie('activeAccordionGroup2', active);
// alert(active);
});
jQuery("#checkout-accordion").on('hidden.bs.collapse', function () {
jQuery.removeCookie('activeAccordionGroup2');
});
var last = jQuery.cookie('activeAccordionGroup2');
if (last != null) {
//remove default collapse settings
jQuery("#checkout-accordion .panel-collapse").removeClass('in');
//show the account_last visible group
jQuery("#" + last).addClass("in");
}
});
I would need another piece of code that sets the cookie for the .panel-heading element. It should remember class collapsed when the accordion panel is collapsed, and remove class collapsed when it's toggled/active.
There's also this code, which works well too, but only for the .panel .panel-collapse element, and not for .panel-heading also.
jQuery(document).ready(function() {
var lastState = localStorage.getItem('lastState');
if (!lastState) {
lastState = [];
localStorage.setItem('lastState', JSON.stringify(lastState));
} else {
lastStateArray = JSON.parse(lastState);
var arrayLength = lastStateArray.length;
for (var i = 0; i < arrayLength; i++) {
var panel = '#'+lastStateArray[i];
$(panel).addClass('in');
}
}
jQuery('#checkout-accordion').on('shown.bs.collapse', '.panel-collapse', function() {
lastState = JSON.parse(localStorage.getItem('lastState'));
if ($.inArray($(this).attr('id'), lastState) == -1) {
lastState.push($(this).attr('id'));
};
localStorage.setItem('lastState', JSON.stringify(lastState));
});
jQuery('#checkout-accordion').on('hidden.bs.collapse', '.panel-collapse', function() {
lastState = JSON.parse(localStorage.getItem('lastState'));
lastState.splice( $.inArray($(this).attr('id'), lastState), 1 );
localStorage.setItem('lastState', JSON.stringify(lastState));
});
});
Any ideas?

Magento Jquery Bootstrap and Prototype conflict? nav-tabs dont work

I use Magento 1.9.2.4 and the following Theme
https://github.com/webcomm/magento-boilerplate
The description of it is "HTML5 Twitter Bootstrap 3.1 Magento Boilerplate Template"
It works fine with everything else of "Bootstrap responsive".
My problem is, that all of the following on this Site did not work on my
Installation:
http://www.w3schools.com/bootstrap/bootstrap_tabs_pills.asp
And "did not work" means you can click on next tab but the border and highlighting and so on is still on the first tab.
Same thing on "nav-pills" of Bootstrap.
In this Boilerplate there is a Workaround for Bootstrap dropdown:
jQuery.noConflict();
;(function ($) {
'use strict';
function Site(settings) {
this.windowLoaded = false;
}
Site.prototype = {
constructor: Site,
start: function () {
var me = this;
$(window).load(function () {
me.windowLoaded = true;
});
this.attach();
},
attach: function () {
this.attachBootstrapPrototypeCompatibility();
this.attachMedia();
},
attachBootstrapPrototypeCompatibility: function () {
/*// Bootstrap and Prototype don't play nice, in the sense that
// prototype is a really wacky horrible library. It'll
// hard-code CSS to hide an element when a hide() event
// is fired. See http://stackoverflow.com/q/19139063
// To overcome this with dropdowns that are both
// toggle style and hover style, we'll add a CSS
// class which has "display: block !important"
$('*').on('show.bs.dropdown show.bs.collapse active nav-tabs.active', function (e) {
$(e.target).addClass('bs-prototype-override');
});
$('*').on('hidden.bs.collapse nav-tabs', function (e) {
$(e.target).removeClass('bs-prototype-override');
});*/
var isBootstrapEvent = false;
if (window.jQuery) {
var all = jQuery('*');
jQuery.each(['hide.bs.dropdown',
'hide.bs.collapse',
'hide.bs.modal',
'hide.bs.tooltip',
'hide.bs.popover',
'hide.bs.tab'], function (index, eventName) {
all.on(eventName, function (event) {
isBootstrapEvent = true;
});
});
}
var originalHide = Element.hide;
Element.addMethods({
hide: function (element) {
if (isBootstrapEvent) {
isBootstrapEvent = false;
return element;
}
return originalHide(element);
}
});
},
attachMedia: function () {
var $links = $('[data-toggle="media"]');
if (!$links.length) return;
// When somebody clicks on a link, slide the
// carousel to the slide which matches the
// image index and show the modal
$links.on('click', function (e) {
e.preventDefault();
var $link = $(this),
$modal = $($link.attr('href')),
$carousel = $modal.find('.carousel'),
index = parseInt($link.data('index'));
$carousel.carousel(index);
$modal.modal('show');
return false;
});
}
};
jQuery(document).ready(function ($) {
var site = new Site();
site.start();
});
})(jQuery);
I already asked on github with no response question on github
So the Dropdown of Bootstrap is working.
My Question am i doing anything wrong or am i missing something?
Why does the nav-tabs not work in here?
Adding the "'bower_components/bootstrap/js/tab.js'," tab.js to the gulpfile.js AND
adding the tab class to the script.js solved my Problem with Bootstrap Nav Pills and Tabs.
$('*').on('show.bs.dropdown show.bs. hide.bs.tab hidden.bs.tab', function(e) {
$(e.target).addClass('bs-prototype-override');
});
$('*').on('hidden.bs.collapse', function(e) {
$(e.target).removeClass('bs-prototype-override');
});
At the end the code looks just like this:
jQuery.noConflict();
;(function($) {
'use strict';
function Site(settings) {
this.windowLoaded = false;
}
Site.prototype = {
constructor: Site,
start: function() {
var me = this;
$(window).load(function() {
me.windowLoaded = true;
});
this.attach();
},
attach: function() {
this.attachBootstrapPrototypeCompatibility();
this.attachMedia();
},
attachBootstrapPrototypeCompatibility: function() {
// Bootstrap and Prototype don't play nice, in the sense that
// prototype is a really wacky horrible library. It'll
// hard-code CSS to hide an element when a hide() event
// is fired. See http://stackoverflow.com/q/19139063
// To overcome this with dropdowns that are both
// toggle style and hover style, we'll add a CSS
// class which has "display: block !important"
$('*').on('show.bs.dropdown show.bs. hide.bs.tab hidden.bs.tab', function(e) {
$(e.target).addClass('bs-prototype-override');
});
$('*').on('hidden.bs.collapse', function(e) {
$(e.target).removeClass('bs-prototype-override');
});
},
attachMedia: function() {
var $links = $('[data-toggle="media"]');
if ( ! $links.length) return;
// When somebody clicks on a link, slide the
// carousel to the slide which matches the
// image index and show the modal
$links.on('click', function(e) {
e.preventDefault();
var $link = $(this),
$modal = $($link.attr('href')),
$carousel = $modal.find('.carousel'),
index = parseInt($link.data('index'));
$carousel.carousel(index);
$modal.modal('show');
return false;
});
}
};
jQuery(document).ready(function($) {
var site = new Site();
site.start();
});
})(jQuery);

Timeline change css on enter view port

Am trying to change the background color of the timeline on scroll like on this site.My replication of the sample is development site. Take a look at the codepen I tried using. The closest I have come to replicating it is with the code below which makes the change in color on each timeline circle flicker on/off on scroll.
jQuery(document).ready(function($) {
function onScroll() {
$('.cd-timeline-block').each( function() {
if( $(this).offset().top <= $(window).scrollTop()+$(window).height()*0.05 && $(this).find('.cd-timeline-img').hasClass('cd-inactive') ) {
$(this).find('.cd-timeline-img').removeClass('cd-inactive').addClass('cd-active');
$(this).find('.cd-date').addClass('cd-ssf-color');
} else {
$(this).find('.cd-timeline-img').addClass('cd-inactive').removeClass('cd-active');
$(this).find('.cd-date').removeClass('cd-ssf-color');
}
});
};
$(window).scroll(onScroll);
});
I have made some modification to the above code.
CodePen link:
http://codepen.io/anon/pen/KzqWVm
Javascript:
jQuery(document).ready(function($) {
var $timeline_block = $('.cd-timeline-block');
var firstelm = $timeline_block.first();
//on scolling, show/animate timeline blocks when enter the viewport
$(window).on('scroll', function() {
var _win = $(window), iselm = null;
$timeline_block.each(function(index) {
var _this = $(this);
if (((_this.offset().top - _win.height())) <= (_win.scrollTop())) {
iselm = _this;
}
});
if (_win.scrollTop() < $(firstelm).offset().top) {
iselm = $(firstelm);
}
if (iselm) {
$('.cd-active').removeClass('cd-active').addClass('cd-inactive');
iselm.find('.cd-timeline-img').removeClass('cd-inactive').addClass('cd-active');
if ((iselm.offset().top - _win.height()) > (_win.scrollTop() * 0.75)) {
$('.cd-date').removeClass('cd-ssf-color');
}
iselm.find('.cd-date').addClass('cd-ssf-color');
}
});
});
Continuing each loop on scroll might not work properly.

jQuery - Toggle text to change on click

I have a menu button, which when clicked will slide down a div below.
My menu is title "+ Open menu"
When the menu button is clicked my code changes the title to "+ Menu" to indicate that the menu is open.
When the user closes the menu I would like the title to revert back to "- Menu"
This is my HTML which defines the class, test in this case.
<span class="test">+ Open menu</span>
Here is my jQuery function, I cannot figure out how to revert the menu state.
$(document).ready(function () {
$(".widget_head_type").click(function ()
{
$(".widget_body_type").slideToggle("slow");
$(".test").text("- Close menu");
});
});
$(".widget_head_type").click(function () {
$(".widget_body_type").slideToggle("slow");
($(".test").text() === "+ Open menu") ? $(".test").text("- Close menu") : $(".test").text("+ Open menu");
});
jQuery.fn.extend({
toggleText: function (a, b){
var that = this;
if (that.text() != a && that.text() != b){
that.text(a);
}
else
if (that.text() == a){
that.text(b);
}
else
if (that.text() == b){
that.text(a);
}
return this;
}
});
Use as:
$("#YourElementId").toggleText('After', 'Before');
Here is an interesting one based on the http://api.jquery.com/toggle/
HTML
<span class="test">+ Open menu</span>
<span class="test" style="display:none">- Close menu</span>
JS
$(document).ready(function () {
$(".widget_head_type").click(function ()
{
$(".widget_body_type").slideToggle("slow");
$(".test").toggle();
});
Simple, just toggles the all tags with class test whether hidden or visible.
WORKING FIDDLE HERE
I've guessed at your html, and made some notes for alternatives, but you consider the following:
HTML:
<div class="some_parent_class">
<div class="widget_head_type">
<span class="test">+ Menu</span>
</div>
<div class="widget_body_type">
Body
</div>
</div>
JS:
jQuery(function ($) {
$('.widget_head_type').each(function () {
// closures
var $toggle = $(this);
var $parent = $toggle.closest('.some_parent_class');
var $target = $parent.find('.widget_body_type');
var $label = $toggle.find('.test');
var bIsTweening = false;
// OR var $target = $toggle.next('.widget_body_type');
// event methods (closures)
var fClickToggle = function () {
if (!bIsTweening) {
bIsTweening = true;
$target.slideToggle('slow', fToggleCallback);
}
};
var fToggleCallback = function () {
bIsTweening = false;
fSetLabel();
};
var fSetLabel = function () {
var sLabel = $label.text().replace('+', '').replace('-', '');
sLabel = ($target.is(':visible') ? '-' : '+') + sLabel;
$label.html(sLabel);
};
// handle event
$toggle.click(fClickToggle);
$target.hide();
fSetLabel();
});
});
had same issue and this is how i solved it: using your code example.
$(".widget_head_type").click(function () {
$(".widget_body_type").slideToggle("slow");
($(".test").text() == "+ Open menu") ? $(".test").text("- Close menu") : $(".test").text("+ Open menu");
});
use two equal signs for comparison.

How to implement nav bar using jQuery

I am trying to implement nav bar navigation using jQuery. But no luck! Please have a look at this fiddle.
My requirement is to active menu item based on content scrolled, and scrolling the content based on menu item clicked. Below is the code
$('.menu-item').on('click', function () {
var that = $(this);
$('.menu-item').each(function () {
$(this).removeClass('active');
});
that.addClass('active');
var index = that.index();
var target = $('.menu .menu-target').eq(index);
$('.right').animate({
scrollTop: target.offset().top
}, 500);
});
$('.right').on('scroll', function () {
var scrTop = $(this).scrollTop(),
tgt = "";
$('.menu-target').each(function () {
var th = $(this),
offTop = th.offset().top;
if (offTop > scrTop && && tgt === "") {
tgt = th;
}
});
if (tgt !== "") {
var index = tgt.index();
$('.menu-item').each(function () {
$(this).removeClass('active');
});
$('.menu-item').eq(index).addClass('active');
}
});
But this is not working. Updating active menu item on scroll is not working. How to fix this?
Edit
Tried to fix the issue and here is the code http://jsfiddle.net/SfR2c/11/
It is working with some inconsistency in updating menu element based on scroll content!
Replace this
var target = $('.menu .menu-target').eq(index);
by this
var target = $('.right .menu-target').eq(index);
there is already a working solution to your needs. when programming please DO reuse everything you can.
the solution is to use Bootstrap from twitter ScrollSpy

Categories

Resources