Prompt confirm before Leaving edited html form

后端 未结 6 1290
被撕碎了的回忆
被撕碎了的回忆 2021-02-04 18:50

If user tries to leave unsaved edited form, a message box pop-up

\"This page is asking you to confirm that you want to leave - data you have entered may not be saved. Le

相关标签:
6条回答
  • 2021-02-04 18:51

    I think you would need to use $window.alert or $window.confirm or beforeroutechange

    Angular documentation

    0 讨论(0)
  • 2021-02-04 18:58

    You can easily protect your form with jQuery with this simple unobtrusive code. Put in just before your </body> closing tag.

    (function () {
        jQuery('form').one('change', function () {
            window.onbeforeunload = function () {
                return 'Form protection';
            };
        });
    })();
    
    0 讨论(0)
  • 2021-02-04 19:01

    If you want to cancel the route change when you determine your form is dirty, you can do this:

    $rootScope.$on('$locationChangeStart', function(event) {
      event.preventDefault();
    });
    

    This will cancel the routing and keep you on the current page.

    0 讨论(0)
  • 2021-02-04 19:02

    You could use the "onbeforeunload" event. The syntax is as follows:

    window.onbeforeunload = function () {
        return "Your text string you want displayed in the box";
    }
    

    This event will popup that confirmation dialog that you described above asking whether or not the user truly wants to leave the page.

    Hope this helps.

    0 讨论(0)
  • 2021-02-04 19:03

    I liked @blesh's answer, but I think it fails to account for internal url changes (for example, if you use ngView on your application and visit different internal views). window.onbeforeunload never gets called when the hash # changes. In this case, you have to listen to both window.onbeforeunload and $locationChangeStart:

    app.controller('OtherCtrl', ['$scope', '$window', '$location', '$rootScope', function($scope, $window, $location, $rootScope) {
      $scope.message = "This time you get a confirmation.";
      $scope.navigate = function() {
        $location.path("/main");
      }
      var getMessage = function() {
        if($scope.myForm.$dirty) {
          return $scope.message;
        } else {
          return null;
        }
      }
      $window.onbeforeunload = getMessage;
      var $offFunction = $rootScope.$on('$locationChangeStart', function(e) {
        var message = getMessage();
        if(message && !confirm($scope.message)) {
          e.preventDefault();
        } else {
          $offFunction();
        }
      });
    }]);
    

    See plunkr here: http://plnkr.co/edit/R0Riek?p=preview

    0 讨论(0)
  • Warlock's answer is partly right, but in doing so, you'd break testability.

    In Angular, you'd want to use $window, and you'll want to watch $dirty on your form. You'll need to have a named form, notice name="myForm" below. Then you can $watch $dirty on the form in your $scope:

    app.controller('MainCtrl', function($scope, $window) {
      $scope.name = 'World';
      var win = $window;
      $scope.$watch('myForm.$dirty', function(value) {
        if(value) {
          win.onbeforeunload = function(){
            return 'Your message here';
          };
        }
      });
    });
    

    HTML

    <form name="myForm">
      Name: <input type="text" ng-model="name"/>
    </form>
    

    Here's a plunk to demonstrate: http://plnkr.co/edit/3NHpU1

    0 讨论(0)
提交回复
热议问题