Angularjs accordion ng-click on panel-header - angularjs

In AngularJS UI Bootstrap I want to activate isopen when panel-heading is clicked, but I couldn't find a way.
In this version is activated only if you click the link.
Here's what I tried;
<accordion-group is-open="isopen">
<accordion-heading ng-click="isopen=!isopen">
I can have markup, too!
<i class="pull-right glyphicon"
ng-class="{'glyphicon-chevron-down': isopen, 'glyphicon-chevron-right': !isopen}"></i>
</accordion-heading>
This is just some content to illustrate fancy headings.
</accordion-group>
ng-click="isopen=!isopen"
This is the link I tried on Plunker
AngularJS UI Bootstrap
Thanks in advance..

EDIT:
A better solution is to move ng-click="isopen=!isopen" to the accordion-group element. This way the panel is opened/closed clicking anywhere on the panel-heading, including the edges.
<accordion close-others="oneAtATime">
<accordion-group is-open="isopen" ng-click="isopen=!isopen">
<accordion-heading >
I can have markup, too!
<i class="pull-right glyphicon"
ng-class="{'glyphicon- chevron-down': isopen, 'glyphicon-chevron-right': !isopen}">
</i>
</accordion-heading>
This is just some content to illustrate fancy headings.
</accordion-group>
</accordion>
END EDIT
enclose the content of <accordion-heading> in a <div>
<accordion close-others="oneAtATime">
<accordion-group is-open="isopen" >
<accordion-heading ng-click="isopen=!isopen">
<div>
I can have markup, too!
<i class="pull-right glyphicon"
ng-class="{'glyphicon- chevron-down': isopen, 'glyphicon-chevron-right': !isopen}">
</i>
</div>
</accordion-heading>
This is just some content to illustrate fancy headings.
</accordion-group>
</accordion>

A very simple CSS-based solution:
.panel-heading {
padding: 0;
}
.panel-title a {
display: block;
padding: 10px 15px;
}
I'm not using complex headings though - just the heading attribute as shown below, so I haven't tested it with the examples above.
<uib-accordion-group heading="Details" class="form-horizontal" is-open="true">

What you need to do is change the accordion-group.html template such that it makes the header take the ng-click event.
<div class="panel {{panelClass || 'panel-default'}}">
<div class="abc panel-heading" ng-keypress="toggleOpen($event)" ng-click="toggleOpen($event)" >
<h4 class="panel-title">
<a href tabindex="0" class="accordion-toggle" accordion-transclude="heading"><span ng-class="{'text-muted': isDisabled}">{{heading}}</span></a>
</h4>
</div>
<div class="panel-collapse collapse" collapse="!isOpen">
<div class="panel-body" ng-transclude></div>
</div>
</div>
Then in your code specify it as the template-url for the accordion-group
<accordion-group heading="Dynamic Body Content" template-url="accordion-group.html">
Example:
http://plnkr.co/edit/EXUgyNi8hrqQbh5maJUx?p=preview

Related

How to change the style properties of uib-accordion-heading

