Dynamically created Bootstrap collapse in Angular 6 not working - javascript

In Angular 6 I iterate through a data set in order to dynamically create an accordion/collapse. The issue is that Bootstrap is initialized at page load, however, this accordion is created after page load, after an API call. So after the accordion is rendered, its is not interactive, as the new DOM elements were not picked by the initilization of bootstrap at page load.
If I could just get bootstrap to re-initialize from the JS entirely, that would be perfect.
Otherwise I need to find a way to re-initialize Bootstrap collapse so that it picks up all of the new DOM additions that are created. Here is the markup. Ive tried $('.collapse').collapse() like the docs say but that only collapses the content, it does not initialize the controls to toggle the content.
<div id="accordion" *ngIf="data && data.length > 0">
<!-- Chart -->
<div class="card" *ngFor="let chart of data; let chartIndex = index">
<div class="card-header" id="heading{{chartIndex}}">
<h4 class="mb-0">
<a href="#"
class="acc-btn"
data-toggle="collapse"
data-target="#collapse{{chartIndex}}"
aria-expanded="true">
<span class="fa fa-chevron-up"></span>
<span class="fa fa-chevron-down"></span>
{{chart.sectionName}}
</a>
</h4>
</div>
<div id="collapse{{chartIndex}}" class="collapse show" data-parent="#accordion">
<div class="card-body">
<table class="scenario">
<tr>
<th *ngFor="let header of chart.headers">{{header}}</th>
</tr>
<tr *ngFor="let row of chart.data">
<td *ngFor="let value of row"><app-parent-child-data-list [data]="value"></app-parent-child-data-list></td>
</tr>
</table>
</div>
</div>
</div>
</div>

You should not mix Angular and JQuery together. They will conflict with each other since both will be manipulating the DOM and each will have issues knowing that the other made changes.
The best solution would be to use something like NG-Bootstrap which is a pure Angular implementation of most of Bootstrap JQuery code. https://ng-bootstrap.github.io/#/home
If you were only using the accordion, you could also write your own simple function to toggle the accordion hidden/shown classes, but as your app grows you may find adding NG-Bootstrap would just be easier.

Related

How to update existing template row in HTML/JS

I'm considering using a template to dynamically create rows in a web application to gradually update the page as the server sends new data after it finishes its calculations. Creating new rows with the template works fine, but I was wondering how I could update the information in existing rows created using the template, or if it is even possible to update existing rows using templates.
<!-- reusable template for row objects -->
<template id="post_template">
<!-- template content -->
<div class="card mb-3 animated fadeIn shadow-sm">
<div class="cared-body">
<h4 class="card-title" id="title"></h4>
<span class="text-muted" id="content"></span>
</div>
</div>
</template>

materializecss collapsible panel with a different html structure

I'm trying to create a custom collapsible panel using materialize but I don't know why the button is not triggering and showing the panel body. I have created a fiddle with my custom example that doesn't work and one materilaize example with their structure that works.
From my inspect I saw that the active class is not being added on panel body while clicking on panel header which is quite strange.
So if anyone can help me with that please ... modifying materialize components is like a pain in the ass !
<div class="collapsible">
<div class="box">
<div class="1left">Left</div>
<div class="2center">Center</div>
<div class="3right">Right
<a class="collapsible-header">Colapse header</a>
</div>
</div>
</div>
<div class="collapsible-body">
This should be the body collapsed
</div
http://jsfiddle.net/zt5515zt/90/
In Materialize you need both collapsible-header and collapsible-body at the same level in order to make Collapsible work.
Just Change the level of you collapsible-body as shown below and it will work.
<a class="collapsible-header">Colapse header</a>
<div class="collapsible-body">
This should be the body collapsed
</div>
Hope this helps you solve the problem.

Open a box with Bootstrap and Angularjs not working

