Bootstrap 3 panel group collapse outside of group - javascript

I think I am doing this a slightly silly way, and so am happy to take suggestions for a new approach.
I am creating a accordion style dropdown nav for mobile but I want the target divs to be outside of the panel group. My code is of the form:
<div class='panel-group' id='accordian'>
<div class='mystyles'>
<ul>
<li>
<div class='nav-item'>
<a data-toggle='collapse' data-parent='#accordian' href='#target-one-id'>Item 1</a>
</div>
</li>
.... more list items here...
</ul
</div>
<!-- the collapsed divs start here -->
<div id='target-one-id' class='clearfix collapse panel-collapse'>
...content
</div>
... more target divs here
</div> <!-- end panel group -->
I have chosen to do this as I need to style the links differently to the collapsed divs and I want them to appear lower down the page. It does generally work, however, to make a target div collapse you have to click on it's parent link. I want the child to collapse whenever any of the list links are clicked. Or in other words I want only one target div visible at any one time.
I may just not understand bootstrap but how would I go about doing this?
EDIT: A bad solution
So I have a slightly rough solution where I add js code of the form:
$("#target-one").on("show.bs.collapse", function(){
$("#target-two").collapse('hide');
$("#target-three").collapse('hide');
});
This works but the transition animation is jerky and the targets being closed appear to reopen and close as they are hidden. What is a better solution?
$("#target-one").on("show.bs.collapse", function(){
$("#target-two").collapse('hide');
$("#target-three").collapse('hide');
});
$("#target-two").on("show.bs.collapse", function(){
$("#target-one").collapse('hide');
$("#target-three").collapse('hide');
});
$("#target-three").on("show.bs.collapse", function(){
$("#target-two").collapse('hide');
$("#target-one").collapse('hide');
});
.mystyles ul {
list-style-type:none;
margin: 0;
padding: 0;
}
.mystyles ul li {
display:inline-block;
}
.mycontent {
background-color:orange;
}
.one {
height:300px;
background-color:pink;
}
.two {
width:200px;
height:500px;
}
<head>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class='panel-group' id='accordian'>
<div class='mystyles'>
<ul>
<li>
<div class='nav-item'>
<a data-toggle='collapse' data-parent='#accordian' href='#target-one'>Item 1</a>
</div>
</li>
<li>
<div class='nav-item'>
<a data-toggle='collapse' data-parent='#accordian' href='#target-two'>Item 2</a>
</div>
</li>
<li>
<div class='nav-item'>
<a data-toggle='collapse' data-parent='#accordian' href='#target-three'>Item 3</a>
</div>
</li>
</ul </div>
<!-- the collapsed divs start here -->
<div id='target-one' class='clearfix collapse panel-collapse'>
<div class='mycontent one'>
content...
</div>
</div>
<div id='target-two' class='clearfix collapse panel-collapse'>
<div class='mycontent two'>
content...
</div>
</div>
<div id='target-three' class='clearfix collapse panel-collapse'>
<div class='mycontent three'>
content...
</div>
</div>
</div>
<!-- end panel group -->
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
Ok so the snippet seems to work properly... I am now a little confused. My actual code is almost identical except for some dynamic content which is inserted into the target divs.
Could resizing of the hidden diff cause problems? I do not know how to simulate that in the snippet.

Related

Bootstrap 4 change accordion behaviour

