Fixes: inconsistent form validity & failing redirect after saving a

project
This commit is contained in:
Leigh Johnson
2016-11-02 15:39:07 -04:00
parent eaca67af18
commit d67bc0654c
3 changed files with 39 additions and 10 deletions

View File

@@ -357,7 +357,7 @@ export function ProjectsAdd($scope, $rootScope, $compile, $location, $log,
Rest.post(data) Rest.post(data)
.success(function(data) { .success(function(data) {
$scope.addedItem = data.id; $scope.addedItem = data.id;
$state.go('projects.edit', { id: data.id }, { reload: true }); $state.go('projects.edit', { project_id: data.id }, { reload: true });
}) })
.error(function(data, status) { .error(function(data, status) {
Wait('stop'); Wait('stop');

View File

@@ -391,7 +391,7 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'JobsHelper'])
.directive('awlookup', ['Rest', 'GetBasePath', '$q', function(Rest, GetBasePath, $q) { .directive('awlookup', ['Rest', 'GetBasePath', '$q', function(Rest, GetBasePath, $q) {
return { return {
require: 'ngModel', require: 'ngModel',
link: function(scope, elm, attrs, ctrl) { link: function(scope, elm, attrs, fieldCtrl) {
let query, let query,
basePath, basePath,
@@ -399,8 +399,18 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'JobsHelper'])
// query the API to see if field value corresponds to a valid resource // query the API to see if field value corresponds to a valid resource
// .ng-pending will be applied to the directive element while the request is outstanding // .ng-pending will be applied to the directive element while the request is outstanding
ctrl.$asyncValidators.validResource = function(modelValue, viewValue) { // form.$pending will contain object reference to any ngModelControllers with outstanding requests
if (viewValue) { fieldCtrl.$asyncValidators.validResource = function(modelValue, viewValue) {
applyValidationStrategy(viewValue, fieldCtrl);
return defer.promise;
};
function applyValidationStrategy(viewValue, ctrl) {
// use supplied data attributes to build an endpoint, query, resolve outstanding promise
function applyValidation(viewValue) {
basePath = GetBasePath(elm.attr('data-basePath')) || elm.attr('data-basePath'); basePath = GetBasePath(elm.attr('data-basePath')) || elm.attr('data-basePath');
query = elm.attr('data-query'); query = elm.attr('data-query');
query = query.replace(/\:value/, encodeURI(viewValue)); query = query.replace(/\:value/, encodeURI(viewValue));
@@ -412,17 +422,34 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'JobsHelper'])
.then((res) => { .then((res) => {
if (res.data.results.length > 0) { if (res.data.results.length > 0) {
scope[elm.attr('data-source')] = res.data.results[0].id; scope[elm.attr('data-source')] = res.data.results[0].id;
ctrl.$setValidity('awlookup', true); return setValidity(ctrl, true);
defer.resolve(true);
} else { } else {
scope[elm.attr('data-source')] = null; scope[elm.attr('data-source')] = null;
ctrl.$setValidity('awlookup', false); return setValidity(ctrl, false);
defer.resolve(false);
} }
}); });
} }
return defer.promise;
}; function setValidity(ctrl, validity){
ctrl.$setValidity('awlookup', validity);
return defer.resolve(validity);
}
// Three common cases for clarity:
// 1) Field is not required & pristine. Pass validation & skip async $pending state
// 2) Field is required. Always validate & use async $pending state
// 3) Field is not required, but is not $pristine. Always validate & use async $pending state
// case 1
if (!ctrl.$validators.required && ctrl.$pristine) {
return setValidity(ctrl, true);
}
// case 2 & 3
else {
return applyValidation(viewValue);
}
}
} }
}; };
}]) }])

View File

@@ -1140,6 +1140,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
html += "ng-model=\"" + field.sourceModel + '_' + field.sourceField + "\" "; html += "ng-model=\"" + field.sourceModel + '_' + field.sourceField + "\" ";
html += "name=\"" + field.sourceModel + '_' + field.sourceField + "\" "; html += "name=\"" + field.sourceModel + '_' + field.sourceField + "\" ";
html += "class=\"form-control\" "; html += "class=\"form-control\" ";
html += (field.required) ? 'required ' : '';
html += (field.ngChange) ? this.attr(field, 'ngChange') : ""; html += (field.ngChange) ? this.attr(field, 'ngChange') : "";
html += (field.ngDisabled) ? this.attr(field, 'ngDisabled') : "" ; html += (field.ngDisabled) ? this.attr(field, 'ngDisabled') : "" ;
html += (field.ngRequired) ? this.attr(field, 'ngRequired') : ""; html += (field.ngRequired) ? this.attr(field, 'ngRequired') : "";
@@ -1156,6 +1157,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
html += `data-basePath="${field.basePath}"`; html += `data-basePath="${field.basePath}"`;
html += `data-source="${field.sourceModel}"`; html += `data-source="${field.sourceModel}"`;
html += `data-query="?${field.sourceField}__iexact=:value"`; html += `data-query="?${field.sourceField}__iexact=:value"`;
html += `ng-model-options="{ updateOn: 'default blur', debounce: { 'default': 300, 'blur': 0 } }"`;
html += " awlookup >\n"; html += " awlookup >\n";
html += "</div>\n"; html += "</div>\n";