Closing nested accordion closes everything - javascript

I have a problem with my nested accordions.
I have been trying to figure out how to nest my accordions but in a sense that I dont need to write any extra jquery codes for each specific one I add.
I made a jsfiddle as an example... https://jsfiddle.net/L2bwmgL8/
and the code for the accordion looks like this:
$(document).ready(function() {
function close_accordion_section() {
$('.accordion .accordion-section-title').removeClass('active');
$('.accordion .accordion-section-content').slideUp(1000).removeClass('open');
}
$('.accordion-section-title').click(function(e) {
// Grab current anchor value
var currentAttrValue = $(this).closest('.accordion-section-title');
//console.log(currentAttrValue);
if (currentAttrValue.hasClass('active')) {
close_accordion_section();
} else {
close_accordion_section();
// Add active class to section title
currentAttrValue.addClass('active');
// Open up the hidden content panel
$('.accordion ' + currentAttrValue.attr('href')).slideDown(1000).addClass('open');
setTimeout(function() {
$('html, body').animate({
scrollTop: $(currentAttrValue.attr('href')).offset().top
}, 1000);
}, 1001);
//console.log((currentAttrValue.attr('href')));
}
e.preventDefault();
});
});
This way it works fine when I dont have them nested. However, when they are nested as in the example, under the first accordion (ignore the broken images).
Then when I click on the specific accordion to close, everything inside that accordion closes, including the parent one. Or, maybe I think just the parent closes.
Now, I tried, maybe passing the currentAttrValue inside the close_accordion_section() function like close_accordion_section(currentAttrValue) and changing the close_acordion_section to:
function close_accordion_section() {
$(this).closest('.accordion .accordion-section-title').removeClass('active');
$(this).closest('.accordion .accordion-section-content').slideUp(1000).removeClass('open');
}
But then everything opens up nicely, but I cant close any of the accordions anymore.
Any help and explanation would be appriciated, I am still learning the ropes so to speak.

I would simplify it, and then just target the siblings of the current accordion so as to not affect the parent accordion of nested accordions etc.
$(document).ready(function() {
$('.accordion-section-title').on('click', function(e) {
e.preventDefault();
var self = $(this).toggleClass('active');
var section = self.closest('.accordion-section');
var siblings = section.siblings('.accordion-section');
siblings.find('.accordion-section-content').slideUp(1000).removeClass('open').end()
.find('.accordion-section-title').removeClass('active');
$('.accordion ' + self.attr('href')).slideToggle(1000).toggleClass('open')
.find('.accordion-section-title.active')
.trigger('click');
if (self.hasClass('active')) {
setTimeout(function() {
$('html, body').animate({
scrollTop: $(self.attr('href')).offset().top
}, 1000);
}, 1001);
}
});
});
FIDDLE

The issue is in your if else statement:
you need to cut one of the calls to close_accordion_section():
I have a problem with my nested accordions. I have been trying to figure out how to nest my accordions but in a sense that I dont need to write any extra jquery codes for each specific one I add.
I made a jsfiddle as an example... https://jsfiddle.net/L2bwmgL8/
and the code for the accordion looks like this:
$(document).ready(function() {
function close_accordion_section() {
$('.accordion .accordion-section-title').removeClass('active');
$('.accordion .accordion-section-content').slideUp(1000).removeClass('open');
}
$('.accordion-section-title').click(function(e) {
// Grab current anchor value
var currentAttrValue = $(this).closest('.accordion-section-title');
//console.log(currentAttrValue);
if (currentAttrValue.hasClass('active')) {
close_accordion_section();
} else {
//CUT THIS
// Add active class to section title
currentAttrValue.addClass('active');
// Open up the hidden content panel
$('.accordion ' + currentAttrValue.attr('href')).slideDown(1000).addClass('open');
setTimeout(function() {
$('html, body').animate({
scrollTop: $(currentAttrValue.attr('href')).offset().top
}, 1000);
}, 1001);
//console.log((currentAttrValue.attr('href')));
}
e.preventDefault();
});
});
fiddle: https://jsfiddle.net/kjyqmzuh/

