ng-clickの確認ダイアログ-AngularJS


85

ng-clickカスタムangularjsディレクティブを使用して確認ダイアログを設定しようとしています:

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)
                    }
                });
            }
        };
}])

これはうまく機能しますが、残念ながら、私のディレクティブを使用したタグ内の式は評価されません。

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

(この場合、名前は評価されません)。ディレクティブのターミナルパラメータが原因のようです。回避策のアイデアはありますか?

コードをテストするには:http//plnkr.co/edit/EHmRpfwsgSfEFVMgRLgj?p = Preview


この場合、なぜターミナルを使用するのですか?それがなくても完全に機能するようです(そしてあなたはそれを知っています)。なぜあなたはそれがあなたの指令で必要だと思うのか疑問に思います。
Simon Belanger 2013

@SimonBelanger terminal = falseの場合、確認ダイアログで「キャンセル」をクリックしても、sayHi()がトリガーされます。私の目標は、ユーザーがキャンセルをクリックした場合にsayHi()を呼び出さないことです。
poiuytrez 2013

回答:


92

を使用しなくてもかまわない場合は、問題なくng-click動作します。クリックハンドラーが2回トリガーされるのを回避しながら、名前を別の名前に変更して属性を読み取ることができます。現時点で問題が発生します。

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

問題は、terminal他のディレクティブに実行しないように指示することだと思います。withのデータバインディング{{ }}は、ng-bindディレクティブの単なるエイリアスであり、おそらくterminal。によってキャンセルされます。


13
このコードスニペットは、現在のバージョンのAngularでは機能しなくなりました。scope。$ eval(..)はscope。$ apply(..)に置き換える必要があります
CoolTapes 2014年

E2E-テストとJSの確認ダイアログのためにこの質問をチェックしてください stackoverflow.com/questions/16424961/...
ndequeker

これは機能しますが、Chromeの[このページを避けて追加のダイアログを作成する]チェックボックスをオンにするとどうなりますか?:s
bigpony 2016年

58

クリーンな指令アプローチ。

更新:古い回答(2014)

基本的にng-clickイベントをインターセプトし、ng-confirm-click="message"ディレクティブに含まれるメッセージを表示して、ユーザーに確認を求めます。確認をクリックすると通常のng-click実行が実行され、クリックしないとスクリプトが終了してng-click実行されません。

<!-- 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();
          }
        });
      }
    }
  }
]);

Zach Snowのコードクレジット:http//zachsnow.com/#! / blog / 2013 / confirming-ng-click /

更新:新しい回答(2016)

1)前者(「ng」)はネイティブの角度ディレクティブ用に予約されているため、プレフィックスを「ng」から「mw」に変更しました。

2)ng-clickイベントをインターセプトする代わりに、関数とメッセージを渡すようにディレクティブを変更しました。

3)デフォルトの「Areyousure?」を追加しました カスタムメッセージが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();
          }
        });
      }
    }
  }
]);

8
Nb、jQueryが必要
egonlegs 2014

1
これは私にはうまくいきません。確認が表示されず、クリックが続行されます。他の誰か?
OneHoopyFrood 2015年

最初にng-clickクリックハンドラーのバインドを解除してから、すぐに停止してデフォルトを防止するのは悪い考えだと思います
James Kleeh 2015年

OneHoopyFrood、ng-click = ""に有効な関数が必要です。そうでないと、失敗します。ありがとう。
mikeborgh 2016年

なぜステップ2)ng-clickイベントをインターセプトする代わりに、関数とメッセージを渡すようにディレクティブを変更したのですか?
シルバー

46

私にとっては、https://www.w3schools.com/js/js_popup.aspで、ブラウザのデフォルトの確認ダイアログボックスが非常に機能しました。これを試してみました:

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

シンプル.. :)
しかし、私はあなたがそれをカスタマイズすることはできないと思います。「キャンセル」または「OK」ボタンで表示されます。

編集:

イオンフレームワークを使用している場合は、次のようにionicPopupダイアログを使用する必要があります。

// 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
     }
   });
 };

詳細については、$ ionicPopupを参照してください。


