1

I'm using angular.js and I have a table where each row is able to click, using ng-click="launchMethodRow", but in a determinate column in the row I have a button, when I clicked in that button, not only functionality of this button is triggered (ng-click="launchMethodButton"), but also the method for the row is launched.

How can I do to avoid this behaviour? I want when I click the button, only the method that the button responds run and not the method for row.

currarpickt
  • 2,290
  • 4
  • 24
  • 39
mos
  • 337
  • 2
  • 4
  • 11
  • Take a look [here](https://stackoverflow.com/questions/15193539/whats-the-best-way-to-cancel-event-propagation-between-nested-ng-click-calls) – vp_arth Jul 06 '16 at 04:16

3 Answers3

2

You can catch the event associated with the click and prevent it from propagating.

Lets say you have a row and a button like so:

<div class="row" ng-click="launchMethodRow()">
    <button ng-click="launchMethodButton($event)"></button>
</div>

For the button ng-click pass the click event ($event) down to the callback function. And in the launchMethodButton function, stop event propagation.

$scope.launchMethodButton = function(event){
    event.stopPropagation();
    // execute button click logic
}

OR

Alternatively, you could wrap propagation stopping logic into a directive and can apply that to the button and that way you wouldn't have to do that logic in controller.

angular.module('someModule', []).directive('stopClickPropagation', function () {
    return {
        restrict: "A",
        link: function (scope, element) {
            element.bind('click', function (e) {
                e.stopPropagation();
            });
        }
    }
});

<div class="row" ng-click="launchMethodRow()">
        <button ng-click="launchMethodButton()" stop-click-propagation></button>
 </div>
Chanthu
  • 1,794
  • 1
  • 15
  • 22
  • Excellent, I'll take the directive approach, in order to reuse. – mos Jul 06 '16 at 04:31
  • @mos Perfect. That way when unit testing, you can just test the directive once and don't have to keep on testing the same logic in every controller with this logic. – Chanthu Jul 06 '16 at 04:32
1

Use $event.stopPropagation() for this :

 <div ng-click="clicked('outer')">
      <div ng-click="clicked('inner'); $event.stopPropagation()"></div>
  </div>
Keshav
  • 821
  • 2
  • 12
  • 33
0

you can use ng-show or ng-hide to disable the button so that you can avoid unwanted click.

<input type="button" value="Login" ng-show="myForm.$valid" ng-click="sigClick(username,password)"> 

the button will be able to click only when the for is valid

Mohan Gopi
  • 7,606
  • 17
  • 66
  • 117
  • each row always has to show this button, the button is an integral part of each row. – mos Jul 06 '16 at 04:21
  • Ok no problem you see the `input type button` will always visible to the user but it will not able to be clickable untill the condition become true look here `ng-disabled="myForm.$valid"` – Mohan Gopi Jul 06 '16 at 04:22