The solution for the problem is already there/I have. But if I change the resource file version(inside head tag) from ui-bootstrap-tpls-2.5.0.js to ui-bootstrap-tpls-1.2.1.js, it is not working proper....Since I have done 90% work in ui-bootstrap-tpls-1.2.1.js, it is not possible to include ui-bootstrap-tpls-2.5.0.js for me(if I change these, other functions are not working).
1.Plunker demo which contains ui-bootstrap-tpls-2.5.0.js
2.Plunker demo which contains ui-bootstrap-tpls-1.2.1.js
Totally, I need to change the color/background-color of _uib-accordion-heading__ using ui-bootstrap-tpls-1.2.1.js, Can anyone help me pls....
HTML
<div ng-controller="AccordionDemoCtrl">
<script type="text/ng-template" id="group-template.html">
<div class="panel-heading" style="background-color:blue;">
<h4 class="panel-title" style="color:red;">
<a href tabindex="0" class="accordion-toggle" ng-click="toggleOpen()" uib-accordion-transclude="heading">
<span uib-accordion-header ng-class="{'text-muted': isDisabled}">
{{heading}}
</span>
</a>
</h4>
</div>
<div class="panel-collapse collapse" uib-collapse="!isOpen">
<div class="panel-body" style="text-align: right" ng-transclude></div>
</div>
</script>
<uib-accordion close-others="oneAtATime">
<div uib-accordion-group class="panel-default" heading="Static Header, initially expanded" is-open="status.isFirstOpen" is-disabled="status.isFirstDisabled">
This content is straight in the template.
</div>
<div uib-accordion-group class="panel-default" heading="{{group.title}}" ng-repeat="group in groups">
{{group.content}}
</div>
<div uib-accordion-group class="panel-default" heading="Dynamic Body Content">
<p>The body of the uib-accordion group grows to fit the contents</p>
<button type="button" class="btn btn-default btn-sm" ng-click="addItem()">Add Item</button>
<div ng-repeat="item in items">{{item}}</div>
</div>
<div uib-accordion-group class="panel-info" heading="Custom template" template-url="group-template.html">
Hello
</div>
<div uib-accordion-group class="panel-default" is-open="status.isCustomHeaderOpen" template-url="group-template.html">
<uib-accordion-heading>
Custom template with custom header template <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.isCustomHeaderOpen, 'glyphicon-chevron-right': !status.isCustomHeaderOpen}"></i>
</uib-accordion-heading>
World
</div>
</uib-accordion>
</div>
HTML
<div ng-controller="AccordionDemoCtrl">
<script type="text/ng-template" id="group-template.html">
<div class="panel-heading">
<h4 class="panel-title">
<a href tabindex="0" class="accordion-toggle" ng-click="toggleOpen()" uib-accordion-transclude="heading">
<span uib-accordion-header ng-class="{'text-muted': isDisabled}">
{{heading}}
</span>
</a>
</h4>
</div>
<div class="panel-collapse collapse" uib-collapse="!isOpen">
<div class="panel-body" style="text-align: right" ng-transclude></div>
</div>
</script>
<uib-accordion close-others="oneAtATime">
<div uib-accordion-group class="panel-default" heading="Static Header, initially expanded" is-open="status.isFirstOpen" is-disabled="status.isFirstDisabled">
This content is straight in the template.
</div>
<div uib-accordion-group class="panel-default" heading="{{group.title}}" ng-repeat="group in groups">
{{group.content}}
</div>
<div uib-accordion-group class="panel-default" heading="Dynamic Body Content">
<p>The body of the uib-accordion group grows to fit the contents</p>
<button type="button" class="btn btn-default btn-sm" ng-click="addItem()">Add Item</button>
<div ng-repeat="item in items">{{item}}</div>
</div>
<div uib-accordion-group class="panel-info" heading="Custom template" template-url="group-template.html">
Hello
</div>
<div uib-accordion-group class="panel-default" is-open="status.isCustomHeaderOpen" template-url="group-template.html">
<uib-accordion-heading>
Custom template with custom header template <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.isCustomHeaderOpen, 'glyphicon-chevron-right': !status.isCustomHeaderOpen}"></i>
</uib-accordion-heading>
World
</div>
</uib-accordion>
CSS
.panel-info .panel-heading {
background: blue;
color: red;
}
If you want to apply the custom-style for default then use the below css
.panel-default .panel-heading {
/* Css Properties */
}
You can overwrite the style generated by javascript file with this css rule to solve the problem.
.panel-default > .panel-heading {
color: #f00 !important;
background-color: #00f !important;
}

AngularJS nested accordions with ng-repeat

