Confirmation dialog on ng-click - AngularJS
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
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
.
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="".
<!-- index.html -->
<button mw-confirm-click="publish()" mw-confirm-click-message="You are about to overwrite your PUBLISHED content!! Are you SURE you want to publish?">
Publish
</button>
// /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();
}
});
}
}
}
]);