bootstrap collapse in ng-repeat - javascript

i'm trying to make sure that each time when new collapse is create it will open only the one that were chosen. right now it just open all when click and close all at the same time
<div ng-repeat = "i in ticket_array">
<div ng-repeat="j in getNumber(i) track by $index">
div class="panel-group" ng-click="expand()">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" >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>
$scope.expand = function(){
$(".collapse").collapse('toggle');
};
$scope.getNumber = function(num) {
console.log(num);
return new Array(parseInt(num.quantity));
};
it create an 3 new collapse but i don know how to make sure it only open the were chosen.
i have try using index it but did not work since my array consist of two object that has the same index
this is my array
[{"type":"men junior", "quantity":"3"},{"type":"men senior", "quantity":"3"}]

Using pure Js to change HTML behaviour into an angular Project is never a good idea.
Have a look at this project for an angular implementation of your collapse : http://embed.plnkr.co/tcTZlA/
The idea is to have a variable that stores a boolean to activate or not your accordeon menu.
In your case ; I'd change your code with :
<div ng-repeat = "i in ticket_array">
<div ng-repeat="j in getNumber(i) track by $index">
<div class="panel-group" ng-click="j.active = !j.active" ng-class="{'expandcollapse-heading-collapsed': j.active, 'expandcollapse-heading-expanded': !j.active}"> // CODE EDITED HERE WITH A NEW VARIABLE
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" >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>
And of course adding some CSS for the transition :
.expandcollapse-item {
overflow: hidden;
border-top:1px solid blue;
}
.expandcollapse-heading-collapsed {
cursor: pointer;
padding: 15px 20px;
position: relative;
z-index: 100000000;
color: black;
background-color: white;
}
.expandcollapse-item:first-of-type {
border-top:0px;
}
.expandcollapse-heading-collapsed h4{
font-size: 16px;
font-weight: normal;
margin:0px;
}

So in this you can make use of $event to add target and specify the inner collapse class. $event will trace the event where it is called like this in javascript. and you can take this event to handle manipulation in your function.
<div ng-repeat = "i in ticket_array">
<div ng-repeat="j in getNumber(i) track by $index">
<div class="panel-group" ng-click="expand($event)">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" >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>
$scope.expand = function($event){
$($event.target).find('.collapse').collapse('toggle');
};
updated solution:
$scope.expand = function($event){
if($($event.target).find('.collapse').hasClass('in')){
$($event.target).find('.collapse').removeClass('in')
}else{
$($event.target).find('.collapse').addClass('in')
}
};

Related

Access Div Based on Another in JQUERY

