Confirmation dialog on ng-click - AngularJS

JavascriptAngularjsAngularjs DirectiveAngularjs Scope

Javascript Problem Overview


I am trying to setup a confirmation dialog on an ng-click using a custom angularjs directive:

app.directive('ngConfirmClick', [
    function(){
        return {
            priority: 1,
            terminal: true,
            link: function (scope, element, attr) {
                var msg = attr.ngConfirmClick || "Are you sure?";
                var clickAction = attr.ngClick;
                element.bind('click',function (event) {
                    if ( window.confirm(msg) ) {
                        scope.$eval(clickAction)
                    }
                });
            }
        };
}])

This works great but unfortunately, expressions inside the tag using my directive are not evaluated:

<button ng-click="sayHi()" ng-confirm-click="Would you like to say hi?">Say hi to {{ name }}</button>

(name is not evaluated is this case). It seems to be due to the terminal parameter of my directive. Do you have any ideas of workaround?

To test my code: http://plnkr.co/edit/EHmRpfwsgSfEFVMgRLgj?p=preview

Javascript Solutions


Solution 1 - Javascript

If you don't mind not using ng-click, it works OK. You can just rename it to something else and still read the attribute, while avoiding the click handler being triggered twice problem there is at the moment.

http://plnkr.co/edit/YWr6o2?p=preview

I think the problem is terminal instructs other directives not to run. Data-binding with {{ }} is just an alias for the ng-bind directive, which is presumably cancelled by terminal.

Solution 2 - Javascript

#A clean directive approach.

Update: Old Answer (2014)

It basically intercepts the ng-click event, displays the message contained in the ng-confirm-click="message" directive and asks the user to confirm. If confirm is clicked the normal ng-click executes, if not the script terminates and ng-click is not run.

<!-- index.html -->
<button ng-click="publish()" ng-confirm-click="You are about to overwrite your PUBLISHED content!! Are you SURE you want to publish?">
  Publish
</button>

// /app/directives/ng-confirm-click.js
Directives.directive('ngConfirmClick', [
  function(){
    return {
      priority: -1,
      restrict: 'A',
      link: function(scope, element, attrs){
        element.bind('click', function(e){
          var message = attrs.ngConfirmClick;
          // confirm() requires jQuery
          if(message && !confirm(message)){
            e.stopImmediatePropagation();
            e.preventDefault();
          }
        });
      }
    }
  }
]);

Code credit to Zach Snow: http://zachsnow.com/#!/blog/2013/confirming-ng-click/

