I ran into an issue today when I tried to use Bootstrap’s collapse functionality inside an Angular JS based application. What would happen is when I click on panel heading, my application would go to the root (default route). This, of course, is caused by browser processing anchor click event in addition to collapse JavaScript doing the same thing. Solution is to eat the default click event. In an Angular application this should be done via directive, since it is manipulating the DOM. Here is a simple “each anchor click” directive. I am using TypeScript in this sample.
export class NoClickDirective extends app.Directives.Core.BaseDirective { constructor() { super(); this.restrict = 'A'; this.link = function (scope: ng.IScope, element: ng.IAugmentedJQuery) { element.click(function (eventObject: JQueryEventObject) { eventObject.preventDefault(); }); }; } }
If you want JS version, it looks just as simple.
function NoClickDirective() { _super.call(this); // take this line out if you do not have a prototype for directives. this.restrict = 'A'; this.link = function (scope, element) { element.click(function (eventObject) { eventObject.preventDefault(); }); }; }
Then, I need to register it in my module.
angular.module('app.Directives.Common', ['app.Services.Utilities']) .directive('noClick', [function () { return new app.Directives.Common.NoClickDirective(); }]);
Now, to use it inside HTML is very easy – I just need to add an attribute, remembering rules for translating directive name into attribute name.
<div class="panel-group"> <div class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title"> <a data-toggle="collapse" data-no-click href="#contactsPanel"> Contacts </a> </h4> </div> <div id="contactsPanel" class="panel-collapse collapse"> <div class="panel-body"> Contacts go here </div> </div> </div>
You can see my directive in bold. Voila, collapse is working again.
Enjoy and thanks for reading.
It didn’t work for me. By debugging the JavaScript code I’ve seen that the execution jumps right out of NoClickDirective when attempting to execute _super.call(this).
@IM
This is probably because you do not have a prototype like I do for directives. Just take that line out.
I’ve just added
onclick=”return false;”
to the a object and it worked just fine for me. It is not elegant as the directive option you presented but it does the trick.