How do I access the <a ....>General</a> base on this div I'm getting below on "test"?
test
<div
role="tabpanel"
class="panel-collapse collapse"
id="collapseGeneral"
aria-labelledby="collapseGeneral"
style="height: auto"
>
<div class="panel-body">
...
</div>
</div>
GIVEN
<div class="panel panel-default">
<div role="tab" class="acc-heading" id="headingGeneral">
<a
data-toggle="collapse"
role="button"
aria-expanded="false"
data-parent="#accordion"
class=""
href="#collapseGeneral"
aria-controls="collapseGeneral"
>General</a
>
</div>
<div
role="tabpanel"
class="panel-collapse collapse"
id="collapseGeneral"
aria-labelledby="collapseGeneral"
style="height: auto"
>
<div class="panel-body">
...
</div>
</div>
</div>
code
console.log(jQuery(test).parent(), "parent");
Looks like you want to find the matching aria-controls element for your <div>
Try this
// Find the matching aria-control
const control = $(`a[aria-controls="${test.id}"]`);
// Add the "collapsed" class
control.addClass("collapsed");
You could also match it by href but it wasn't exactly clear what your selection criteria was
const control = $(`a[href="#${test.id}"]`);
Here's a runnable demo...
// You don't need to redefine `test`,
// this is just emulating the variable in your question
// to make my answer runnable.
// IGNORE THIS LINE
const test = document.querySelector("#collapseGeneral");
// Find the matching aria-control
const control = $(`a[aria-controls="${test.id}"]`);
// now do something with `control`...
control.addClass("collapsed");
.collapsed { color: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.slim.min.js"></script>
<!-- minified HTML -->
<div class="panel panel-default"> <div role="tab" class="acc-heading" id="headingGeneral"> <a data-toggle="collapse" role="button" aria-expanded="false" data-parent="#accordion" class="" href="#collapseGeneral" aria-controls="collapseGeneral" >General</a > </div><div role="tabpanel" class="panel-collapse collapse" id="collapseGeneral" aria-labelledby="collapseGeneral" style="height: auto" > <div class="panel-body"> ... </div></div></div>

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>

ng-click + ng-repeat and try to change panel style

I'm trying to make a click event to change my element style.
I'm using Bootstrap and Angular.
This is the panel, It does show all the groups I have in DB as it should.
<div class="col-sm-6 panel-group panel-hover panel-click" ng-repeat="y in allGroups " id="panel-{{$index}}"" ng-click="showGroupsMembersList(y.GroupId)">
<div class="panel panel-default" >
<div class="panel-heading">
<h4 class="panel-title">
<p><bold>{{y.GroupName}}</bold></p>
</h4>
</div>
<div class="panel">
<div class="panel-body">Group Code: <div class="text-info"> {{y.GroupeCode}}</div></div>
<!-- <div class="panel-footer">Panel Footer</div> -->
</div>
</div>
</div>
And after clicking on it, I do get a few of all the group members as it should.
But how can I change the group style?
I tryed panel-click:
.panel-click:active{
padding: 20px;
box-shadow: 0 0 14px 5px #31b0d5;
}
But I guess I don't understand css functions...
Also tried to get element by ID, but every time I send ID to ng-click function the function get stuck and don't work...
Please help!
you can use
ng-click="y.customVariable=!y.customVariable" ng-class="{'active':y.customVariable}"
like;
<div class="col-sm-6 panel-group panel-hover" ng-repeat="y in allGroups" ng-click="y.customVariable=!y.customVariable" ng-class="{'active':y.customVariable}">
<div class="panel panel-default" >
<div class="panel-heading">
<h4 class="panel-title">
<p><bold>{{y.GroupName}}</bold></p>
</h4>
</div>
<div class="panel">
<div class="panel-body">Group Code: <div class="text-info"> {{y.GroupeCode}}</div></div>
<!-- <div class="panel-footer">Panel Footer</div> -->
</div>
</div>
</div>
and then you can use "active" class
.active{/* do something */}
<div class="col-sm-6 panel-group" ng-repeat="y in allGroups " id="panel-{{$index}}"" ng-click="showGroupsMembersList(y.GroupId)">
<div class="panel panel-default" ng-class="{'active-panel': y.id == selectedPanel}">
<div class="panel-heading">
<h4 class="panel-title">
<p><bold>{{y.GroupName}}</bold></p>
</h4>
</div>
<div class="panel">
<div class="panel-body">Group Code: <div class="text-info"> {{y.GroupeCode}}</div></div>
<!-- <div class="panel-footer">Panel Footer</div> -->
</div>
</div>
</div>
you can add in your controller something like that :
function showGroupsMembersList(id){
// your code
// and then add
$scope.selectedPanel = id;
}
in your css now
.active-panel{
padding: 20px !important;
box-shadow: 0 0 14px 5px #31b0d5 !important;
}
Use ng-class. Suppose you want to change the background color of the panel based on click.
In your html: add ng-class active, and ng-click function: setSelectedY
<div class="col-sm-6 panel-group panel-hover panel-click" ng-repeat="y in allGroups" ng-click="showGroupsMembersList(y.GroupId); setSelectedY(y._id)" ng-class="{active: y._id === idSelectedY}">
Rest of your code here<
/div>
In your controller,
// set default selected Y to null
$scope.idSelectedY = null;
// switch selected Y to active element
$scope.setSelectedY = function (idSelectedY) {
$scope.idSelectedY = idSelectedY;
};
In your css file
.active {background-color: #ccc}
These code lines should work!

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.

Categories

Resources