Angular js stop propagation from Bootstrap "dropdown-toggle" event - javascript

I have an Angular JS 1.3 app.
In it I have a table row repeater with an ng-click:
<tr ng-repeat-start="user in users.users" ng-click="showDetails = !showDetails">
<!-- main row, with the menu td shown below -->
<tr class="row-details" ng-show="showDetails" ng-class="{ 'active': showDetails }">
<td>this is the row that hows details</td>
</tr>
<tr ng-repeat-end></tr>
Which toggles opening a detail view. Works fine. But now I need to add another item in each of the tds, a Bootstrap button menu:
<td>
<div class="btn-group">
<div ng-switch on="user.status">
<button class="btn btn-link btn-gear dropdown-toggle" type="button" data-toggle="dropdown"><i class="fa fa-cog"></i></button>
<ul class="dropdown-menu dropdown-menu-right" role="menu" ng-switch-when="Inactive">
<li>Delete</li>
</ul>
<ul class="dropdown-menu dropdown-menu-right" role="menu" ng-switch-when="Invited">
<li>Resend invitation</li>
<li>Delete</li>
</ul>
<ul class="dropdown-menu dropdown-menu-right" role="menu" ng-switch-default>
<li>Reset password</li>
<li>Delete</li>
</ul>
</div>
</div>
</td>
Problem is, trying to click on this menu button instead triggers the ng-click on the row, toggling the row state but never opening my menu. How can I prevent this?

This is pretty tricky problem. The thing is that when you click menu button two things happens: the first is that it opens Bootstrap dropdown menu, and the second is that event propagates to the parent element and also triggers showDetails = !showDetails.
The obvious solution is to try to stop event propagation with $event.stopPropagation() on the td level, so that event doesn't bubble up the DOM tree and never triggers parent ngClick. Unfortunately, it will not work because Bootstrap sets up click event listener on the document element to benefit from bubbling, so you can't stop propagation.
The simplest solution I came up with in such cases is to set a flag on the original event object whether event occurred on the menu button. If this is the case ngClick on the tr won't do anything.
It will look like this for tr:
<tr ng-repeat-start="user in users.users" ng-click="$event.originalEvent.dropdown || (showDetails = !showDetails)">
ans for button:
<button ng-click="$event.originalEvent.dropdown = true" class="btn btn-link btn-gear dropdown-toggle" type="button" data-toggle="dropdown">
<i class="fa fa-cog"></i>
</button>
Demo: http://plnkr.co/edit/eIn6VW3Y2jHn0MtJQVcU?p=preview

With help of dfsq's answer I managed solve same kind of problem in Angular 2. Here is my sample code.
<td class="tablerowdata" (click)="$event.dropdown || onSelect(track)" >
<button (click)="$event.dropdown = true" type="button" class="btn btn-default dropdown-toggle trackbuttons" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">

Related

Manually trigger a dropdown event using just plain javascript?

I am trying to trigger a manual dropdown event in javascript. below is the function where I am working. I am stopping the first event that takes place and now i want to trigger a drop down event.
stopNavigationTriggerDropDown(event: any){
event.stopImmediatePropagation();
event.stopPropagation();
event.preventDefault();
//code that triggers manual dropdown event
}
now this is the html code:
<tr (click)="goToPlan(plan)">
<td>....</td>...
<td>
<div class="input-group">
<button (click)="stopNavigationTriggerDropDown($event)" type="button" class="btnTransparent" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-ellipsis-h"></i>
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item" (click)="action(apl)">Go</a>
</div>
</div>
</td>
</tr>
I can not use jQuery just pure JavaScript. I have searched online but many examples show jQuery, but I need it to be just pure JS. I thank you guys in advance!
There are two main ways you can accomplish this.
1: Fire button's click event:
var button = document.getElementsByClassName("example");
button.click()
2: Create and dispatch an event on the page (see: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events)
var button = document.getElementsByClassName("example");
var btnEvent = new Event('click');
button.dispatchEvent(btnEvent);

AngularJS elements located in components are fired only after the second click