Update: New Answer (2016)

  1. Changed prefix from 'ng' to 'mw' as the former ('ng') is reserved for native angular directives.

  2. Modified directive to pass a function and message instead of intercepting ng-click event.

  3. Added default "Are you sure?" message in the case that a custom message is not provided to mw-confirm-click-message="".

    // /app/directives/mw-confirm-click.js "use strict";

    var module = angular.module( "myApp" ); module.directive( "mwConfirmClick", [ function( ) { return { priority: -1, restrict: 'A', scope: { confirmFunction: "&mwConfirmClick" }, link: function( scope, element, attrs ){ element.bind( 'click', function( e ){ // message defaults to "Are you sure?" var message = attrs.mwConfirmClickMessage ? attrs.mwConfirmClickMessage : "Are you sure?"; // confirm() requires jQuery if( confirm( message ) ) { scope.confirmFunction(); } }); } } } ]);

Solution 3 - Javascript

For me, https://www.w3schools.com/js/js_popup.asp, the default confirmation dialog box of the browser worked a great deal. just tried out this:

$scope.delete = function() {
    if (confirm("sure to delete")) {
        // todo code for deletion
    }
};

Simple.. :)
But I think you can't customize it. It will appear with "Cancel" or "Ok" button.

EDIT:

In case you are using ionic framework, you need to use the ionicPopup dialog as in:

// A confirm dialog


$scope.showConfirm = function() {
   var confirmPopup = $ionicPopup.confirm({
     title: 'Delete',
     template: 'Are you sure you want to delete this item?'
   });

   confirmPopup.then(function(res) {
     if(res) {
       // Code to be executed on pressing ok or positive response
       // Something like remove item from list
     } else {
       // Code to be executed on pressing cancel or negative response
     }
   });
 };

For more details, refer: $ionicPopup

Solution 4 - Javascript

Its so simple using core javascript + angular js:

$scope.delete = function(id) 
	{ 
       if (confirm("Are you sure?"))
		   {
				//do your process of delete using angular js.
		   }
   }

If you click OK, then delete operation will take, otherwise not.

  • id is the parameter, record that you want to delete.

Solution 5 - Javascript

You don't want to use terminal: false since that's what's blocking the processing of inside the button. Instead, in your link clear the attr.ngClick to prevent the default behavior.

http://plnkr.co/edit/EySy8wpeQ02UHGPBAIvg?p=preview

app.directive('ngConfirmClick', [
  function() {
    return {
      priority: 1,
      link: function(scope, element, attr) {
        var msg = attr.ngConfirmClick || "Are you sure?";
        var clickAction = attr.ngClick;
        attr.ngClick = "";
        element.bind('click', function(event) {
          if (window.confirm(msg)) {
            scope.$eval(clickAction)
          }
        });
      }
    };
  }
]);

Solution 6 - Javascript

    $scope.MyUpdateFunction = function () {
        var retVal = confirm("Do you want to save changes?");
        if (retVal == true) {
            $http.put('url', myData).
            success(function (data, status, headers, config) {
                alert('Saved');
            }).error(function (data, status, headers, config) {
                alert('Error while updating');
            });
            return true;
        } else {
            return false;
        }
    }

Code says everything

Solution 7 - Javascript

In today's date this solution works for me:

/**
 * A generic confirmation for risky actions.
 * Usage: Add attributes: ng-really-message="Are you sure"? ng-really-click="takeAction()" function
 */
angular.module('app').directive('ngReallyClick', [function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('click', function() {
                var message = attrs.ngReallyMessage;
                if (message && confirm(message)) {
                    scope.$apply(attrs.ngReallyClick);
                }
            });
        }
    }
}]);

Credits:https://gist.github.com/asafge/7430497#file-ng-really-js

Solution 8 - Javascript

I created a module for this very thing that relies on the Angular-UI $modal service.

https://github.com/Schlogen/angular-confirm

Solution 9 - Javascript

An angular-only solution that works alongside ng-click is possible by using compile to wrap the ng-click expression.

Directive:

.directive('confirmClick', function ($window) {
  var i = 0;
  return {
    restrict: 'A',
    priority:  1,
    compile: function (tElem, tAttrs) {
      var fn = '$$confirmClick' + i++,
          _ngClick = tAttrs.ngClick;
      tAttrs.ngClick = fn + '($event)';
  
      return function (scope, elem, attrs) {
        var confirmMsg = attrs.confirmClick || 'Are you sure?';

        scope[fn] = function (event) {
          if($window.confirm(confirmMsg)) {
            scope.$eval(_ngClick, {$event: event});
          }
        };
      };
    }
  };
});

HTML:

<a ng-click="doSomething()" confirm-click="Are you sure you wish to proceed?"></a>

Solution 10 - Javascript

HTML 5 Code Sample

<button href="#" ng-click="shoutOut()" confirmation-needed="Do you really want to
shout?">Click!</button>

AngularJs Custom Directive code-sample

var app = angular.module('mobileApp', ['ngGrid']);
app.directive('confirmationNeeded', function () {
    return {
    link: function (scope, element, attr) {
      var msg = attr.confirmationNeeded || "Are you sure?";
      var clickAction = attr.ngClick;
      element.bind('click',function (e) {
        scope.$eval(clickAction) if window.confirm(msg)
        e.stopImmediatePropagation();
        e.preventDefault();
       });
     }
    };
});

Solution 11 - Javascript

Confirmation dialog can implemented using AngularJS Material:

> $mdDialog opens a dialog over the app to inform users about critical > information or require them to make decisions. There are two > approaches for setup: a simple promise API and regular object syntax.

Implementation example: Angular Material - Dialogs

Solution 12 - Javascript

If you use ui-router, the cancel or accept button replace the url. To prevent this you can return false in each case of the conditional sentence like this:

app.directive('confirmationNeeded', function () {
  return {
    link: function (scope, element, attr) {
      var msg = attr.confirmationNeeded || "Are you sure?";
      var clickAction = attr.confirmedClick;
      element.bind('click',function (event) {
      if ( window.confirm(msg) )
        scope.$eval(clickAction);
      return false;
    });
  }
}; });

Solution 13 - Javascript

A very simple angular solution

You can use id with a message or without. Without message the default message will show.

Directive

app.directive('ngConfirmMessage', [function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.on('click', function (e) {
                var message = attrs.ngConfirmMessage || "Are you sure ?";
                if (!confirm(message)) {
                    e.stopImmediatePropagation();
                }
            });
        }
    }
}]);

Controller

$scope.sayHello = function(){
    alert("hello")
}

