Implementation Details:
I'm using ui-router to load form page in ui-view div. I referred great example by Andres Ekdahi, How can i do $dirty check on multiple forms using same directive ?
form1
<form name="myForm" ng-controller="Controller" confirm-on-exit>
form2
<form name="iForm" ng-controller="Controller" confirm-on-exit ng-model="myModel">
app.js ( directive )
myApp.directive('confirmOnExit', function() {
return {
link: function($scope, elem, attrs) {
// condition when back page is pressed
window.onbeforeunload = function(){
if ($scope.myForm.$dirty) {
return "The formI is dirty, do you want to stay on the page?";
}
}
// condition when user try to load other form (via icons )
$scope.$on('$stateChangeStart', function(event, next, current) {
if ($scope.myForm.$dirty) {
if(!confirm("myForm. Do you want to continue ?")) {
event.preventDefault();
}
}
if ($scope.iForm.$dirty) {
if(!confirm("iform. Do you want to continue ?")) {
event.preventDefault();
}
}
});
}
};
});
Error:
First time on page load, the $dirty value is false. and I fill the form details and click third icon (file) and i get error for second form dirty check if ($scope.iForm.$dirty)
and for $dirty
in alert.
angular.js:12520 TypeError: Cannot read property '$dirty' of undefined
and
<form name="iForm" ng-controller="Controller" confirm-on-exit="" ng-model="myModel" class="ng-pristine ng-untouched ng-valid ng-scope">
Demo : Plunker
Make you directive more simpler by taking it from name
attribute of form
, so that only one condition will lie inside a directive & it can be reusable in many places.
<form name="myForm" ng-controller="Controller" confirm-on-exit>
Code
var form = $scope[attrs.name]; //which will take out form name & do search that inside scope
if (form.$dirty) { //form object would always exist, to make sure you could also add one more check `form &&`
if(!confirm("myForm. Do you want to continue ?")) {
event.preventDefault();
}
}