I have AngularJS (1.x) component - or actually directive to be precise,
and the elements inside this directive are get fired/worked/actioned only in the second click.
For example: a dropdown will not toggle unless you click twice.
After the second click the toggle will be on each next click.
It's like the elements are not digested in the DOM.
This is the component call:
<dropdown-custom-component-example></dropdown-custom-component-example>
This is the component html file:
<div class="dropdown">
<a class="btn pl-2" data-toggle="dropdown">
<i class="icon-options"></i>
</a>
<div class="dropdown-menu">
<a class="dropdown-item" data-toggle="modal" data-target=".create-supplier">
<i class="fa icon-plus text-primary"></i>
Action
</a>
</div>
</div>
you could try to digest by your own inside your directive, after you've checked if $digest isn't alreay in progress:
if(!$scope.$$phase) $scope.$digest();
// or $apply ..
hope this solves your issue :)
Most of the time AngularJS does not respond is because something is happening outside the Angular context, in those cases it's useful to try to replicate the functionality you want with built-in AngularJS directives.
It would be useful to have access to some of the implementation of your component. However, with all the information you have provided, you can use the ngClick built-in directive:
<div class="dropdown">
<a class="btn pl-2" data-toggle="dropdown">
<i class="icon-options"></i>
</a>
<div class="dropdown-menu">
<a class="dropdown-item" data-toggle="modal" data-target=".create-supplier" ng-click="yourFunctionHere(this)">
<i class="fa icon-plus text-primary"></i>
Action
</a>
</div>
</div>
AngularJS Docs - ngClick

Dropdown on icon, bootstrap

I'm using bootstrap (I have bootstrap and jquery included and dropdowns working elsewhere) and tryingo to use my profile icon as a trigger for a dropdown with an option to logout.
My profile icon is showing the downward caret like it's a dropdown, but when I click there is no dropdown triggered.
I can't use a button here, it needs to be tied to the icon.
What exactly am I doing wrong?
<div class="dropdown">
<div class="menu-button profile dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<i class="far fa-user-circle fa-2x"></i>
</div>
<ul class="dropdown-menu">
<li>Logout</li>
</ul>
</div>

div popup if button click not working

I have a button which on clicked shows a dropdown we are using bootstrap to show the dropdown on button click below is my code.
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">
Dropdown Example
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
</div>
The requirement is that I have to show a div pop up stating system error which will occur only when the button click is not working.
How to check if button click is working or not and show pop up.
The above code is a sample code from w3schools
my main code is written in angularjs and I am using angualar-ui-bootstrap for the drop down. the list values are also coming from the controller.

Protractor clicking on dropdown toggle

I am running E2E on my angular application using Protractor. I am running into a very weird problem.
I am using the Bootstrap Dropdown which has some options. I need to click on one of the options.
I referred this answer which tries to do something similar, but doesn't work for me:
Protractor - how to select heavily nested dropdown element?
My structure looks like:
<div id="fc-more-btn" class="btn-group btn-group-sm dropdown" role="group" dropdown="" is-open="ctrl.fcDropdown">
<button type="button" class="btn btn-default dropdown-toggle filetree-btn" tooltip="More Actions" tooltip-trigger="mouseenter" tooltip-placement="bottom" ng-disabled="ctrl.sd.noSelections" dropdown-toggle="" aria-haspopup="true" aria-expanded="false">
<span class="fa fa-caret-down"></span>
</button>
<ul class="dropdown-menu filetree-dropdown" role="menu">
<li>
<a class="btn fc-dropdown-link" ng-disabled="ctrl.sd.noSelections||(ctrl.sd.multipleSelections||!ctrl.sd.dirSelected)" ng-click="ctrl.createNewFile()">
New File
</a>
</li>
<li>
<a class="btn fc-dropdown-link" ng-disabled="ctrl.sd.noSelections||(ctrl.sd.multipleSelections||!ctrl.sd.dirSelected)" ng-click="ctrl.createNewDir()">
New Folder
</a>
</li>
<li>
<a class="btn fc-dropdown-link" ng-disabled="ctrl.sd.noSelections" ng-click="ctrl.copyFiles()">
Copy
</a>
</li>
<li>
<a class="btn fc-dropdown-link" ng-disabled="ctrl.clipboardEmpty||ctrl.sd.noSelections||(ctrl.sd.multipleSelections||!ctrl.sd.dirSelected)" ng-click="ctrl.pasteFiles()" disabled="disabled">
Paste
</a>
</li>
<li>
<a class="btn fc-dropdown-link" ng-disabled="ctrl.sd.noSelections||ctrl.sd.multipleSelections" ng-click="ctrl.renameFile()">
Rename
</a>
</li>
</ul>
</div>
In my test, I am trying to click on the Rename link.
The code I have written is:
element(by.css('.dropdown-toggle')).click().then(function(){
//click on rename
});
On running the test, there is a small flicker over the dropdown toggle button, and it seems that the button is clicked. However, the dropdown that should be shown is not shown.
As a result of this, I am not able to simulate a click to rename. Am I doing something wrong?
Try selecting by cssContainingText, very helpful with dropdowns and nested elements!
element(by.cssContainingText('option', 'Rename')).click();

Categories

Resources