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)
.success(function(data) {
$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) {
Wait('stop');

View File

@ -391,7 +391,7 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'JobsHelper'])
.directive('awlookup', ['Rest', 'GetBasePath', '$q', function(Rest, GetBasePath, $q) {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
link: function(scope, elm, attrs, fieldCtrl) {
let query,
basePath,
@ -399,8 +399,18 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'JobsHelper'])
// 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
ctrl.$asyncValidators.validResource = function(modelValue, viewValue) {
if (viewValue) {
// form.$pending will contain object reference to any ngModelControllers with outstanding requests
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');
query = elm.attr('data-query');
query = query.replace(/\:value/, encodeURI(viewValue));
@ -412,17 +422,34 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'JobsHelper'])
.then((res) => {
if (res.data.results.length > 0) {
scope[elm.attr('data-source')] = res.data.results[0].id;
ctrl.$setValidity('awlookup', true);
defer.resolve(true);
return setValidity(ctrl, true);
} else {
scope[elm.attr('data-source')] = null;
ctrl.$setValidity('awlookup', false);
defer.resolve(false);
return setValidity(ctrl, 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 += "name=\"" + field.sourceModel + '_' + field.sourceField + "\" ";
html += "class=\"form-control\" ";
html += (field.required) ? 'required ' : '';
html += (field.ngChange) ? this.attr(field, 'ngChange') : "";
html += (field.ngDisabled) ? this.attr(field, 'ngDisabled') : "" ;
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-source="${field.sourceModel}"`;
html += `data-query="?${field.sourceField}__iexact=:value"`;
html += `ng-model-options="{ updateOn: 'default blur', debounce: { 'default': 300, 'blur': 0 } }"`;
html += " awlookup >\n";
html += "</div>\n";