Bootstrap toggle chevron - javascript

I am using bootstrap 3 and I have some collapsible panels which act as filters on a results page. So it isnt really an accordion menu as more than one can be open at any given time. Plus some will be open upon page load (using class in). So I need some javascript that will toggle the chevron depending on the state of the panel (opened or closed).
Here is the mark up:
<!-- Filter options -->
<div id="accordion">
<div class="panel-header">
<h5><a data-toggle="collapse" data-parent="#accordion" href="#collapseOne">Subject<span class="glyphicon glyphicon-chevron-down pull-right"></span></a></h5>
<div id="collapseOne" class="panel-collapse collapse in">
<ul class="list-unstyled">
<li class="selected"><span class="uxf-icon uxf-close-square"></span>Foreign Relations (15676) </li>
<li>Vietnam War (13013) </li>
<li>Government Documents (10479) </li>
<li class="selected"><span class="uxf-icon uxf-close-square"></span>Military Assistance</li>
<li>More...</li>
</ul>
</div>
</div>
<div class="panel-header">
<h5><a data-toggle="collapse" data-parent="#accordion" href="#collapseTwo">Geography<span class="glyphicon glyphicon-chevron-down pull-right"></span></a></h5>
<div id="collapseTwo" class="panel-collapse collapse">
<ul class="list-unstyled">
<li>Foreign Relations (15676) </li>
<li>Vietnam War (13013) </li>
<li>Government Documents (10479) </li>
<li>Military Assistance
</li><li>More...</li>
</ul>
</div>
</div>
<div class="panel-header">
<h5><a data-toggle="collapse" data-parent="#accordion" href="#collapseThree">Person As Subject<span class="glyphicon glyphicon-chevron-down pull-right"></span></a></h5>
<div id="collapseThree" class="panel-collapse collapse">
<ul class="list-unstyled">
<li>Foreign Relations (15676) </li>
<li>Vietnam War (13013) </li>
<li>Government Documents (10479) </li>
<li>Military Assistance
</li><li>More...</li>
</ul>
</div>
</div>
</div>
Obviously at the minute all of the panels have the chevron down icon.
Many thanks

Check the open/closed status of each div by looking for the in class.
Once set you can swap the chevron classes within a click event.
// onload
$('a[data-toggle=collapse]').each(function() {
var chevron = $(this).parent().next('div');
if ( chevron.hasClass('in') ) {
$(this).children('span').removeClass('glyphicon-chevron-down').addClass('glyphicon-chevron-up');
} else {
$(this).children('span').removeClass('glyphicon-chevron-up').addClass('glyphicon-chevron-down');
}
});
// click event
$('a[data-toggle=collapse]').click( function() {
// swap chevron
$(this).children('span').toggleClass('glyphicon-chevron-down glyphicon-chevron-up');
});
Bootply

Related

Nav bar accordion link not working

I have a nav bar that contains another page of my site, the page listed in the nav bar has a drop down list that is going to be linked to an accordion on the specific page. I'm having trouble implementing it, that if one of the drop down list items is click, then you will be taken to the page and the particular accordion linked to the item will be open.
For testing purposes I only have the nav bar list item "Monitoring" accordion linked right now; when I click "Monitoring" it takes me to the right page, but the accordion is still closed.
Here's my nav bar:
<nav class="navbar navbar-inverse navbar-fixed-top" style="background-color: #6F9824; text-align:center ">
<div class="navbar-header" align="center">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" style="color:white;" align="center"></a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav" style="color:white;" align="center">
<li>
<a asp-page="/Index" style="color:white;">Home</a>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" style="color:white;">
Centrify
<span class="caret"></span>
<ul class="dropdown-menu">
<li>Centrify Home</li>
<li>Monitoring</li>
<li>Patching</li>
<li>Onboarding</li>
<li>Disaster Recovery</li>
<li>Reporting</li>
</ul>
</li>
</div>
</nav>
Accordion I'm trying to open:
<div id="Accordion1" role="tablist" aria-multiselectable="true">
<div class="card">
<div class="card-header" role="tab" id="2">
<h5 class="mb-0">
<a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
Vault Status
</a>
</h5>
</div>
<div id="collapseTwo" class="collapse" role="tabpanel" aria-labelledby="2">
<div class="card-block">
<div class="form-group">
<label for="exampleFormControlSelect2">Select Environment</label>
<select multiple class="form-control" id="exampleFormControlSelect2">
<option>RTP</option>
<option>OMA</option>
<option>BGI</option>
<option>BG2</option>
<option>CLD</option>
<option>WRKSTN</option>
<option>QA</option>
</select><br />
<button>Submit</button>
</div>
</div>
</div>
</div>
JavaScript:
$(function() {
$("#Accordion1").accordion();
});
function getParam(name) {
var query = location.search.substring(1);
if (query.length) {
var parts = query.split('&');
for (var i = 0; i < parts.length; i++) {
var pos = parts[i].indexOf('=');
if (parts[i].substring(0, pos) == name) {
return parts[i].substring(pos + 1);
}
}
}
return 0;
}
$(function() {
var defaultPanel = parseInt(getParam('panel'));
$("#Accordion1").accordion({
active: defaultPanel
});
});
I don't know if that's what's causing the problem, but the end of you'r <ul> and first <li> is missing on you'r first HTML code
How do you expect your accordion to work if there are no headers? According to jQuery UI documentation, your HTML should look something like
<div id="accordion">
<h3>First header</h3>
<div>First content panel</div>
<h3>Second header</h3>
<div>Second content panel</div>
</div>
but it does not. You need pairs header-content in order for it to work.