Related

How to set an event listener which closes the menu

I have the following code:
<script type="text/discourse-plugin" version="0.8.13">
$(document).ready(function() {
if ($('#daily-check-in').length) {
$('#daily-check-in').attr("href", settings.daily_check_in_url);
$('#daily-check-in').text(settings.daily_check_in_text);
}
if ($('#current-user').length) {
var image_bell = 'https://cdn.ramseysolutions.net/church/fpu/images/icon-bell.svg';
$('#current-user').find('img')[0].setAttribute('src', image_bell);
}
setTimeout(function() {
$('#js_fpu_global_nav > ul').css('transition', 'margin 0.4s').delay(1000);
}, 2000);
$('#js_top_nav_hamburger').click(function(e) {
$('#js_fpu_global_nav > ul').toggleClass('open-top-nav');
e.stopPropagation();
});
$(document).on("click", function(e) {
if ($(e.target).is("#js_fpu_global_nav > ul") === false) {
$('#js_fpu_global_nav > ul').removeClass('open-top-nav');
}
});
});
</script>
The important part is:
$('#js_top_nav_hamburger').click(function(e) {
$('#js_fpu_global_nav > ul').toggleClass('open-top-nav');
e.stopPropagation();
});
For now, when I move between pages in dynamic way, it keeps the menu open. I would like to close it every time user clicked on some other place of the page (not in the menu box) or if he moved to a different page (even if its from one of the links from this menu page).
I'm familiar with Vanilla JS addEventListener but I'm not sure how to use it here or if its the right approach. The desired output is to close the menu every time user clicks on something else. Other code could be found on Github (link).

jQuery scroll to anchor with exception

friends,
I'm building single page website, which uses the jQuery function to scroll to an anchor, when the menu link is being selected. Here is the code I use:
(function($) {
var jump = function(e)
{
if (e) {
e.preventDefault();
var target = $(this).attr("href");
} else {
var target = location.hash;
}
$('html,body').animate(
{
scrollTop: $(target).offset().top - 150
}, 1500, 'swing', function()
{
location.hash = target - 150;
});
}
$('html, body').hide()
$(document).ready(function()
{
$('a[href^=#]').bind("click", jump);
if (location.hash) {
setTimeout(function() {
$('html, body').scrollTop(0).show()
jump()
}, 0);
} else {
$('html, body').show()
}
});
})(jQuery)
Now this function is called for all html 'a' elements with 'href'. I need to modify the function above, so it would work for all defined links except this one with the anchor #nav-menu:
<span></span>
Any suggestions would be very appreciated.
Jquery provide a set of built-in filters that you can use in your case you may use:
the built in filter not() as following:-
$("a[href^=#]:not([href=#nav-menu])").click(jump);
build you own business filter as following:-
$("a[href^=#]").filter(function() {
//you may here do whatever filteration business you want
return $(this).attr("href")!='#nav-menu';
}).click(jump);
Simple Example Here

Can't get basic jQuery logic to work

