Ravi Ram
Ravi Ram

Reputation: 24488

AngularJS ng-click fires twice

I am using ng-click and it fires twice when I apply it to SPAN tag.

HTML

<div ng-app="regApp" ng-controller="RegistrationCtrl" data-ng-init="GetEventDetail()" ng-show="data.EventName">

    <h2>Registration for {{data.EventName}}</h2>
    <span class="btn" id="btnSave" ng-click="PostRegistration()">Save </span>

</div>

CONTROLLER

var app = angular.module('regApp', ['ui']);

app.controller('RegistrationCtrl', function ($scope, $http) {
    $scope.PostRegistration = function () {
    alert('click '); <--- fires twice
    /// some code here -- 
};

It should only fire once. How I can find why this is happening and how to fix it?

Upvotes: 24

Views: 49125

Answers (19)

Vladislav
Vladislav

Reputation: 218

My case: I used ng-click event on my custom custom angular checkbox component. So just providing a method binding for custom component did the trick.

Before: <mono-checkbox-ng ng-click="vm.onSelectAllClicked()">

After: <mono-checkbox-ng on-changed="vm.onSelectAllClicked()">

Upvotes: 0

Enigma Fox
Enigma Fox

Reputation: 1

I have handled it by following code

HTML :

<div>
    <ui>
        <li>
            <button class="Button" ng-disabled="self.desableSubmitButton" ng- 
            click="self.SubmitClick($event)">Submit</button>
        </li>
    </ui> 
</div>

Angular 1.0 Controller :

_self.SubmitClick = function(event){   
     _self.desableSubmitButton = true; //disable submit button
     event.preventDefault();
     event.stopPropagation();

     setTimeout(funtion() {
       _self.desableSubmitButton = false; //enable submit button after timeout
           if(_self.$scope.$$phase != '$apply' || _self.$scope.$$phase != '$digest'){
             _self.$scope.$digest();
             }
      }, 1000);//other Code logic
}

Upvotes: 0

noodle_wave
noodle_wave

Reputation: 255

I had a similar problem, but could not find where I included Angular twice in my files.

I was using an ajax calls to load specific form layouts, so I need to use $compile to activate Angular on the inserted DOM. However, I was using $compile on my directive $element which has a controller attached. Turns out this "includes" the controller twice, causing two triggers with ng-click or ng-submit.

I fixed this by using $compile directly on the inserted DOM instead of my directive $element.

Upvotes: 17

Uncle Dan
Uncle Dan

Reputation: 3290

You might have a ng-click inside a form container using a ng-submit. In that case, add type="button" to all your using ng-click.

Upvotes: 4

Bruno Heringer
Bruno Heringer

Reputation: 243

I don't know what was the reason this happened, but I had to use event.stopPropagation(); inner my JavaScript function.

HTML

<button class="button" ng-click="save($event)">Save</button>

JAVASCRIPT

function save(event) {
    event.stopPropagation();
}

Upvotes: 1

SaltyCatFish
SaltyCatFish

Reputation: 59

I had a problem like this as well.

<button style="width: 100%;" class="btn btn-danger" ng-click="'{{vm.delete()}}'">

Thats not how you call ng-click, but no errors were thrown and the function calls still worked.

<button style="width: 100%;" class="btn btn-danger" ng-click="vm.delete()">

Is correct and will then only be called once.

Upvotes: 1

John Huang
John Huang

Reputation: 1338

This situation may be caused by lacking the ngTouch in Angular.

Event if the ngTouch is loaded, the bug in ngTouch and ngClick before Angular 1.5.0 may occur. It results from the ngClick being triggered by pointerup and mouseUp in Chrome for Desktop on device toolbar or mobile device.

Upvotes: 1

physox
physox

Reputation: 323

In case of somebody having the same issue: This was my problem:

<a type="submit" ng-click="login()">submit login<a>

Both, the type="submit" and the ng-click="login()"triggered the login()-method in my controller.

So just use either the type=submit or the ng-click directive

Upvotes: 7

erier
erier

Reputation: 1744

I'm a bit of a dummy and had this:

<li data-shape="amethyst" ng-click="toggleGem('amethyst')">
    <label></label>
    <i class="amethyst"></i>Amethyst
    <input type="checkbox" name="gem_type" id="gem-amethyst" value="amethyst" />
</li>

The click event was triggering twice. I moved the ng-click to the label element and it's working as expected.

<li data-shape="amethyst">
    <label ng-click="toggleGem('amethyst')"></label>
    <i class="amethyst"></i>Amethyst
    <input type="checkbox" name="gem_type" id="gem-amethyst" value="amethyst" />
</li>

Upvotes: 1

Rajiv
Rajiv

Reputation: 1295

I have changed <button ng-click='clickHandler()'> to <a ng-click='clickHandler()'> and now event fires only once

Upvotes: 2

A.T.
A.T.

Reputation: 26302

was facing same issue. Find out they were using https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js version and i switch it to latest 1.4.5 version and it just worked.

https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js

var app = angular.module('regApp', []);

app.controller('RegistrationCtrl', ['$scope','$http',function($scope,$http ) {
  $scope.PostRegistration = function() {
    alert('click '); // <--- fires twice
    /// some code here -- 
  };
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="regApp" ng-controller="RegistrationCtrl">
  <h2 >Registration for {{data.EventName}}</h2>
  <span ng-click="PostRegistration()" class="btn" id="btnSave">Save </span>

</div>

Upvotes: 2

Denys Wessels
Denys Wessels

Reputation: 17019

I've had the same issue when dynamically injecting partial views in my SPA(Single Page Applications).The way I solved it was to store the content of my div in a local variable like this:

var html = $("#leftContainer").html();

Then empty out the div and reset its content like this:

$("#leftContainer").empty();
$("#leftContainer").append(html);

Now you can add any additional html you have received from an AJAX call or dynamically constructed and lastly remember to re-compile your HTML to make it bound to angular:

var entities = $("#entitiesContainer");

var entity = "<div><a href='#' ng-click='Left(" + entityId + ")'>&nbsp;" + entityName + "</a><div>"
entities.append(entity);

var leftContainer = angular.element(document.getElementById("entitiesContainer"));

$compile(leftContainer)($scope);

Upvotes: 1

sebap
sebap

Reputation: 1691

Same problem using

<a ng-click="fn()"></a>

fn was called twice

Using a button fixed it :

<button ng-click="fn()"></button>

Upvotes: 11

Ross Shannon
Ross Shannon

Reputation: 557

This is probably obscure, but I had ng-click firing twice because I had BrowserSync running, which would mirror my inputs into a tab that I had open in another window, thus doubling up all my clicks. To resolve, I disabled “ghostMode”: https://www.browsersync.io/docs/options/

Upvotes: 9

Vahid Montazer
Vahid Montazer

Reputation: 1301

elements wrapped one another, and this can cause trigger event twice or more.

So i used a simple CSS trick for this solution :

.off{
   pointer-events:none;
}

and apply it to an element correspond to click event.

Upvotes: 4

Vlex28
Vlex28

Reputation: 31

I got it when I accidently called $compile for the dynamically added elements several times in the cycle, instead of just once. Compiling just once removed this effect.

Upvotes: 3

Jovica Zaric
Jovica Zaric

Reputation: 543

If other answers don't help, make sure that AngularJS profiling is disabled in Batarang (if you have it installed of course).

This was making ng-click to fire twice for me.

enter image description here

Upvotes: 5

Elan Hasson
Elan Hasson

Reputation: 1270

I solved this by removing my ngsubmit handler as I don't have a need for it. I'm monitoring on change events and using SignalR to update the screen in near real-time.

I was also in a form and the AngularJS docs for ngSubmit states:

Warning: Be careful not to cause "double-submission" by using both the ngClick and ngSubmit handlers together. See the form directive documentation for a detailed discussion of when ngSubmit may be triggered.

Upvotes: 7

Langdon
Langdon

Reputation: 20053

The code you've provided does not fire the event twice:

http://jsfiddle.net/kNL6E/ (click Save)

Perhaps you included Angular twice? If you do that, you'll get two alerts, demonstrated here:

http://jsfiddle.net/kNL6E/1/

Upvotes: 29

Related Questions