JavaScript Event for Capturing Dynamically Generated Non-Children Elements

I need to be able to get access to an element that will be available via AJAX after several click events. I cannot simply use $(element).on('click', selector, event) because the element I need access to is not a child element.
For example, what appears on initial page load is this:
<ol class="opc" id="checkoutSteps">
<li id="opc-billing" class="section opc-step"
data-step-number="0">
<div class="step-title" data-href="#step-1">
<span class="number">1</span>
<h2>Billing Information</h2>
<a onclick="stepTo('#step-2'); return false;"
href="#step-2">
View </a>
<a data-toggle="collapse" data-parent="#step-all"></a>
</div>
<div id="billing-step-login" class="step a-item">
<div id="step-2"
class="panel-collapse collapse in">
<div class="panel-body">
</div>
</div>
</div>
</li>
<li id="opc-shipping" class="section opc-step"
data-step-number="1">
<div class="step-title" data-href="#step-2">
<span class="number">2</span>
<h2>Shipping Information</h2>
<a onclick="stepTo('#step-3'); return false;"
href="#step-3">
Edit </a>
<a data-toggle="collapse" data-parent="#step-all"></a>
</div>
<div id="shipping-step-login" class="step a-item">
<div id="step-3"
class="panel-collapse collapse ">
<div class="panel-body">
<button class="button btn-next" type="submit"><span><span>Continue</span></span></button>
</div>
</div>
</div>
</li>
<li id="opc-shipping_method" class="section opc-step"
data-step-number="2">
<div class="step-title" data-href="#step-3">
<span class="number">3</span>
<h2>Shipping Method</h2>
<a onclick="stepTo('#step-4'); return false;"
href="#step-4">
Edit </a>
<a data-toggle="collapse" data-parent="#step-all"></a>
</div>
<div id="shipping_method-step-login" class="step a-item">
<div id="step-4"
class="panel-collapse collapse ">
<div class="panel-body">
</div>
</div>
</div>
</li>
<li id="opc-payment" class="section opc-step"
data-step-number="3">
<div class="step-title" data-href="#step-4">
<span class="number">4</span>
<h2>Payment Method</h2>
<a onclick="stepTo('#step-5'); return false;"
href="#step-5">
Edit </a>
<a data-toggle="collapse" data-parent="#step-all"></a>
</div>
<div id="payment-step-login" class="step a-item">
<div id="step-5"
class="panel-collapse collapse ">
<div class="panel-body">
</div>
</div>
</div>
</li>
<li id="opc-review" class="section">
<div class="step-title" data-href="#step-6">
<span class="number">5</span>
<h2>Order Review</h2>
Edit
<a data-toggle="collapse" data-parent="#step-all"></a>
</div>
<div id="review-step-login" class="step a-item">
<div id="step-6" class="panel-collapse collapse">
<div class="panel-body"></div>
</div>
</div>
</li>
</ol>
Once I click the button inside div.#step-3, some content with a button loads in div.#step-4. After clicking the button in that div, a button loads in #step-5. Finally, after clicking on the button inside #step-5, there is content (textarea and another button) loaded in #step-6 that I'm interested in.
How do I go about writing a jQuery or JavaScript event that would allow me to get access to the div.#step-6 textarea? Can I write several nested $(element).on() events?
P.S. I don't have access to change any of the existing HTML, CSS, or JavaScript files. I can only write new JavaScript.
It seems that you can bind the delegated event to a common static ancestor.
For example, #checkOutSteps:
jQuery('#checkOutSteps').on('focus','div.#step-6 textarea',function(){
...
});
Event delegation allows us to attach a single event listener, to a parent element, that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future. --Event Delegation