確かにきれいに見えますが、Angularの宣言型アプローチに反していると思います。このアプローチでは、コントローラー内にビューロジックを配置するのは簡単です。可能であれば、コントローラーをUI要素からクリーンに保つことが役立つ場合があります。
ジム・アホ

1
すでにブール値を返している== trueため、この場合は完全に不要なを取り除くことができますconfirm()。JSにタイプを強制してtrueと比較させる必要はありません。
レオラム2015

10

コアJavaScriptとAngularjsを使用すると非常に簡単です。

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

[OK]をクリックすると、削除操作が実行されます。それ以外の場合は実行されません。* idは、削除するパラメーター、レコードです。


5

それがterminal: falseボタン内の処理をブロックしているので、使用したくありません。代わりに、デフォルトの動作を防ぐためにlinkクリアでattr.ngClick

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)
          }
        });
      }
    };
  }
]);

plunkerで参照するバージョンのAngularで機能しますが、ajax.googleapis.com / ajax / libs / angularjs / 1.2.15 /angular.min.jsを参照すると期待どおりに機能しません。
ChrisW 2014年

最終的に、ngClickは「クリック」への単純なバインディング以上の方法を実行するため、提案されたアプローチは一部のケースでのみ機能します。より正しいアプローチは、個別の属性を介するのではなく、ng-clickハンドラーで確認を処理することだと思います。
Stepan Riha 2014年

4

今日の日付では、このソリューションは私のために機能します:

/**
 * 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);
                }
            });
        }
    }
}]);

クレジット:https//gist.github.com/asafge/7430497#file-ng-really-js



4

ng-clickコンパイルを使用してng-click式をラップすることにより、一緒に機能する角度のみのソリューションが可能です。

指令:

.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>

3
    $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;
        }
    }

コードはすべてを言います


1

HTML5コードサンプル

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

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();
       });
     }
    };
});

1

確認ダイアログは、AngularJSマテリアルを使用して実装できます。

$ mdDialogは、アプリ上でダイアログを開き、重要な情報についてユーザーに通知したり、ユーザーに意思決定を要求したりします。セットアップには、単純なPromiseAPIと通常のオブジェクト構文の2つのアプローチがあります。

実装例:AngularMaterial-ダイアログ


0

ui-routerを使用している場合は、[キャンセル]または[承認]ボタンでURLを置き換えます。これを防ぐために、次のような条件文のそれぞれの場合にfalseを返すことができます。

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;
    });
  }
}; });

0

非常に単純な角度ソリューション

idは、メッセージありでもメッセージなしでも使用できます。メッセージがない場合、デフォルトのメッセージが表示されます。

指令

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();
                }
            });
        }
    }
}]);

コントローラ

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

HTML

メッセージ付き

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

メッセージなし

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

0

ここでは、角度の約束を使用して、クリーンでシンプルなソリューションであり$q$windowそしてネイティブ.confirm()モーダルは:

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

ここでは、controllerAs構文とES6矢印関数を使用していますが、プレーンな古いES5でも機能しています。


0

anglejsのブートストラップを使用して確認ポップアップを削除します

非常に簡単です。ブートストラップコンフォメーションポップアップを使用することで、これに対する1つの解決策があります。ここで私は提供されます

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

ブートストラップモデルのポップアップ:

<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');
};

[削除]ボタンをクリックすると、ブートストラップの削除コンフォメーションポップアップが開き、[はい]をクリックするとボタンの行が削除されます。


0

ng-クリックして戻る100%動作することを確認

HTMLファイルでdelete_plot()関数を呼び出します

<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")

        }
    }

-1

AngularJSに確認ダイアログが組み込まれているといいのですが。多くの場合、組み込みのブラウザダイアログを使用するよりも、カスタマイズされたダイアログを使用する方が適切です。

バージョン6で廃止されるまで、Twitterブートストラップを簡単に使用しました。代替案を探しましたが、見つけたものは複雑でした。JQueryUIを試してみることにしました。

これは、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;
            }
        }
    });

これが誰かに役立つことを願っています。ui-bootstrap-tpls.jsをアップグレードする必要があるときに髪を引っ張っていましたが、既存のダイアログが壊れました。私は今朝仕事に就き、いくつかのことを試みましたが、それから私が複雑になりすぎていることに気づきました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.