I have a 4 level model, for which I need to create nested accordions. However I cannot figure out why when I click on a Child, all of the sibbligs open (or close).
I'm using ui.bootstrap. Here's the code I'm using (the short versiĆ³n anyway):
<div ng-controller="ProgramasController as vm">
<accordion>
<accordion-group ng-repeat="programa in programas" is-open="status.open">
<accordion-heading>
<i class="fa fa-lg" ng-class="{'fa-minus-circle': status.open, 'fa-plus-circle': !status.open}"></i> {{programa.xrmName}}
</accordion-heading>
<accordion close-others="false">
<accordion-group ng-repeat="tipoDeAtencion in tiposDeAtencion" is-open="status.innerOpen">
<accordion-heading>
<i class="fa fa-lg" ng-class="{'fa-minus-circle': status.innerOpen, 'fa-plus-circle': !status.innerOpen}"></i> {{tipoDeAtencion.xrmName}}
</accordion-heading>
<div>
algo
</div>
</accordion-group>
</accordion>
</accordion-group>
</accordion>
</div>
Each programa in your programas is using the same status.open variable.
I think you want to switch to using an attribute of the programa itself like programa.open; note that you may want to initialize the field to false in each.
You will need to apply the same change for status.innerOpen and switch it to tipoDeAtencion.open.
You might want to use property from the iterating object to handle the open status as follows:
<div ng-controller="ProgramasController as vm">
<accordion>
<accordion-group ng-repeat="programa in programas" is-open="programa.open">
<accordion-heading>
<i class="fa fa-lg" ng-class="{'fa-minus-circle': programa.open, 'fa-plus-circle': !programa.open}"></i> {{programa.xrmName}}
</accordion-heading>
<accordion close-others="false">
<accordion-group ng-repeat="tipoDeAtencion in tiposDeAtencion" is-open="tipoDeAtencion.open">
<accordion-heading>
<i class="fa fa-lg" ng-class="{'fa-minus-circle': tipoDeAtencion.open, 'fa-plus-circle': !tipoDeAtencion.open}"></i> {{tipoDeAtencion.xrmName}}
</accordion-heading>
<div>
algo
</div>
</accordion-group>
</accordion>
</accordion-group>
</accordion>
So each level of accordion-group and its items open status will be unique.

UI-Bootstrap Accordion Directive not working

