Reputation: 71
I have a dropdownlist and need to cancel the ng-change event if user does not want to proceed. The previousPortfolioId value is setting correctly in the $scope but the view is still displaying the changed value. I tried $scope.$apply also, but not working. How do I cancel the ng-change event?
Template.html
<select style="width:200px;" ng-model="SelectedPortfolioId" ng-change="PortfolioSelectionChange(SelectedPortfolioId)" ng-options="Portfolio.BlendId as Portfolio.BlendName for Portfolio in Portfolios">
</select>
Controller.js
$scope.PortfolioSelectionChange = function (SelectedPortfolioId) {
var previousPortfolioId = $scope.SelectedPortfolioId;
if ($scope.IsPageDirty) {
var promise = DisplayConfirmation('Your unsaved changes will be lost. Do you want to continue?');
promise.done(function () {
// do something
});
promise.fail(function () {
// cancel the change
$scope.SelectedPortfolioId = previousPortfolioId;
});
}
};
Upvotes: 5
Views: 3159
Reputation: 1834
Firstly you cannot cancel a change event. See here: https://developer.mozilla.org/en-US/docs/Web/Events/change It states it is not cancelable. However you can prevent the model bound to the form control from being changed and then revert the form fields value.
You can do this by using ng-model-options and setting the updateOn to a custom event. ng-model-options="{updateOn:'confirmed'}"
The directive below will show a confirm message and if accepted uses the ngmodelcontroller to update the model. If the confirm is denied then the form fields value is set back to what is stored in the model value.
This is good because any watches targeting the same model value wont ever trigger.
(function () {
'use strict';
angular.module('app.registration')
.directive('confirm', function ($window) {
return {
require: 'ngModel',
link: function (scope, el, att, ctrl) {
var message = att.confirm;
el.on('change', function (){
var val = ctrl.$modelValue;
if (!val || $window.confirm(message)) {
ctrl.$setViewValue(el.val(), 'confirmed');
ctrl.$$debounceViewValueCommit('confirmed');
}
else {
el.val(val);
}
});
}
};
});
})();
Upvotes: 1
Reputation: 5665
I actually don't like my answer (I was here looking for a better one!), but as far as I can see there's nothing like an event.cancel you can call. Editing the variable during its change event just doesn't seem to take, so what I ended up doing was passing $timeout to my controller and queueing the change:
promise.fail(function () {
// cancel the change
$timeout(function () {
$scope.SelectedPortfolioId = previousPortfolioId;
}, 0);
});
Upvotes: 1
Reputation: 1860
Wouldn't just a plain ol' confirm work?
$scope.PortfolioSelectionChange = function(portfolio) {
if (confirm('Your unsaved changes will be lost. Do you want to continue?')) {
// proceed with what you need to do
}
}
Upvotes: 0