mirror of
https://github.com/ansible/awx.git
synced 2026-05-07 17:37:37 -02:30
Fixes: inconsistent form validity & failing redirect after saving a
project
This commit is contained in:
@@ -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');
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}])
|
}])
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user