I downloaded the angularjs UI Bootstrap accordion directive found here: UI Bootstrap
However, I cannot get it to work and the <accordion> tag generates errors. I included the ['ui.bootstrap'] dependency in my angular module and I put references to files directly on page. Can anyone tell me what I am missing?
Here is my module:
var myApp = angular.module("dashboardManagement", ['ui.bootstrap'])
Here is my view:
#section scripts{
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/angular-animate.js"></script>
<script src="~/Scripts/app/app.js"></script>
<script src="~/Scripts/app/Contractor/contractorController.js"></script>
<script src="~/Scripts/app/Contractor/contractorService.js"></script>
<script src="~/Scripts/ui-bootstrap-custom-tpls-0.13.3.js"></script>
<script src="~/Scripts/app/Test/AccordionDemoCtrl.js"></script>
}
<h2>Index</h2>
<div ng-app="dashboardManagement">
<div>
<div>
<div ng-controller="AccordionDemoCtrl">
<p>
<button type="button" class="btn btn-default btn-sm" ng-click="status.open = !status.open">Toggle last panel</button>
<button type="button" class="btn btn-default btn-sm" ng-click="status.isFirstDisabled = ! status.isFirstDisabled">Enable / Disable first panel</button>
</p>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="oneAtATime">
Open only one at a time
</label>
</div>
<accordion close-others="oneAtATime">
<accordion-group heading="Static Header, initially expanded" is-open="status.isFirstOpen" is-disabled="status.isFirstDisabled">
This content is straight in the template.
</accordion-group>
<accordion-group heading="{{group.title}}" ng-repeat="group in groups">
{{group.content}}
</accordion-group>
<accordion-group heading="Dynamic Body Content">
<p>The body of the accordion group grows to fit the contents</p>
<button type="button" class="btn btn-default btn-sm" ng-click="addItem()">Add Item</button>
<div ng-repeat="item in items">{{item}}</div>
</accordion-group>
<accordion-group is-open="status.open">
<accordion-heading>
I can have markup, too! <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
</accordion-heading>
This is just some content to illustrate fancy headings.
</accordion-group>
</accordion>
</div>
</div>
`
there's a couple of different issues I can see here. First is, you are including both the minified and unminified versions of these resources, so you have the same code twice. So make sure to just include <script src="~/Scripts/ui-bootstrap-custom-tpls-0.13.3.js"></script> and remove the other three similar overlapping scripts. Are you also including Angular above these scripts? because that is a dependency and will throw errors if not included before
second, is the provided example code what you're actually using? Because of course just having this:
<accordion>
</accordion>
will not do very much. You have to provide content for this directive like:
<accordion>
<accordion-group heading="{{group.title}}" ng-repeat="group in groups">
{{group.content}}
</accordion-group>
</accordion>
Check out the plnkr demo for full working example code:
http://plnkr.co/edit/MlcqWL?p=preview
What I discovered is that the Accordion feature is not working as expected because my _Layout.cshtml has a nav-sidebar in it. If I comment out the navbar, the Accordion works as expected. I plan to post a "new" question regarding the found issue.

Toggling accordion panel icons with ng-class and ng-click

I have an accordion with "chevron" icons that are toggled to point up or down when clicked, this is done with ng-click and ng-class. The accordion only permits one panel to be open at the same time - so when I click on a panel that is closed, the panel that is open closes. But how do I toggle the chevron icon on the open panel that is getting closed with ng-click?
Originally i could do it with DOM manipulation etc, but since this is a partial view in angular I cannot do it.
Code:
<div class="panel-group" id="accordion">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseOne" ng-click="firstpaneisopen=!firstpaneisopen">
<i class="glyphicon" ng-class="{'glyphicon-chevron-up': firstpaneisopen, 'glyphicon-chevron-down': !firstpaneisopen}"></i> Collapsible Group Item #1
</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse in">
<div class="panel-body">
Body
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" ng-click="secondpaneisopen=!secondpaneisopen>
<i class="glyphicon" ng-class="{'glyphicon-chevron-up': secondpaneisopen, 'glyphicon-chevron-down': !secondpaneisopen}"></i> Collapsible Group Item #2
</a>
</h4>
</div>
<div id="collapseTwo" class="panel-collapse collapse">
<div class="panel-body">
Body
</div>
</div>
</div>
</div>
This is what I've tried and it seems to work
In my controller I have
$scope.menuStatus = [ { isOpen : true },
{ isOpen : false },
{ isOpen : false } ]
In my html I have
<accordion id='cntLeftMenu' close-others='false'>
<accordion-group is-open='menuStatus[0].isOpen'>
<accordion-heading class='menu-title'>
Cars <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': menuStatus[0].isOpen , 'glyphicon-chevron-right': !menuStatus[0].isOpen }"></i>
</accordion-heading>
<ul class='left-menu'>
<li><a href=''>test1</a></li>
<li><a href=''>test1</a></li>
<li><a href=''>test1</a></li>
</ul>
</accordion-group>
<accordion-group is-open='menuStatus[1].isOpen'>
<accordion-heading class='menu-title'>
Customers <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': menuStatus[1].isOpen , 'glyphicon-chevron-right': !menuStatus[1].isOpen }"></i>
</accordion-heading>
<ul class='left-menu'>
<li><a href=''>test1</a></li>
<li><a href=''>test1</a></li>
<li><a href=''>test1</a></li>
</ul>
</accordion-group>
<accordion-group is-open='menuStatus[2].isOpen'>
<accordion-heading class='menu-title'>
Staff <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': menuStatus[2].isOpen , 'glyphicon-chevron-right': !menuStatus[2].isOpen }"></i>
</accordion-heading>
<ul class='left-menu'>
<li><a href=''>test1</a></li>
<li><a href=''>test1</a></li>
<li><a href=''>test1</a></li>
</ul>
</accordion-group>
<accordion>
How about working with CSS? Bootstrap adds a class collapsed on the html element that has the data-toggle="collapse". When the slide opens, it removes this collapsed class. We can then work with css to, for example, rotate the span element (a child of the element that has the data-toggle attribute).
<style>
button.collapsed span {
transform: rotate(-90deg);
}
</style>
<button type="button" class="btn btn-info collapsed" data-toggle="collapse" data-target="#demo">
Simple collapsible
<span class="glyphicon glyphicon-chevron-down"></span>
</button>
<div id="demo" class="collapse">
Lorem ipsum dolor...
</div>
IMPORTANT NOTE : Ensure collapsed class is added to the element that has the data-toggle="collapse" attribute for this to work smoothly. Otherwise, on initial loading of the element, the span element doesn't rotate as expected the first time.
I would recommend that you check out 'UI Bootstrap' from the AngularUI team. It's a collection of "Bootstrap components written in pure AngularJS".
http://angular-ui.github.io/bootstrap/
Their website features an example which shows their Accordion directive using ng-class to toggle the chevron icons.
http://angular-ui.github.io/bootstrap/#/accordion
Their directive also features a close-others attribute which, if true, will ensure only a single panel is open at any one time.
<accordion close-others="true">
The easiest solution I have ever think. And not to use any controller,
<div
class="fa fa-fw list-arrow"
ng-class="{'fa-angle-down': isClicked, 'fa-angle-right' : !isClicked}"
ng-click="isClicked = !isClicked">
</div>
You can write similar like me.
Did some researching, I was able to use this method to add the class open to the panel-header when it's toggled open. This is example allows multiple panels to be open and uses Angular Strap Collapse.
Template:
<div class="panel-group"
role="tablist"
data-ng-model="multiplePanels.activePanels"
data-allow-multiple="true"
data-bs-collapse>
<div class="panel panel-default" ng-repeat="location in locations">
<div class="panel-heading"
role="tab"
data-ng-class="{'open' : multiplePanels.activePanels.indexOf($index) > -1}"
bs-collapse-toggle>
<h3>Some Header Stuff</h3>
</div>
<div class="panel-collapse" role="tabpanel" bs-collapse-target>
<div class="panel-body">
<p>Stuff in the panel body...</p>
</div>
</div>
</div>
</div>
JS in the controller:
$scope.multiplePanels.activePanels = [];
You can use bootstrap (tested in 4+) collapse and the following styles to toggle the button;
<style>
[id^='particon'] {
display: block !important;
}
[id^='particon']:after {
font-family: 'Glyphicons Halflings';
color: grey;
}
[id^='particon'].collapse:after {
content: "\e081";
}
[id^='particon'].collapse.show:after {
content: "\e082";
}
/*optional*/
[id^='particon'].collapsing {
transition: none;
}
</style>
For fully working snipplet;
https://js.do/code/changecollapseicon
After some research i've got one way to solve this.
JS:
$scope.firstpaneisopen = false;
$scope.secondpaneisopen = false;
Modified ng-click on the first pane:
<a data-toggle="collapse" data-parent="#accordion" href="#collapseOne" ng-click="firstpaneisopen=!firstpaneisopen; secondpaneisopen=false">
vice versa on the second pane.
I don't think this is any elegant solution, especially if we got more than two panes, but it works.

How do I set model according to chosen accordion group. UI Bootstrap

I'm working on accordion using Angularjs and this directive: http://angular-ui.github.io/bootstrap/#/accordion
I have an accordion similar to this:
<accordion close-others="true">
<accordion-group heading="Static Header1">
This content is straight in the template.
</accordion-group>
<accordion-group heading="Static Header 2">
This content is straight in the template.
</accordion-group>
<accordion-group heading="Static Header 3">
This content is straight in the template.
</accordion-group>
</accordion>
I know that I can set is-open directive to specify if accordion-group is opened, but how I can pass which accordion is opened to model?
Additional question:
How can I make sure that there always one accordion opened(not multiple, and not all hidden)?
Solution that works fine, but I'm not so happy about it:
<script type="text/ng-template" id="template/accordion/accordion-group.html">
<div class="accordion-group">
<div class="accordion-heading" >
<a class="accordion-toggle no-padding" ng-click="isOpen = true" accordion-transclude="heading">{% heading %}</a>
</div>
<div class="accordion-body" collapse="!isOpen">
<div class="accordion-inner" ng-transclude></div>
</div>
</div>
</script>
<accordion close-others="true">
<accordion-group>
<accordion-heading>
<span ng-click="chosen = 'acc1'">Accordion 1</span>
</accordion-heading>
This content is straight in the template.
</accordion-group>
<accordion-group>
<accordion-heading>
<span ng-click="chosen = 'acc2'">Accordion 2</span>
</accordion-heading>
This content is straight in the template.
</accordion-group>
<accordion-group>
<accordion-heading>
<span ng-click="chosen = 'acc3'">Accordion 3</span>
</accordion-heading>
This content is straight in the template.
</accordion-group>
</accordion>
CSS style that make span full height and width:
.accordion-toggle {
padding: 0;
}
.accordion-toggle span {
display: block;
padding: 8px 15px;
}

Resources