I have this button in my HTML that basically collapses/expands the #leftmenu and it's working okay: <a id="menutoggle" data-toggle="collapse" data-target="#leftmenu">Placeholder</a>
I want to accomplish this:
If #leftmenu is visible when you load the page then add
top:-10px property to #contentfix.
If #leftmenu is collapsed by clicking the collapse button then remove top:-10px property from #contentfix.
If #leftmenu is expanded by clicking the collapse button then add top:-10px property to #contentfix.
I basically want the top:-10px property in my #contentfix whenever #leftmenu is visible and top:0px whenever it is hidden. Regardless of whether page had it visible/hidden by default or you changed it by clicking the collapse button.
Here's my current attempt:
if ($("#leftmenu").is(":visible")) {
$('#contentfix').css('top','-10px');
var visible = 1;
}
$('#menutoggle').click(function(e) {
$('html, body').animate({ scrollTop: 0 }, 'fast');
if (visible == 0){
$('#contentfix').css('top','-10px');
visible = 1;
} else {
$('#contentfix').css('top','0px');
visible = 0;
}
});
Make sure to use $(document).ready(). Moreover you can cache jQuery objects and do not need to set a visible variable and write the same functionality twice.
$(document).ready(function(){
var contentFix = $('#contentfix');
var leftMenu = $("#leftmenu");
var menuToggle = $('#menutoggle');
var htmlBody = $('html, body');
var toggle = function(){
htmlBody.animate({ scrollTop: 0 }, 'fast');
if (leftMenu.is(":visible")) {
contentFix.css('top','-10px');
} else {
contentFix.css('top','0px');
}
}
menuToggle.on('click', function() {
toggle();
});
});

On click add/remove overflow hidden

I'm trying to add/remove .css('overflow-y','hidden') onclick, Which I did. The problem appears when I try to remove that css, also onclick. But this time, user needs to click on another element.
Idea is to have modal (twitter bootstrap 2.3) window where there is some data and when user click on modal button (triggers) the css applies to html element in order to prevent scrolling of the website. And now when I click anywhere on modal (modal shuts down) but there is still overflow-y styling and because of it I can't scroll my page.
So this is what I've made, but I have been stuck here and don't know where I am making mistake. Could anyone help me with this one, and if is possible give me some advice so I could take care in future.
Thanks!
<script type="text/javascript">
$('#myModal').modal('hide') // initializes and invokes show immediately</p>
$('.note').delay(10000).fadeOut('slow');
$(document).ready(function() {
var $html = $('html');
var $button = $('.container > .btn-primary');
var $modal = $('.modal-backdrop');
$button.on('click', function(e) {
$html.css('overflow-y', 'hidden');
if ($html.attr('style')) {
alert('WORKS!');
}
else {
$modal.onclick( function() {
$html.css('overflow-y','scroll');
});
};
});
});
</script>
Put your css in a class and use jquery's .toggleClass() to show/hide the overflow.
Here's a simplified example: http://jsbin.com/towiyaqa/1/
You can use like this:
$button.on('click', function(e) {
$html.css('overflow-y','hidden' ? 'scroll' : 'hidden');
e.preventDefault();
})
Here is solution for problem:
$(document).ready(function() {
var $html = $('html');
var $button = $('.container > .btn-primary');
var $modal = $('.modal-backdrop');
$button.on('click', function(e) {
$('.note').delay(10000).fadeOut('slow');
$html.css('overflow-y', 'hidden');
if ($html.attr('style')) {
console.log("overflow-y: hidden added");
}
});
$('#myModal').on('hidden.bs.modal', function () {
// do something…
console.log("fires myModal");
$html.css('overflow-y','scroll');
});
});
</script>

How to adjust div location on animate

In a webapplication I'm working on, when you click on a listitem, a div pops out.
You can find an example here.
How can I adjust the top of the div to the listitem?
The div (#home in the example) has to pop out with the top next to the list item.
$(function () {
$("#home_link").click(function () {
$("#home").animate({width: 'toggle'}, 500);
});
});
$(function () {
$("#edit_link").click(function () {
$("#home").animate({width: 'toggle'}, 500);
});
});
So, I cleaned up some of it and reorganized it. Basically, I marked a container element (which holds both the navs and the content), and use that to determine the desired offset. I made everything more generic so you can just add more hyperlinks as you need! Hopefully this is helpful, let me know if you have any questions about why I did things this way, or how something works.
jsFiddle
$(function () {
$("#list a").click(function () {
var $this = $(this);
var $container = $this.closest('[data-id="container"]');
var $target = $($this.attr('href'));
$target.css('margin-top', $this.offset().top - $container.offset().top);
$target.animate({width: 'toggle'}, 500);
});
});

Categories