How to change icon in Bootstrap collapse for multiple requirments

I have used Bootstrap collapse for three different div for different requirments.
First Collapse div : I need to change "glypicon-left and bottom icon" of "showing text and hide".
<div class="col-md-12">
<span class="badge">
<span>0</span>
</span>
<span> Function</span>
<a data-toggle="collapse" data-parent="#accordion" href="#collapse1" class="fb_down_arrow">
<span class="glyphicon glyphicon-triangle-bottom"></span>
</a>
</div>
<ul class="fb_list_option collapse in" id="collapse1">
<li>
<input type="checkbox" id="c5" name="cc">
<label for="c5"><span></span>Corporate Real Estate</label>
</li>
</ul>
Second Collapse div : I need to change "glypicon-plus and minus" icon of "showing text and hide".
<li>
<input type="checkbox" id="c92" name="cc">
<label for="c92"><span></span>Construction (###)</label>
<a href="" data-toggle="collapse" data-target="#fb_plus_one" class="" >
<span class="glyphicon glyphicon-plus fb_list_plus_arrow"></span>
</a>
<ul id="fb_plus_one" class="collapse in" aria-expanded="true">
<li>
<input type="checkbox" id="c01" name="cc">
<label for="c01"><span></span>Child 1</label>
</li>
</ul>
</li>
Third Collapse div : I need to change "glypicon-left and bottom icon" and also change Text of "show more" , "less more" of showing text and hide.
See more detail <span class="glyphicon KB_glyphicon glyphicon-triangle-left"></span>
<div class="row collapse in" id="demo1" aria-expanded="true">
</div>
Script:
I am using below script archiving first collapse div requirement.kindly advise how to to archive second & third collapse.
// Collapse Start
$('.collapse').on('shown.bs.collapse', function(){
$(this).parent().find(".glyphicon-triangle-left")
.removeClass("glyphicon-triangle-left")
.addClass("glyphicon-triangle-bottom");
}).on('hidden.bs.collapse', function(){
$(this).parent().find(".glyphicon-triangle-bottom")
.removeClass("glyphicon-triangle-bottom")
.addClass("glyphicon-triangle-left");
});
// Collapse End
Please try this
$('.collapse').on('shown.bs.collapse', function(){
e.stopImmediatePropagation()
$(this).parent().find(".glyphicon-triangle-left").first().removeClass("glyphicon-triangle-left").addClass("glyphicon-triangle-bottom");
}).on('hidden.bs.collapse', function(){
e.stopImmediatePropagation()
$(this).parent().find(".glyphicon-triangle-bottom").first().removeClass("glyphicon-triangle-bottom").addClass("glyphicon-triangle-left");
});

add CSS element using an angular directive

Im using angular and ng-repeat to populate a list of studies. This list is dynamic so you can toggle into child elements of each element. So basically I have a accordion style toggle list that can go three levels deep on each list item. I have a jQuery issue that I think should be solved with some angular directive or something. Basically I have an arrow (glyphicon) that should switch to up or down depending on if your looking at a child or a parent element in this list. I have this working with pure jQuery just adding and removing a css class from each list item. However, it only works on the first item in the list because ng-repeat creates multiple id’s but jQuery will only work on the first element with that id tag.
This is the HTML from the page.
<!-- User Studies List -->
<div ng-controller="StudiesController" id="before">
<h3 class="center"> User Studies </h3>
<div ng-repeat="study in studies" arrow>
<div class="panel-group" style="margin-bottom:0">
<div class="panel panel-default">
<div class="panel-heading" data-toggle="collapse" href="#collapse{{$index}}">
<h3 class="panel-title">{{ study.study }} <span class="glyphicon glyphicon-menu-down pull-right"></span></h3>
<p></p>
</div>
<div id="collapse{{$index}}" class="panel-collapse collapse">
<ul class="list-group">
<li class="list-group-item" data-toggle="collapse" href="#collapse{{study.id}}" style="margin-left:1%" id="sampleID{{$index}}">
<i>Sample: </i>{{ study.sample }}
<span id="glyph-switch" class="glyphicon glyphicon-menu-down pull-right"></span>
<span id="glyph-up" class="glyphicon glyphicon-menu-up pull-right"></span>
</li>
<div id="collapse{{study.id}}" class="panel-collapse collapse">
<ul class="list-group">
<li class="list-group-item" style="margin-left:3%"><i>Fastq: </i>{{ study.fastq }}
<div class="dropdown center pull-right">
<button class="btn-xs btn-default hvr-shadow" id="dLabel" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Action <span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dLabel">
<li id="list-item" data-toggle="modal" data-target="#more-metadata-modal" ng-click="showMore(study)">More Data</li>
<li id="list-item" data-toggle="modal" data-target="#edit-metadata-modal" ng-click="showMore(study)">Edit</li>
<li id="list-item" data-toggle="modal" data-target="#delete-metadata-modal" ng-click="showMore(study)">Delete</li>
</ul>
</div>
</li>
</ul>
</div>
</ul>
</div>
</div>
</div>
</div>
</div>
This is the Javascript
var count = 1;
$(document).on("click", "li[id*='sampleID']", function() {
console.log("clicked");
if(count > 0) {
$('#glyph-switch').css('visibility','hidden');
$('#glyph-up').css('visibility', 'visible');
count -= 1;
console.log("count", count);
} else {
$('#glyph-switch').css('visibility','visible');
$('#glyph-up').css('visibility', 'hidden');
count += 1;
console.log("count",count);
}
});
I would just use angular code (no jQuery at all).
Since you already have an object of studies, just handle an onClick="showGlyph($index)" passing the index and then in the code just set the a state for the up/down arrow $scope.GlyphUp = !$scope.GlyphUp.
In the template file have the up/down arrow object bind ng-show="GlyphUp"

Bootstrap Collapse doesn't toggle after you show, hide or toggle from code

My HTML is:
<div id="accordion-container">
<div class="accordion" id="navaccordion">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#navaccordion" href="#collapseMenu">
<strong>My Menus</strong>
</a>
</div>
<div id="collapseMenu" class="accordion-body collapse in">
<div class="accordion-inner">
<div class="navigation" id="navigationcontainer">
<span id="menutree">
MenuTree
</span>
</div>
</div>
</div>
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#navaccordion" href="#collapseQuickLinks">
<strong>Quick Links</strong>
</a>
</div>
<div id="collapseQuickLinks" class="accordion-body collapse">
<div class="accordion-inner">
<div class="quicklinks" id="quicklinkscontainer">
<span id="quicklinkslist">
QuickLinks
</span>
</div>
</div>
</div>
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#navaccordion" href="#collapseQueue">
<strong>Queue</strong>
</a>
</div>
<div id="collapseQueue" class="accordion-body collapse">
<div class="accordion-inner">
<div class="queue" id="queuecontainer">
<span id="queuetree">
Queue
</span>
</div>
</div>
</div>
</div>
</div>
</div>
My example is here: http://jsfiddle.net/pdavis68/Xut4C/2/
If you remove the JavaScript code, you'll notice that the toggling of the collapse operates properly. If you click "Quick Links", "My Menus" closes and "Quick Links" opens.
If you leave the JS in, you'll notice that opening "My Menus" or "Quick Links" doesn't cause anything else to collapse, but if you open "Queue", it will still cause the others to collapse.
It doesn't seem to matter if I use "toggle", "show" or "hide" command in the collapse, it will break the toggling functionality.
Also, in the example, what ought to happen (by my reckoning, at least) is that that "My Menus" should toggle closed (which it does) and then "Quick Links" ought to toggle open (which it does NOT do.)
So, 2 questions:
How do I programmatically show/hide groups without breaking the toggle functionality?
How do I toggle things open?
1.Try to use collapse() with options, the 'parent' is important
$("#collapseMenu").collapse({"toggle": true, 'parent': '#navaccordion'});
$("#collapseQuickLinks").collapse({"toggle": true, 'parent': '#navaccordion' });
Fiddle: http://jsfiddle.net/hieuh25/Xut4C/6/
2.Basically you have 2 ways:
Add class in to that div, e.g: <div id="collapseMenu" class="accordion-body collapse in"> cause that div to open.
Use collapse() with option 'toggle': true as above, when the div is closed.
Hope it helps.
Try activating your content as a collapsible element first. I skimmed over this part when reading the documentation and it really stumped me.
$('#myCollapsible').collapse({
toggle: false
})
After you activate it you can hide and show it as usual.
$('#myCollapsible').collapse('hide');
$('#myCollapsible').collapse('show');
http://getbootstrap.com/javascript/#collapse-methods
You also can add data-parent="#navaccordion" to <div id="collapseMenu" class="accordion-body collapse" data-parent="#navaccordion"> and call without addional key 'parent' like .collapse({"toggle": true});

Categories

Resources