Open a box with Bootstrap and Angularjs not working - javascript

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 :)

Related

Dynamically created Bootstrap collapse in Angular 6 not working

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.

Event listener disappears inside ng-repeat

My HTML form has many questions I create using ng-repeat.
I want to create a pop-over for some questions.
When I put the button that triggers the pop-over outside the ng-repeat, it works. Inside the ng-repeat it does not.
This works (button before ng-repeat):
<div class="row">
<div class="col-md-12">
<button title="" data-toggle="popover" data-placement="top" data-trigger="hover" data-title="Popover on hover" data-content="And here's some amazing content. It's very engaging. Right?" class="btn btn-primary btn-wide">
hover
</button>
<div ng-repeat="q in config.questionnaire.questions">
Producing this:
This does not work (button after ng-repeat):
<div class="row">
<div class="col-md-12">
<div ng-repeat="q in config.questionnaire.questions">
<button title="" data-toggle="popover" data-placement="top" data-trigger="hover" data-title="Popover on hover" data-content="And here's some amazing content. It's very engaging. Right?" class="btn btn-primary btn-wide">
hover
</button>
Inspecting the button element on google chrome, I found that some event listeners were removed:
These are the event listeners for the button before the ng-repeat:
These are the event listeners for the button after the ng-repeat:
As you can see, mouseover and mouse out listeners disappeared.
Why?
What can I do?
If you are using Bootstrap with your Angular project, think of using Angular UI library.
https://angular-ui.github.io/bootstrap/#/popover
It provides many directives which make it easier to connect Bootstrap with Angular. I tested the uib-popover directive with ng-repeat and it works properly this way. The code is pretty simple:
//...
<div ng-repeat="t in main.testArray">
<button uib-popover="My popover content" popover-title="Popover title" popover-trigger="mouseenter">{{t.text}}</button>
</div>
//...
I will try to investigate your problem further, but the library seems to be an easy workaround.
Edit
I think I also managed to figure out a solution without using external library. What I did was creating a directive which initializes Boostrap popover on specified element. This way you make sure that the popover function will be fired when elements are rendered. I guess this was the reason why it didn't work with your method. You probably invoked the popover function before elements were really rendered as ng-repeat does this with a delay.
And here is the code:
angular.module('moduleName')
.directive('bootstrapPopover', function() {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.popover();
}
};
});
And then use directive on element:
<div ng-repeat="t in main.test">
<button data-toggle="popover" data-placement="top" data-trigger="hover" data-title="Test" data-content="Test"
class="btn btn-primary btn-wide" bootstrap-popover>hover {{t.text}</button>
</div>
However, I would still recommend trying the Angular UI out. I used it in the last Angular project and it was really helpful.

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.

Angular ng-click does not work in Kendo UI template

I'm trying to add ng-click into Kedo UI template, but function saveCustomView on theUser controller still cannot be fired.
But outside of the tag is ng-click working correctly.
<div id="grid" data-ng-controller="UsersCtrl" data-ng-init="initGrid()" >
<script type="text/x-kendo-template" id="testBtn" >
<div class="toolbar">
<a data-ng-controller="UsersCtrl"
ng-click="saveCustomView()">
Add actual selection to custom views
</a>
</div>
</script>
Could somebody tell me how can I solve it?
Thanks for any help.

Disabling tabs generated by Angular Strap (AngularJS)

I'm creating some tabs in my HTML page for which Im using AngularStrap library. I want to disable one of the tab in it.
My code :
<div bs-tabs>
<div data-title="General"> <!-- the tab which needs to be disabled -->
</div>
</div>
I tried using ng-show, ng-disabled and ng-if -- But it doesn't get disabled.
Any help would be appreciated.
This is something that has been fixed in 2.1.3.
After upgrading, 'ng-if' should be enough:
<div ng-model="tabs.activeTab" bs-tabs="">
<div ng-repeat="tab in tabs" title="{{ tab.title }}" bs-pane="" ng-if="tab.show">
<div ng-include="tab.page"></div>
</div>
</div>
There is now a disabled option for bs-pane (version 2.2.0 onwards)

Categories