I'm trying to stop navigation on my application if any form made changes and try to navigate without saving changes.
i want to show a dialog to show whether to save navigate or discard or cancel navigation action.
i'm using angular ui.routing
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/dashboard');
$stateProvider
.state('dashboard', {
url: '/dashboard',
templateUrl: '/application/private/views/dashboard.html'
})
.state('websites', {
url: '/websites',
templateUrl: '/application/private/views/websites.html'
})
});
i was planning to have implementation something like using angularjs service singleton
app.service('dirtyCheckService', function ($rootScope, dialogService){
});
and on controller level i can write a submit click like this
app.controller('formSubmitCtrl', function ($scope, dirtyCheckService){
dirtyCheckService.checkForm($scope).then(function(){
//allow navigation
},function(){
//not allowed}
});
i'm not sure is there easy way exist already or not
thanks you
The answer is: It is ok to move that kind of check into service/factory - for some further reuse. Also, here is some example at least to show how to - plunker
A factory:
.factory('CheckStateChangeService', function($rootScope){
var addCheck = function($scope){
var removeListener = $rootScope.$on('$stateChangeStart'
, function (event, toState, toParams, fromState, fromParams) {
if($scope.form.$pristine)
{
return;
}
var shouldContinue = confirm("The form has changed" +
", do you want to continue without saving");
if(shouldContinue)
{
return;
}
event.preventDefault();
});
$scope.$on("$destroy", removeListener);
};
return { checkFormOnStateChange : addCheck };
})
And having a view
like this:
<div>
<form name="form">
<dl>
<dt>Name</dt>
<dd><input type="text" ng-model="person.Name" />
<dt>Age</dt>
<dd><input type="number" ng-model="person.Age" />
</dl>
</form>
</div>
And the controller:
.controller('MyCtrl', function($scope, CheckStateChangeService) {
$scope.person = { Name: "name", Age: 18 };
CheckStateChangeService.checkFormOnStateChange($scope);
})
There is an example
You're right about a service being the way to do this, something like this should do:
$scope.$watch("myForm.$dirty",function(v){
dirtyCheckService.setDirty(v);
},true)
Then maybe somewhere in your app, such as the run block:
app.run(function($rootScope,dirtyCheckService){
$rootScope.$on('$locationChangeStart', function (event, next, prev) {
if(dirtyCheckService.isFormDirty()){
event.preventDefault();
}
}
})
Of course the above will only work given that you set your form to pristine once the user saves their changes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With