Estou tentando configurar uma caixa de diálogo de confirmação ng-click
usando uma diretiva angularjs personalizada:
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)
}
});
}
};
}])
Isso funciona muito bem, mas, infelizmente, as expressões dentro da tag usando minha diretiva não são avaliadas:
<button ng-click="sayHi()" ng-confirm-click="Would you like to say hi?">Say hi to {{ name }}</button>
(o nome não é avaliado neste caso). Parece ser devido ao parâmetro terminal da minha diretiva. Você tem alguma ideia de solução alternativa?
Para testar meu código: http://plnkr.co/edit/EHmRpfwsgSfEFVMgRLgj?p=preview
Respostas:
Se você não se importa em não usar
ng-click
, funciona bem. Você pode simplesmente renomeá-lo para outra coisa e ainda ler o atributo, evitando que o manipulador de cliques seja disparado duas vezes, problema que existe no momento.http://plnkr.co/edit/YWr6o2?p=preview
Acho que o problema é
terminal
instruir outras diretivas para não executar. A vinculação de dados com{{ }}
é apenas um alias para ang-bind
diretiva, que é presumivelmente cancelada porterminal
.fonte
Uma abordagem diretiva limpa.
Atualização: Resposta Antiga (2014)
Basicamente, ele intercepta o
ng-click
evento, exibe a mensagem contida nang-confirm-click="message"
diretiva e solicita a confirmação do usuário. Se confirmar for clicado, o normal éng-click
executado; caso contrário, o script termina eng-click
não é executado.<!-- 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(); } }); } } } ]);
Crédito do código para Zach Snow: http://zachsnow.com/#!/blog/2013/confirming-ng-click/
Atualização: Nova Resposta (2016)
1) Prefixo alterado de 'ng' para 'mw', pois o anterior ('ng') é reservado para diretivas angulares nativas.
2) Diretiva modificada para passar uma função e mensagem em vez de interceptar o evento ng-click.
3) Adicionado o padrão "Tem certeza?" mensagem no caso de uma mensagem personalizada não ser fornecida para 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(); } }); } } } ]);
fonte
Para mim, https://www.w3schools.com/js/js_popup.asp , a caixa de diálogo de confirmação padrão do navegador funcionou muito bem. acabei de experimentar isto:
$scope.delete = function() { if (confirm("sure to delete")) { // todo code for deletion } };
Simples .. :)
Mas acho que você não pode personalizá-lo. Ele aparecerá com o botão "Cancelar" ou "Ok".
EDITAR:
Caso você esteja usando uma estrutura iônica, é necessário usar a caixa de diálogo ionicPopup como em:
// 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 } }); };
Para mais detalhes, consulte: $ ionicPopup
fonte
== true
, o que é completamente desnecessário neste caso, porqueconfirm()
já retorna um booleano. Não há necessidade de obter JS para digitar, coagi-lo e compará-lo com verdadeiro.É tão simples usar o núcleo javascript + angular js:
$scope.delete = function(id) { if (confirm("Are you sure?")) { //do your process of delete using angular js. } }
Se você clicar em OK, a operação de exclusão ocorrerá; caso contrário, não. * id é o parâmetro, registro que você deseja excluir.
fonte
Você não deseja usar,
terminal: false
pois é isso que está bloqueando o processamento de dentro do botão. Em vez disso, em seulink
claro oattr.ngClick
para evitar o comportamento padrão.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) } }); } }; } ]);
fonte
Na data de hoje, esta solução funciona para mim:
/** * 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); } }); } } }]);
Créditos: https://gist.github.com/asafge/7430497#file-ng-really-js
fonte
Eu criei um módulo exatamente para isso que depende do serviço Angular-UI $ modal.
https://github.com/Schlogen/angular-confirm
fonte
Uma solução apenas angular que funciona paralelamente
ng-click
é possível usando compilar para envolver ang-click
expressão.Diretriz:
.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>
fonte
$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; } }
Código diz tudo
fonte
Amostra de código HTML 5
<button href="#" ng-click="shoutOut()" confirmation-needed="Do you really want to shout?">Click!</button>
Amostra de código da diretiva personalizada AngularJs
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(); }); } }; });
fonte
A caixa de diálogo de confirmação pode ser implementada usando o material AngularJS :
Exemplo de implementação: Angular Material - Diálogos
fonte
Se você usa ui-roteador, o botão cancelar ou aceitar substituirá o url. Para evitar isso, você pode retornar falso em cada caso da sentença condicional como esta:
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; }); } }; });
fonte
Uma solução angular muito simples
Você pode usar id com uma mensagem ou sem. Sem mensagem, a mensagem padrão será exibida.
Diretriz
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(); } }); } } }]);
Controlador
$scope.sayHello = function(){ alert("hello") }
HTML
Com uma mensagem
<span ng-click="sayHello()" ng-confirm-message="Do you want to say Hello ?" >Say Hello!</span>
Sem mensagem
<span ng-click="sayHello()" ng-confirm-message>Say Hello!</span>
fonte
Aqui está uma solução limpa e simples, utilizando promessas angulares
$q
,$window
e nativa.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 } }); }; });
Aqui estou usando a
controllerAs
sintaxe e as funções de seta do ES6, mas também está funcionando no ES5.fonte
Apague o popup de confirmação usando bootstrap no angularjs
muito simples .. Eu tenho uma solução para isso usando o pop-up de conformação de bootstrap. Aqui estou eu
<button ng-click="deletepopup($index)">Delete</button>
no pop-up do modelo de bootstrap:
<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'); };
Quando eu clico no botão Excluir bootstrap, o pop-up de confirmação de exclusão é aberto e quando eu clico no botão Sim, a linha é excluída.
fonte
<i class="fa fa-trash delete-plot" ng-click="delete_plot()"></i>
$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") } }
fonte
Gostaria que o AngularJS tivesse uma caixa de diálogo de confirmação embutida. Freqüentemente, é melhor ter uma caixa de diálogo personalizada do que usar o do navegador embutido.
Usei brevemente o bootstrap do Twitter até que ele foi descontinuado com a versão 6. Procurei alternativas, mas as que encontrei eram complicadas. Decidi experimentar o JQuery UI.
Aqui está meu exemplo que chamo quando estou prestes a remover algo do 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; } } });
Espero que isso ajude alguém. Eu estava puxando meu cabelo quando precisei atualizar ui-bootstrap-tpls.js, mas quebrou minha caixa de diálogo existente. Cheguei ao trabalho esta manhã, tentei algumas coisas e então percebi que estava complicando demais.
fonte