HTML

With a message

<span ng-click="sayHello()" ng-confirm-message="Do you want to say Hello ?" >Say Hello!</span>

Without a messsage

<span ng-click="sayHello()" ng-confirm-message>Say Hello!</span>

Solution 14 - Javascript

Here is a clean and simple solution using angular promises $q, $window and native .confirm() modal:

angular.module('myApp',[])
  .controller('classicController', ( $q, $window ) => {
    this.deleteStuff = ( id ) => {
      $q.when($window.confirm('Are you sure ?'))
        .then(( confirm ) => {
          if ( confirm ) {
            // delete stuff
          }
        });
    };
  });

Here I'm using controllerAs syntax and ES6 arrow functions but it's also working in plain ol' ES5.

Solution 15 - Javascript

Delete confirmation popup using bootstrap in angularjs

very simple.. I have one solution for this with using bootstrap conformation popup. Here i am provided

<button ng-click="deletepopup($index)">Delete</button>

in bootstrap model popup:

<div class="modal-footer">
  <a href="" data-dismiss="modal" ng-click="deleteData()">Yes</a>
  <a href="" data-dismiss="modal">No</a>
</div>

js

var index=0;
$scope.deleteData=function(){
    $scope.model.contacts.splice(index,1);
}
// delete a row 
$scope.deletepopup = function ($index) {
    index=$index;
    $('#myModal').modal('show');
};

when i click delete button bootstrap delete conformation popup will open and when i click yes button row will deleted.

Solution 16 - Javascript

> ng-click return confirm 100% works > > in html file call delete_plot() function

<i class="fa fa-trash delete-plot" ng-click="delete_plot()"></i> 
 
  

> Add this to your controller

    $scope.delete_plot = function(){
        check = confirm("Are you sure to delete this plot?")
        if(check){
            console.log("yes, OK pressed")
        }else{
            console.log("No, cancel pressed")

        }
    }

Solution 17 - Javascript

I wish AngularJS had a built in confirmation dialog. Often, it is nicer to have a customized dialog than using the built in browser one.

I briefly used the twitter bootstrap until it was discontinued with version 6. I looked around for alternatives, but the ones I found were complicated. I decided to try the JQuery UI one.

Here is my sample that I call when I am about to remove something from ng-grid;

    // Define the Dialog and its properties.
    $("<div>Are you sure?</div>").dialog({
        resizable: false,
        modal: true,
        title: "Modal",
        height: 150,
        width: 400,
        buttons: {
            "Yes": function () {
                $(this).dialog('close');
                //proceed with delete...
                /*commented out but left in to show how I am using it in angular
                var index = $scope.myData.indexOf(row.entity);

                $http['delete']('/EPContacts.svc/json/' + $scope.myData[row.rowIndex].RecordID).success(function () { console.log("groovy baby"); });

                $scope.gridOptions.selectItem(index, false);
                $scope.myData.splice(index, 1);
                */
            },
            "No": function () {
                $(this).dialog('close');
                return;
            }
        }
    });

I hope this helps someone. I was pulling my hair out when I needed to upgrade ui-bootstrap-tpls.js but it broke my existing dialog. I came into work this morning, tried a few things and then realized I was over complicating.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionpoiuytrezView Question on Stackoverflow
Solution 1 - JavascriptMichael LowView Answer on Stackoverflow
Solution 2 - JavascriptmikeborghView Answer on Stackoverflow
Solution 3 - JavascriptKailasView Answer on Stackoverflow
Solution 4 - JavascriptVBMaliView Answer on Stackoverflow
Solution 5 - JavascriptStepan RihaView Answer on Stackoverflow
Solution 6 - Javascriptom471987View Answer on Stackoverflow
Solution 7 - JavascriptNanuView Answer on Stackoverflow
Solution 8 - JavascriptJames KleehView Answer on Stackoverflow
Solution 9 - JavascriptscarlzView Answer on Stackoverflow
Solution 10 - JavascriptAnil SinghView Answer on Stackoverflow
Solution 11 - JavascriptJustinas JakavonisView Answer on Stackoverflow
Solution 12 - JavascriptJuanma JuradoView Answer on Stackoverflow
Solution 13 - JavascriptMerlinView Answer on Stackoverflow
Solution 14 - JavascriptFreezystemView Answer on Stackoverflow
Solution 15 - JavascriptRama KrishnaView Answer on Stackoverflow
Solution 16 - JavascriptazharView Answer on Stackoverflow
Solution 17 - JavascriptDoug WeemsView Answer on Stackoverflow