I'm using HTML templates, which are based on Bootstrap 4.3.1 to present my students with learning content. In the current templates, all accordion panels are closed on page load and each accordion panel can be opened regardless of how many others have also been opened.
A working example can be found on this CodePen: https://codepen.io/hagelslag1001/pen/MWGeZJr
The HTML code is as follows:
<h2>Accordion: Group of 2</h2>
<p class="small">Accordion: start copy</p>
<!-- Accordion headings should be changed to respect page hierarchy -->
<div class="accordion shadow mb-5">
<div class="card">
<div class="card-header">
<h2 class="card-title">
Accordion 1 of 2
</h2>
</div>
<div class="collapse">
<div class="card-body">
<p>Insert Accordion 1 of 2 content here.</p>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h2 class="card-title">
Accordion 2 of 2
</h2>
</div>
<div class="collapse">
<div class="card-body">
<p>Insert Accordion 2 of 2 content here.</p>
</div>
</div>
</div>
</div>
<p class="small">Accordion: end copy</p>
Is it possible to change this default behaviour so that only one panel can be opened at a time? (i.e. as soon as a new panel is opened, the previously opened panel will automatically close)
The Bootstrap examples use (data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne") to accomplish this for the accordions in these templates
I can't figure out how to accomplish this, since the HTML code for the accordions in these templates look different than the Bootstrap 4 examples, which use either an a or button tag to trigger the collapsible event.
Here is a simpler answer based on your CodePen: https://codepen.io/mrtcntn/pen/MWGeZdP
According the Bootstrap 4 docs, you need id="accordion" on the top level div and you don't need to give ids like id="accordion_1" and id="accordion_2".
Therefore I removed the first portion from the JS and added id="accordion" at line 18 in the HTML.
You can do this by letting javascript check for active classes and only allowing one at the time. Here's a simplified example.
// DOM here
let nav = document.querySelector(".nav");
// Handlers here
const clickHandler = function (e) {
if (e.target.classList.contains("nav__link")) {
const link = e.target;
const siblings = link.closest(".nav").querySelectorAll(".nav__link");
link.classList.toggle("active");
// removes all actives except for the clicked one
siblings.forEach((el) => {
if (el !== link) el.classList.remove("active");
});
}
};
// Listeners here
nav.addEventListener("click", clickHandler);
body {
font-family: sans-serif;
}
.nav__link {
display: block;
width: 100%;
}
.active {
background: #0f0;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
</head>
<body>
<div class="nav">
<ul class="nav__links">
<li class="nav__item">
<a class="nav__link" href="#accordeon--1">Accordeon 1</a>
</li>
<li class="nav__item">
<a class="nav__link" href="#accordeon--2">Accordeon 2</a>
</li>
<li class="nav__item">
<a class="nav__link" href="#accordeon--3">Accordeon 3</a>
</li>
<li class="nav__item">
<a class="nav__link" href="#accordeon--4"
>Accordeon 4</a
>
</li>
</ul>
</div>
</div>
<script src="src/index.js"></script>
</body>
</html>

add a margin when the navbar becomes fixed

So the problem is, I want to make my nav fixed when the header disappeared.
everything works fine but the problem is that after the navbar got fixed the article goes under it. and I want to fix that but i want the padding or margin to be added when the navbar is fixed.
my code:
<script type="text/javascript" src="jquery-3.1.1.js"></script>
<script>
var num = 120; //number of pixels before modifying styles
$(window).bind('scroll', function() {
if ($(window).scrollTop() > num) {
$('nav').addClass('fixed');
} else {
$('nav').removeClass('fixed');
}
});
</script>
Html
<div id="headwrapper">
<header>
<img src="Logo.png">
<h1>IT TECH</h1>
</header>
</div>
<nav>
<div id="selector"></div>
<a class="link1" href="home.htm">
<p>Home</p>
</a>
<a class="link2" href="talen.htm">
<p>Programmeertalen</p>
</a>
<a class="link3" href="computer.htm">
<p>Computers</p>
</a>
<a class="link4" href="richting.htm">
<p>Richtingen</p>
</a>
<a class="link5" href="contact.htm">
<p>Contact</p>
</a>
</nav>
<div id="element">
<div id="slider">
<div title="Banaan" id="foto1">
<h1>Welcome to</h1><img src="Logo.png">
<h1>IT TECH</h1></div>
<div title="Peren" id="foto2"></div>
<div title="Kiwi's" id="foto3"></div>
<div title="Aardbeien" id="foto4"></div>
</div>
</div>
<article></article>
so i want to add a class which gives the slider a margin or the element a padding.
I am not the pro with javascript so I am happy it works so far :)
Have your script set the padding on the body equal to the (current) height of the nav when the user scrolls down to it (or causes the nav to be at the top by resizing the window.)
$(window).bind('scroll resize', function() {
var $nav = $('nav'),
$body = $('body');
$nav.removeClass('fixed');
$body.css('padding-top',0);
if ($(window).scrollTop() > $nav.offset().top) {
$nav.addClass('fixed');
$body.css('padding-top',$nav.outerHeight());
}
});
html, body {margin:0;}
nav {display:block; background:#eee; width:100%;}
nav.fixed {position:fixed; top:0;}
nav a {display:inline-block; padding:10px;}
#foto1 img {width:100%}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="headwrapper">
<header>
<img src="https://placekitten.com/50/50">
<h1>IT TECH</h1>
</header>
</div>
<nav>
<div id="selector"></div>
<a class="link1" href="home.htm">
<p>Home</p>
</a>
<a class="link2" href="talen.htm">
<p>Programmeertalen</p>
</a>
<a class="link3" href="computer.htm">
<p>Computers</p>
</a>
<a class="link4" href="richting.htm">
<p>Richtingen</p>
</a>
<a class="link5" href="contact.htm">
<p>Contact</p>
</a>
</nav>
<div id="element">
<div id="slider">
<div title="Banaan" id="foto1">
<h1>Welcome to</h1><img src="https://placekitten.com/50/50">
<h1>IT TECH</h1></div>
<div title="Peren" id="foto2"></div>
<div title="Kiwi's" id="foto3"></div>
<div title="Aardbeien" id="foto4"></div>
</div>
</div>
<article></article>
You can use the general sibling selector to select the article. It would look like this:
.fixed ~ #slider {}
It's important to note that the general sibling will only select items AFTER the first element. Your selector cannot traverse back up the DOM.

Manipulate css style of a class depending on other class css style

I am using navigation drawer of Framework7 plugin on my hybrid app. The drawer can be open/close using the button as well as using swipe/slide left/right.
Now when the navigation drawer was open, the class <div class="panel panel-left panel-reveal"> added another class which is active class.
So when opened: <div class="panel panel-left panel-reveal active ">
when closed: <div class="panel panel-left panel-reveal>
Based on that event, is it possible to add style to other class?
Example is this class: <div class="views"> to <div class="views" style="opacity: 0.5">
What to accomplish: When the drawer is open, the class view will add style, when drawer is close remove the view class style.
Is it possible to catch that event and accomplish what I would like to do?
Sorry for the delay, so below is the sample code to add a css class to a div only on hover event. I have done this using html and css only. (No DOM manipulation).
<!doctype html>
<html>
<head>
<style>
a.ex1:hover{color: red;}
a.ex2:hover, a.ex2:active {font-size: 150%;}
a.ex3:hover, a.ex3:active {background: red;}
a.ex4:hover, a.ex4:active {font-family: monospace;}
a.ex5:visited, a.ex5:link {text-decoration: none;}
a.ex5:hover, a.ex5:active {text-decoration: underline;}
.open-close{ display: none;}
a.ex6:hover .open-close{display: block;}
</style>
</head>
<body>
<p>
<a class = "ex1" href="#"> This link changes color </a>
</p>
<p>
<a class = "ex2" href="#"> This link changes font-size </a>
</p>
<p>
<a class = "ex3" href="#"> This link changes background-color </a>
</p>
<p>
<a class = "ex4" href="#"> This link changes font-family </a>
</p>
<p>
<a class = "ex5" href="#"> This link changes text-decoration </a>
</p>
<p>
<a class = "ex6" href="#">
<div>This link displays another div by detecting change in class</div>
<div class="open-close">
Here you can add your content to hide/show/modify elements based on the classes
</div>
</a>
</p>
</body>
</html>
NOTE - Just remember to use the appropriate CSS selector based on your HTML structure.
Hope this helps. Let me know if you have any questions. Happy to help.
Hi Yes it is Possible. Using HTML and Javascript itself. You can also achieve this using JQUERY DOM manipulation. Let me know which one would you want to know.
I have modified your HTML a little
<div class="panel-overlay"></div>
<div class="panel panel-left panel-reveal">Just to see if his appears in green on fire of a single common event</div> <!---it adds "active class" e.g. <div class="panel panel-left panel-reveal active"> -->
<div class="views"> Just to see if this appears in red on fire of a single common event<!--this should toggle change background, i mean add background color when class panel has active class then remove the bgcolor when active class remove (vise versa) -->
<div class="view view-main" data-page="home">
<div class="pages">
<div data-page="home" class="page navbar-fixed">
<div class="navbar">
<div class="navbar-inner">
<div class="left">
<button onclick="myFunction()" type="button" class="open-panel fa fa-bars button-nav"> I am button 1</button>
</div>
<div class="center" style="left: -6.5px;"></div>
<div class="right">
<button type="button" id="refresh" class="button-nav"> <i class="el el-refresh"></i> I am button 2</button>
</div>
</div>
</div>
<div class="page-content">
<div class="content-block"> content here... </div>
</div>
</div>
</div>
</div>
</div>
Just add this JavaScript function and you will be good to go.
function myFunction(){
$(".panel-reveal").addClass("active");
if($(".panel-reveal").hasClass("active")) {
$(".views").addClass("change")
}
}
CSS will be
.active{
background-color: green !important;
}
.change{
background-color: red !important;
}
I hope this helped.

buttons to activate buttons that toggle from one div to another

Apologies in advance if this is a simple trick, but I'm not any good at javascript so I don't know how to do it...
I have two buttons (blue and yellow) that toggle between two divs with content. On another part of the page, I have another two buttons (also blue and yellow) that are supposed to activate the same-colored button of these two toggle buttons. So blue will activate toggle-blue and yellow will activate toggle-yellow. I used the below script I found on here for the toggle feature:
<div class="flr-wrap">
<ul>
<li><a class="button active" data-rel="#content-a" href="#">a button</a>
</li>
<li><a class="button" data-rel="#content-b" href="#">b button</a>
</li>
</ul>
<div class="flr-inner">
<div class="container" id="content-a">AAA</div>
<div class="container" id="content-b">BBB</div>
</div>
</div>
// set content on click
$('.button').click(function (e) {
e.preventDefault();
setContent($(this));
});
// set content on load
$('.button.active').length && setContent($('.button.active'));
function setContent($el) {
$('.button').removeClass('active');
$('.container').hide();
$el.addClass('active');
$($el.data('rel')).show();
}
from here:
jsfiddle
What do I add to make the other two buttons trigger the active states of their corresponding toggle buttons?
Many thanks in advance for any help!
Since you said you need the second set of buttons to trigger actions of the first set, this means that buttons do the same thing.
Here's an example of how this works:
http://jsfiddle.net/ivanbatic/b43m405x/
Javascript:
$('.activator').on('click', function () {
var target = $(this).attr('data-target');
$('.panel').removeClass('active');
$(target).toggleClass('active');
});
HTML
<section>
<button class="activator" data-target=".panel-a">Blue</button>
<button class="activator" data-target=".panel-b">Yellow</button>
<section>
<div class="panel active panel-a">First Panel</div>
<div class="panel panel-b">Second Panel</div>
</section>
<section>
<button class="activator" data-target=".panel-a">Blue</button>
<button class="activator" data-target=".panel-b">Yellow</button>
</section>
Also, you are not using buttons in your example, you are using links. Links are meant to take you to another page, buttons are meant to trigger an action.
If you want buttons to look like plain text, use CSS for styling.
You can do pretty much the same, just use the selector based on your data-rel to add the active class and add the active class to the button's data-rel statement, like that it's quite easy to always toggle the matching tags
function setContent($el) {
var rel = $el.data('rel');
$('.active').removeClass('active');
$('.container').hide();
$('[data-rel="' + rel + '"]').addClass('active');
$(rel).show();
}
$(function() {
// the right place to fire the initial setContent (all scripts are ready and page is loaded)
setContent($('.button.active'));
// add event handlers in ready event (DOM is most surely there)
$('.button').click(function(e) {
e.preventDefault();
setContent($(this));
});
});
.container {
display: none;
}
.button.active {
color: #C00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="flr-wrap">
<ul>
<li><a class="button active" data-rel="#content-a" href="#">a button</a>
</li>
<li><a class="button" data-rel="#content-b" href="#">b button</a>
</li>
</ul>
<div class="flr-inner">
<div class="container" id="content-a">
AAA
</div>
<div class="container" id="content-b">
BBB
</div>
</div>
<ul>
<li><a class="button active" data-rel="#content-a" href="#">a button</a>
</li>
<li><a class="button" data-rel="#content-b" href="#">b button</a>
</li>
</ul>
</div>

Keep toggle state on divs using cookie.js after page refresh [duplicate]

This question already has answers here:
Keep toggle state on divs using cookie.js after page refresh view jsFiddle
(2 answers)
Closed 9 years ago.
I have a simple code which allows me to toggle betwen two divs which are wraps for two sub navigations (#sub-nav-wrap is the alternative nav). They are fixed to the bottom of the browser :
$(function(){
$('.button').click(function(){
$('#sub-nav-wrapmin').toggle();
$('#sub-nav-wrap').toggle();
});
});
What I wish to do is to keep the state of each div the same as chosen by the user after page refresh and even if the clicks on a new sub-heading the menu will remain the same, rather then resorting to the default state.
The html is this:
<!--- Main Sub Wrap --->
<div id="bottom-wrap">
<!-- Mini Sub Nav -->
<div id="sub-nav-wrapmin" class="snWrap divone">
<div id="sn-contentmin">
<div id="sn-likemin"></div>
<div id="sn-coffeesml"></div>
<div id="sn-sharemin"></div>
<div id="sn-commentsml"></div>
<div id="toggle-barmin">
<div id="sn-sidebrdrmin"></div>
<div class="sn-toggle button"></div>
</div>
<ul class="sn-comicsmin menu">
<li><a class="sn-comics" style="background-position: right top" href="#comic.html">Comic</a></li>
<li><a class="sn-archive" href="#archive.html">Archive</a></li>
<li><a class="sn-vote" href="#vote.html">Vote</a></li>
<li><a class="sn-spotlight" href="#spotlight.html">Spotlight</a></li>
</ul>
</div>
</div>
<!-- Sub Nav -->
<div id="sub-nav-wrap" class="snWrap divtwo">
<div id="sub-nav-container">
<div id="sub-nav-content">
<div id="sn-bnrlft"></div>
<div id="sn-bnrrgt"></div>
<div class="sn-dividelft"></div>
<div class="sn-dividergt"></div>
<div id="sn-likebg"></div>
<div id="sn-coffeebtn">
</div>
<div id="sn-sharebtn"></div>
<div id="sn-commentbtn"></div>
<div id="toggle-bar">
<div id="sn-sidebrdr"></div>
<div class="toggle button"></div>
</div>
</div>
<div id="sub-nav-brdr">
<ul class="sub-nav-comics menu">
<li><a class="comics" style="background-position: right top" href="#comic.html">Comic</a></li>
<li><a class="archive" href="#archive.html">Archive</a></li>
<li><a class="vote" href="#vote.html">Vote</a></li>
<li><a class="spotlight" href="#spotlight.html">Spotlight</a></li>
</ul>
</div>
</div>
</div>
The CSS is this:
#sub-nav-wrap {
display: none;
}
This is my first time asking, and I have been wracking my brains to get this to work using other similar codes from this site, but nothing is working.
Please help...
you're almost done everything right only have written a lot of superfluous :)
$(function(){
if($.cookie('submin_visible') == 'true') {
$('#sub-nav-wrapmin').show();
$('#sub-nav-wrap').hide();
} else {
$('#sub-nav-wrapmin').hide();
$('#sub-nav-wrap').show();
}
$('.button').click(function(){
$('#sub-nav-wrapmin').toggle();
$('#sub-nav-wrap').toggle();
var isVisible = $('#sub-nav-wrapmin').is(':visible').toString();
$.cookie('submin_visible', isVisible);
});
});

Categories

Resources