Skip to content

Instantly share code, notes, and snippets.

@lucassus
Created June 27, 2014 19:33
Show Gist options
  • Save lucassus/9e7bbb89a630f3390b2f to your computer and use it in GitHub Desktop.
Save lucassus/9e7bbb89a630f3390b2f to your computer and use it in GitHub Desktop.
'use strict';
var app = angular.module('glossaryApp');
app.config(function($provide) {
$provide.decorator('$modal', function($delegate) {
var open = $delegate.open;
// decorate newly created modalInstance with some custom methods
$delegate.open = function() {
var modalInstance = open.apply(this, arguments);
modalInstance.freeze = function(freeze) {
modalInstance._freezed = freeze;
};
// return true when the modal instance is freezed and
// dismiss reason is 'backdrop click' or 'escape key press'
modalInstance.freezed = function(reason) {
if (!modalInstance._freezed) { return false; }
return _.contains(['backdrop click', 'escape key press'], reason);
};
return modalInstance;
};
return $delegate;
});
$provide.decorator('$modalStack', function($delegate) {
var dismiss = $delegate.dismiss;
// do nothing when the modal is freezed
// otherwise fallback to the old behaviour
$delegate.dismiss = function(modalInstance, reason) {
if (modalInstance.freezed(reason)) { return; }
dismiss.apply(this, arguments);
};
return $delegate;
});
});
app.directive('glFreezeModal', function($parse) {
return {
restrict: 'A',
require: 'form',
link: function(scope, element, attrs, form) {
var modalInstance = $parse(attrs.glFreezeModal)(scope);
scope.$watch(function() { return form.$dirty; }, function(dirty) {
modalInstance.freeze(dirty);
});
}
}
});
var FormCtrl = function($scope, $modalInstance, list) {
this.$modalInstance = $modalInstance;
this.list = list;
};
angular.extend(FormCtrl.prototype, {
submit: function(list) {
// create/update new record
var promise = list.isPersisted() ? list.$update() : list.$create();
// freeze the modal keyboard/backdrop close until request is complete
this.$modalInstance.freeze(true);
promise.finally(angular.bind(this, function() {
this.$modalInstance.freeze(false);
}));
// close the modal and resolve it with updated/created record
promise.then(angular.bind(this, function(list) {
this.$modalInstance.close(list);
}));
return promise;
},
cancel: function() {
this.$modalInstance.dismiss();
}
});
angular.module('glossaryApp')
.controller('list.FormCtrl', FormCtrl);
<div class="modal-header">
<h3 class="modal-title" ng-switch="formCtrl.list.isPersisted()">
<span ng-switch-when="true">Edit list</span>
<span ng-switch-when="false">Create list</span>
</h3>
</div>
<form name="listForm" novalidate
gl-submit="formCtrl.submit(formCtrl.list)"
gl-freeze-modal="formCtrl.$modalInstance">
<div class="modal-body">
<fieldset ng-disabled="listForm.$saving">
<div class="form-group" ng-class="{ 'has-error': listForm.name.$invalid && (listForm.$dirty || listForm.$submitted) }">
<label for="nameInput">Name</label>
<input type="text" name="name" id="nameInput" class="form-control"
placeholder="Enter list name" autocomplete="off"
server-error
ng-model="formCtrl.list.name" ng-required="true" gl-focus />
<p class="help-block" ng-show="listForm.name.$error.required && (listForm.$dirty || listForm.$submitted)">
Please enter the name.
</p>
<p class="help-block" ng-show="listForm.name.$error.server">
{{listForm.$serverErrors.name}}
</p>
</div>
<div class="form-group">
<label for="descriptionTextarea">Description</label>
<textarea name="description" id="descriptionTextarea"
class="form-control" rows="3"
ng-model="formCtrl.list.description"></textarea>
</div>
</fieldset>
</div>
<div class="modal-footer">
<fieldset ng-disabled="listForm.$saving">
<a class="btn btn-default" ng-click="formCtrl.cancel()">Cancel</a>
<button type="submit" class="btn btn-primary" ng-switch="formCtrl.list.isPersisted()">
<span ng-switch-when="true">Update</span>
<span ng-switch-when="false">Create</span>
</button>
</fieldset>
</div>
</form>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment