Bootstrap collapse within a foreach loop - javascript

I am having trouble getting the collapsible panels to work within my foreach loop. When an item is clicked, all of the items expand/retract, which isn't what I want. I want each element to be independent.
I am connected to a database and basically want to display the data simply and be able to expand to see more information.
I've tried lots of different solutions, my current method is based off https://stackoverflow.com/a/18568997/1366033
What should I do about the id and href?
Any help would be greatly appreciated.
foreach (var item in groupItem){
<div class="panel-group" id="accordion">
<div class="panel panel-default" id="panel1">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-target="#collapseOne"
href="#collapseOne">
#Html.DisplayFor(modelItem => item.Name)
</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse in">
<div class="panel-body">#Html.DisplayFor(modelItem => item.IdNumber)
</div>
</div>
</div>
</div>

Basically you are creating panel with loop and assigning the same id to all the panel-group and that's what causing the problem here! So you can try working as below and please note ids should be unique in DOM
#{int i=0;}
foreach (var item in groupItem)
{
<div class="panel-group" id="accordion_#i">
<div class="panel panel-default" id="panel_#i">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-target="#collapseOne_#i" href="#collapseOne_#i">
#Html.DisplayFor(modelItem => item.Name)
</a>
</h4>
</div>
<div id="collapseOne_#i" class="panel-collapse collapse in">
<div class="panel-body">
#Html.DisplayFor(modelItem => item.IdNumber)
</div>
</div>
</div>
</div>
i++;
}

Related

Pass text to panel with toggle

When I click the link of the panel, I would like to have text passed to the panel body. I have placed the onClick in each of the panel tags including the tag. The onClick calls myFunction, which is supposed to send text to the body of the panel. That is not happening. Any suggestions?
function myFunction() {
document.getElementId("panel-body").innerHTML = "it worked"
};
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" href="#collapse1" onClick="myFunction">Name</a>
</h4>
</div>
<div id="collapse1" class="panel-collapse collapse">
<div class="panel-body"></div>
</div>
</div>
</div>
You have to call the function with (): onClick="myFunction()"
The selector you tried to use would be .getElementById(), but in this case you want a more specific element. So the the css-selector would be #collapse1 > .panel-body which selects the elements with class panel-body which are direct children of #collapse1.
querySelector() selects the first element which fulfills the given css selector, querySelectorAll() would return all of them in an array-like structor NodeList.
function myFunction() {
document.querySelector("#collapse1 > .panel-body").innerHTML = "it worked"
};
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" href="#collapse1" onClick="myFunction()">Name</a>
</h4>
</div>
<div id="collapse1" class="panel-collapse collapse">
<div class="panel-body"></div>
</div>
</div>
</div>

Bootstrap collapse panel keeping a div open after a submit

I have an accordion div (panel-collapse), at the end of the panel I have a submit button, initially, all the panel div are closed, I want to keep the state of the div the same after the submit reload.
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" href="#collapse1">Collapsible panel</a>
</h4>
</div>
<div id="collapse1" class="panel-collapse collapse">
<div class="panel-body">Panel Body</div>
<div class="panel-footer">Panel Footer</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" href="#collapse2">Collapsible panel</a>
</h4>
</div>
<div id="collapse2" class="panel-collapse collapse">
<div class="panel-body">Panel Body</div>
<div class="panel-footer">Panel Footer</div>
</div>
</div>
</div>
On a regular form submit the page gets reloaded and resets everything, but if you submit the form Asynchronously using ajax nothing will change on your page. Using php + jQuery, you could do something like this:
$(document).on("click","#submitButton",function(e) {
e.preventDefault();
var formData = $("#formID").serialize();
$.post("your_php_file.php",formData,function(response) {
console.log(response);
});
});
Only way to preserve setting without async requests is using cookies.
You can set them via Javascript:
(http://www.w3schools.com/js/js_cookies.asp)
Probably like assigning an array of active collapse panels
var active_panels=[0,1,2];
$.cookie('active_panels', JSON.stringify(active_panels))
Without jQuery see W3C specification

Show/hide element using jQuery

I am trying to add/remove a class of an element by clicking on a header. The problem I am facing is that the div I am targeting to show does not have an unique class, no ID and is on the same level as the header I am clicking on:
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" href="#text-background" data-parent="#settings-accordeon" class="collapsed">achtergrond</a>
</h4>
</div>
<div id="text-background" class="panel-collapse collapse">
~~ Something in in it.
</div>
</div>
I have 4 of these divs below each other.
I am trying to find the right selector in jQuery to be able to do the following:
Click on div with class: "panel-heading"
Select the div with the class: "panel-collapse collapse"
Add a class to this div called: "in"
This is what I got so far:
$('.panel-heading').click(function() {
$('.panel-collapse').addClass('in');
});
But because I have multiple div's with this class, it opens them all...
Now you can try to this
$('.panel-heading').click(function() {
$('.panel-collapse').removeClass('in');
$(this).next('.panel-collapse').addClass('in');
});
Demo
$(document).ready(function(){
$('.panel-heading').click(function() {
$('.panel-collapse').removeClass('in');
$(this).next('.panel-collapse').addClass('in');
});
});
.in{background:red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" href="#text-background" data-parent="#settings-accordeon" class="collapsed">achtergrond</a>
</h4>
</div>
<div id="text-background" class="panel-collapse collapse">
~~ Something in in it.
</div>
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" href="#text-background" data-parent="#settings-accordeon" class="collapsed">achtergrond</a>
</h4>
</div>
<div id="text-background" class="panel-collapse collapse">
~~ Something in in it.
</div>
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" href="#text-background" data-parent="#settings-accordeon" class="collapsed">achtergrond</a>
</h4>
</div>
<div id="text-background" class="panel-collapse collapse">
~~ Something in in it.
</div>
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" href="#text-background" data-parent="#settings-accordeon" class="collapsed">achtergrond</a>
</h4>
</div>
<div id="text-background" class="panel-collapse collapse">
~~ Something in in it.
</div>
</div>
This will help
$('.panel-collapse.collapse').addClass('in');
This will only select the element which have both panel-collapse and collapse class .
Can you try:
$('.panel-heading').click(function() {
$(this).closest('.panel-collapse').addClass('in');
});
You can use this to refer current selector
jQuery
$('.panel-heading').click(function() {
$(this).siblings('.panel-collapse.collapse').addClass('in');
});
In order to select an element at the same level, you can use .next() function like this:
$('.panel-heading').on('click', function() {
$(this).next('.panel-collapse.collapse').addClass('in');
});
.in {
padding:10px;
border: 2px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" href="#text-background" data-parent="#settings-accordeon" class="collapsed">achtergrond</a>
</h4>
</div>
<div id="text-background" class="panel-collapse collapse">
~~ Something in in it.
</div>
</div>
You can use next since the div of class panel-collapse collapse is a direct sibling to the panel-heading div, also use toggleClass which is better in your case:
$('.panel-heading').click(function() {
$(this).next('div').toggleClass('in');
});
You can use this selector instead
$('.panel .panel-collapse:first-child').addClass('in');
Or
$('.panel-heading').next('.panel-collapse').addClass('in);
You can change your code to apply to the immediate sibling of .panel-heading only as such:
$('.panel-heading').click(function() {
$(this).siblings('.panel-collapse').addClass('in');
});
Note the usage of this with refers to the element that raised the event (i.e. click event).
Basically you just need to find the current elements next sibling and add a class to it:
$('.panel-heading').click(function() {
$(this).next().addClass('in');
});
That will work if the panel-collapse is always after you panel-heading, else to be safe, you can do:
$('.panel-heading').click(function() {
$(this).next(".panel-collapse").addClass('in');
});
Use the reference of the clicked div and try this code :-
$('.panel-heading').click(function() {
$(this).next('.panel-collapse').addClass('in');
});
Hope this will work with your case.

bootstrap accordion icon change in click

I am using bootstrap accordion in my code. On click on every list I will display Data and Icon will change.
<i class="fa fa-plus-square"></i>
will change to
<i class="fa fa-minus-square"></i>
My code:-
<div class="priority-lists">
<div class="panel-group" id="accordion">
<div class="panel panel-default">
<div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#waterMindDistrictMeteres">
<h2 class="panel-title accordion-toggle">
<i class="fa fa-minus-square"></i>
WaterMind District Meters
</h2>
</div>
<div id="waterMindDistrictMeteres" class="panel-collapse collapse">
<div class="panel-body">
<div class="row">
<div id="servicePointsGrid" watermind-priority-lists kendo-grid k-options="watermindDetailGridOptions" k-rebind="watermindDetailGridOptions"></div>
</div>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#waterMindPressurePoints">
<h2 class="panel-title accordion-toggle">
<i class="fa fa-minus-square"></i>
WaterMind Pressure Points
</h2>
</div>
<div id="waterMindPressurePoints" class="panel-collapse collapse">
<div class="panel-body">
<div class="row">
<div id="servicePointsGrid" watermind-priority-lists kendo-grid k-options="watermindDetailGridOptions" k-rebind="watermindDetailGridOptions"></div>
</div>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#waterMindServicePoints">
<h2 class="panel-title accordion-toggle">
<i class="fa fa-minus-square"></i>
WaterMind Service Points
</h2>
</div>
<div id="waterMindServicePoints" class="panel-collapse collapse in">
<div class="panel-body">
<div class="row">
<div id="servicePointsGrid" watermind-priority-lists kendo-grid k-options="watermindDetailGridOptions" k-rebind="watermindDetailGridOptions"></div>
</div>
</div>
</div>
</div>
</div>
</div>
I tried to use some code:
My jsFiddle code
I will see icon are not working properly. I am looking for solution in CSS or JavaScript or jQuery.
You have to add .collapsed to your panel-headings! The first time .collapsed is not on that element, but bootstrap updated it on a click.
It does work fine by me now.
Updated fiddle
Please check on this link
Js Fiddle
You must add a class "collapsed" next to "panel-heading". your problem will be solved
You should init your icons with : fa-plus-square, not fa-minus-square.

Angularjs UI collapse in ngRepeat

I am trying to embed some collapsible panels in a ngRepeat.
This is what I have:
<div class="panel panel-default" ng-repeat="element in elements">
<div class="panel-heading">
{{element.name}}
<button value="Collapse" ng-click="element.isCollapsed != element.isCollapsed"></button>
</div>
<div class="panel-body" collapse="element.isCollapsed">
Content
</div>
</div>
Now, when I click on the button, the collapse doesn't work.
From the documentation I understand that the repeater creates a scope for every element.
And the attribute collapse of the panel-body should get the same scope, right?
It seems that the scope.$watch in the collapse directive is not working properly.
Please check the updated fiddle: http://jsfiddle.net/nZ9Nx/9/
I have created the app and injected ui-bootstrap in it to have the collapse working.
angular.module('test', ['ui.bootstrap']);
The problem is
<div class="panel-heading" toggle target="collapseOne">
It's hardcoded in the example. Replace with...
<div class="panel-heading" toggle target="collapse{{ $index + 1 }}">
Also update this tag
<div id="collapse{{ $index + 1 }}" toggleable active-class="in" exclusion-group="accordion1" default="active" class="panel-collapse collapse">
Here is a full example
<div ng-repeat="item in awesomeThings">
<div class="panel panel-default">
<div class="panel-heading" toggle target="collapse{{ $index + 1 }}">
<h4 class="panel-title">
{{ item }}
</h4>
</div>
<div id="collapse{{ $index + 1 }}" toggleable active-class="in" exclusion-group="accordion1" default="active" class="panel-collapse collapse">
<div class="panel-body">
<!-- ... -->
</div>
</div>
</div>
</div>

Categories

Resources