I am beginning with AngularJS, and I am wondering why there is a conflict between Bootstrap and Angularjs when I try to simply open a box like this:
Link:
<a class="btn btn-primary" role="button" data-toggle="collapse" href="#open-baggage-box" aria-expanded="false" aria-controls="open-baggage-box">Add Now</a>
Box:
<div id="open-baggage-box" class="collapse add-price-section">
<div class="open-holder">
<div class="container">
</div>
</div>
</div>
It actually does not work and I don't really know why. Thank you
As angular templates are usually dynamically loaded, bootstrap can look for collapse element before it is rendered.
If you want to use Bootstrap UI elements with AngularJS, I recommend UI Bootstrap which implements them as Angular directives.
In your case, collapse directive will do the job :)

making accordion panel open when clicking on header rather than just title

I found this stackoverflow questions which looks to be the same problem I am having. That is the default behavior is for angular ui-bootstrap accordion to only open when you click on the panel title and not anywhere else on the panel.
ng-click on accordion panel header
The solutions presented seems to get out of sync when one time clicking on the panel and then clicking on the title. Sometimes you have to click twice to get it back in sync. I noticed this snippet on the documentation, To use clickable elements within the accordion, you have override the accordion-group template to use div elements instead of anchor elements, and add cursor: pointer in your CSS.
Can someone provide and example of using div tags instead of anchor elements?
You have to customise the template for accordion-group to use clickable links otherwise it will trigger unexpected routing. You can modify the template as below:
<script id="uib/template/accordion/accordion-group.html" type="text/ng-template">
<div role="tab" id="{{::headingId}}" aria-selected="{{isOpen}}" class="" ng-keypress="toggleOpen($event)">
//this is previously <a role="tab"> - replace it with div
<div role="button" style="border-top:1px solid #e6e6e6" data-toggle="collapse" href aria-expanded="{{isOpen}}" aria-controls="{{::panelId}}"
tabindex="0" ng-click="toggleOpen()" uib-accordion-transclude="heading" ng-disabled="isDisabled"
uib-tabindex-toggle><span uib-accordion-header ng-class="{'text-muted': isDisabled}">{{heading}}</span>
</div>
</div>
<div id="{{::panelId}}" aria-labelledby="{{::headingId}}" aria-hidden="{{!isOpen}}" role="tabpanel"
class="panel-collapse collapse" uib-collapse="!isOpen">
<div class="" ng-transclude></div>
</div>
</script>
You can put this template in your view where you are using accordion. This will override your default accordion-group template that comes from angular ui bootstrap tpls library.

Bootstrap: Accordion Collapse stopped working with Bootstrap 2.0.3

My accordion using data-toggle="collapse" and data-parent="#selector"works fine with Bootstrap 2.0.2, but when I switch to 2.0.3 the accordion functionality stops working.
It still opens and closes the target div, but it won't automatically close an open target div when another td with data-toggle="collapse" is clicked.
You can see it not working with 2.0.3 here: http://chooserealtoday.com/#faq
The following code example is also on JSFiddle at http://jsfiddle.net/N7MN9/3/.
<table id="faq-table" class="table table-bordered">
<tr>
<td class="question" data-toggle="collapse" data-target="#answer1" data-parent="#faq-table">
<p><strong>What is your name?</strong></p>
<div id="answer1" class="answer collapse">
<p>Mark Rummel</p>
</div>
</td>
</tr>
<tr>
<td class="question" data-toggle="collapse" data-target="#answer2" data-parent="#faq-table">
<p><strong>What is your favorite color?</strong></p>
<div id="answer2" class="answer collapse">
<p>Blue, no yellow.</p>
</div>
</td>
</tr>
</table>
Thanks for any help you can offer on this!
I see two options
use divs instead of table (go for the example http://twitter.github.com/bootstrap/javascript.html#collapse )
modify bootstrap.js and replace :
actives = this.$parent && this.$parent.find('> .accordion-group > .in')
by the 2.0.2 version :
actives = this.$parent && this.$parent.find('.in')
You can solve this without modifying the Bootstrap files: just throw in the .accordion-group class.
Reference
I wrote this extension to allow using collapse with a table. It allows you to specify the selector used to find active siblings in a collapse group.
bootstrap-collapse-activeselector

Categories