diff --git a/awx/ui/client/src/adhoc/adhoc.form.js b/awx/ui/client/src/adhoc/adhoc.form.js index 2632a0e7bb..4afa92525e 100644 --- a/awx/ui/client/src/adhoc/adhoc.form.js +++ b/awx/ui/client/src/adhoc/adhoc.form.js @@ -74,7 +74,7 @@ export default function() { dataPlacement: 'right', dataContainer: 'body', awRequiredWhen: { - variable: 'credRequired', + reqExpression: 'credRequired', init: 'false' } }, diff --git a/awx/ui/client/src/forms/Credentials.js b/awx/ui/client/src/forms/Credentials.js index 781e9459f0..7865383ad3 100644 --- a/awx/ui/client/src/forms/Credentials.js +++ b/awx/ui/client/src/forms/Credentials.js @@ -103,7 +103,7 @@ export default type: 'text', ngShow: "kind.value == 'aws'", awRequiredWhen: { - variable: "aws_required", + reqExpression: "aws_required", init: false }, autocomplete: false, @@ -115,7 +115,7 @@ export default type: 'sensitive', ngShow: "kind.value == 'aws'", awRequiredWhen: { - variable: "aws_required", + reqExpression: "aws_required", init: false }, autocomplete: false, @@ -149,7 +149,7 @@ export default dataContainer: "body", autocomplete: false, awRequiredWhen: { - variable: 'host_required', + reqExpression: 'host_required', init: false }, subForm: 'credentialSubForm' @@ -160,7 +160,7 @@ export default ngShow: "kind.value && kind.value !== 'aws' && " + "kind.value !== 'gce' && kind.value!=='azure'", awRequiredWhen: { - variable: 'username_required', + reqExpression: 'username_required', init: false }, autocomplete: false, @@ -171,7 +171,7 @@ export default type: 'email', ngShow: "kind.value === 'gce'", awRequiredWhen: { - variable: 'email_required', + reqExpression: 'email_required', init: false }, autocomplete: false, @@ -186,7 +186,7 @@ export default type: 'text', ngShow: "kind.value == 'azure'", awRequiredWhen: { - variable: 'subscription_required', + reqExpression: 'subscription_required', init: false }, addRequired: false, @@ -203,7 +203,7 @@ export default type: 'sensitive', ngShow: "kind.value == 'rax'", awRequiredWhen: { - variable: "rackspace_required", + reqExpression: "rackspace_required", init: false }, autocomplete: false, @@ -223,7 +223,7 @@ export default autocomplete: false, hasShowInputButton: true, awRequiredWhen: { - variable: "password_required", + reqExpression: "password_required", init: false }, subForm: "credentialSubForm" @@ -245,7 +245,7 @@ export default ngShow: "kind.value == 'ssh' || kind.value == 'scm' || " + "kind.value == 'gce' || kind.value == 'azure'", awRequiredWhen: { - variable: 'key_required', + reqExpression: 'key_required', init: true }, class: 'Form-textAreaLabel', @@ -319,7 +319,7 @@ export default addRequired: false, editRequired: false, awRequiredWhen: { - variable: 'project_required', + reqExpression: 'project_required', init: false }, subForm: 'credentialSubForm' diff --git a/awx/ui/client/src/forms/Inventories.js b/awx/ui/client/src/forms/Inventories.js index ce5d18de21..20ee5db148 100644 --- a/awx/ui/client/src/forms/Inventories.js +++ b/awx/ui/client/src/forms/Inventories.js @@ -42,7 +42,7 @@ export default sourceField: 'name', ngClick: 'lookUpOrganization()', awRequiredWhen: { - variable: "organizationrequired", + reqExpression: "organizationrequired", init: "true" } }, diff --git a/awx/ui/client/src/forms/JobTemplates.js b/awx/ui/client/src/forms/JobTemplates.js index 9799fb76a8..f5071773b5 100644 --- a/awx/ui/client/src/forms/JobTemplates.js +++ b/awx/ui/client/src/forms/JobTemplates.js @@ -58,7 +58,10 @@ export default sourceModel: 'inventory', sourceField: 'name', ngClick: 'lookUpInventory()', - awRequiredWhen: {variable: "inventoryrequired", init: "true" }, + awRequiredWhen: { + reqExpression: "inventoryrequired", + init: "true" + }, column: 1, awPopOver: "

Select the inventory containing the hosts you want this job to manage.

", dataTitle: 'Inventory', @@ -71,7 +74,10 @@ export default sourceModel: 'project', sourceField: 'name', ngClick: 'lookUpProject()', - awRequiredWhen: {variable: "projectrequired", init: "true" }, + awRequiredWhen: { + reqExpression: "projectrequired", + init: "true" + }, column: 1, awPopOver: "

Select the project containing the playbook you want this job to execute.

", dataTitle: 'Project', @@ -83,7 +89,10 @@ export default type:'select', ngOptions: 'book for book in playbook_options track by book', id: 'playbook-select', - awRequiredWhen: {variable: "playbookrequired", init: "true" }, + awRequiredWhen: { + reqExpression: "playbookrequired", + init: "true" + }, column: 1, awPopOver: "

Select the playbook to be executed by this job.

", dataTitle: 'Playbook', diff --git a/awx/ui/client/src/forms/Projects.js b/awx/ui/client/src/forms/Projects.js index ad391c941e..cf75609b1a 100644 --- a/awx/ui/client/src/forms/Projects.js +++ b/awx/ui/client/src/forms/Projects.js @@ -45,7 +45,7 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition']) sourceField: 'name', ngClick: 'lookUpOrganization()', awRequiredWhen: { - variable: "organizationrequired", + reqExpression: "organizationrequired", init: "true" }, awPopOver: '

A project must have at least one organization. Pick one organization now to create the project, and then after ' + @@ -95,7 +95,7 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition']) id: 'local-path-select', ngOptions: 'path.label for path in project_local_paths', awRequiredWhen: { - variable: "pathRequired", + reqExpression: "pathRequired", init: false }, ngShow: "scm_type.value == 'manual' && !showMissingPlaybooksAlert", @@ -111,7 +111,7 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition']) type: 'text', ngShow: "scm_type && scm_type.value !== 'manual'", awRequiredWhen: { - variable: "scmRequired", + reqExpression: "scmRequired", init: false }, subForm: 'sourceSubForm', diff --git a/awx/ui/client/src/forms/Source.js b/awx/ui/client/src/forms/Source.js index 1eee07b344..6bd94809c8 100644 --- a/awx/ui/client/src/forms/Source.js +++ b/awx/ui/client/src/forms/Source.js @@ -35,7 +35,7 @@ export default ngShow: "source && source.value == 'file'", type: 'text', awRequiredWhen: { - variable: "sourcePathRequired", + reqExpression: "sourcePathRequired", init: "false" } }, @@ -47,7 +47,7 @@ export default sourceField: 'name', ngClick: 'lookUpCredential()', awRequiredWhen: { - variable: "cloudCredentialRequired", + reqExpression: "cloudCredentialRequired", init: "false" } }, diff --git a/awx/ui/client/src/forms/Teams.js b/awx/ui/client/src/forms/Teams.js index e15b191900..471cda62c4 100644 --- a/awx/ui/client/src/forms/Teams.js +++ b/awx/ui/client/src/forms/Teams.js @@ -42,7 +42,7 @@ export default editRequire: false, ngClick: 'lookUpOrganization()', awRequiredWhen: { - variable: "orgrequired", + reqExpression: "orgrequired", init: true } } diff --git a/awx/ui/client/src/forms/Users.js b/awx/ui/client/src/forms/Users.js index f3af8243c7..d1c2c2613f 100644 --- a/awx/ui/client/src/forms/Users.js +++ b/awx/ui/client/src/forms/Users.js @@ -46,7 +46,7 @@ export default label: 'Username', type: 'text', awRequiredWhen: { - variable: "not_ldap_user", + reqExpression: "not_ldap_user", init: true }, autocomplete: false @@ -61,7 +61,7 @@ export default excludeMode: 'edit', ngClick: 'lookUpOrganization()', awRequiredWhen: { - variable: "orgrequired", + reqExpression: "orgrequired", init: true } }, diff --git a/awx/ui/client/src/helpers/Users.js b/awx/ui/client/src/helpers/Users.js index 61ddaa4ed9..7f09b486c3 100644 --- a/awx/ui/client/src/helpers/Users.js +++ b/awx/ui/client/src/helpers/Users.js @@ -3,7 +3,7 @@ * * All Rights Reserved *************************************************/ - + /** * @ngdoc function * @name helpers.function:Users @@ -30,12 +30,12 @@ export default UserForm.fields.email.readonly = false; UserForm.fields.email.editRequired = true; UserForm.fields.organization.awRequiredWhen = { - variable: "orgrequired", + reqExpression: "orgrequired", init: true }; UserForm.fields.organization.readonly = false; UserForm.fields.username.awRequiredWhen = { - variable: "not_ldap_user", + reqExpression: "not_ldap_user", init: true }; UserForm.fields.username.readonly = false; diff --git a/awx/ui/client/src/inventory-scripts/inventory-scripts.form.js b/awx/ui/client/src/inventory-scripts/inventory-scripts.form.js index 61d256a098..eb56f6df96 100644 --- a/awx/ui/client/src/inventory-scripts/inventory-scripts.form.js +++ b/awx/ui/client/src/inventory-scripts/inventory-scripts.form.js @@ -36,7 +36,7 @@ export default function() { label: 'Organization', type: 'lookup', awRequiredWhen: { - variable: "orgrequired", + reqExpression: "orgrequired", init: true }, sourceModel: 'organization', diff --git a/awx/ui/client/src/lookup/lookup.factory.js b/awx/ui/client/src/lookup/lookup.factory.js index ef4cfafba6..fb7f3e2b47 100644 --- a/awx/ui/client/src/lookup/lookup.factory.js +++ b/awx/ui/client/src/lookup/lookup.factory.js @@ -78,8 +78,8 @@ export default ['Rest', 'ProcessErrors', 'generateList', } if (parent_scope.mode === "add") { if (parent_scope[sourceModel + "_field"].awRequiredWhen && - parent_scope[sourceModel + "_field"].awRequiredWhen.variable && - parent_scope[parent_scope[sourceModel + "_field"].awRequiredWhen.variable]) { + parent_scope[sourceModel + "_field"].awRequiredWhen.reqExpression && + parent_scope.$eval(parent_scope[sourceModel + "_field"].awRequiredWhen.reqExpression)) { return true; } else if (parent_scope[sourceModel + "_field"].addRequired === true) { return true; diff --git a/awx/ui/client/src/shared/directives.js b/awx/ui/client/src/shared/directives.js index 17babdf4bc..70085d78cd 100644 --- a/awx/ui/client/src/shared/directives.js +++ b/awx/ui/client/src/shared/directives.js @@ -328,9 +328,9 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'JobsHelper']) }) // - // awRequiredWhen: { variable: "", init:"true|false" } + // awRequiredWhen: { reqExpression: "", init: "true|false" } // - // Make a field required conditionally using a scope variable. If the scope variable is true, the + // Make a field required conditionally using an expression. If the expression evaluates to true, the // field will be required. Otherwise, the required attribute will be removed. // .directive('awRequiredWhen', function() { @@ -338,47 +338,35 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'JobsHelper']) require: 'ngModel', link: function(scope, elm, attrs, ctrl) { - function checkIt () { + function updateRequired () { + var isRequired = scope.$eval(attrs.awRequiredWhen); + var viewValue = elm.val(), label, validity = true; - if ( scope[attrs.awRequiredWhen] && (elm.attr('required') === null || elm.attr('required') === undefined) ) { + label = $(elm).closest('.form-group').find('label').first(); + if ( isRequired && (elm.attr('required') === null || elm.attr('required') === undefined) ) { $(elm).attr('required','required'); - if ($(elm).hasClass('lookup') || $(elm).hasClass('ui-spinner-input')) { - $(elm).parent().parent().parent().find('label').first().addClass('prepend-asterisk'); - } - else { - $(elm).parent().parent().find('label').first().addClass('prepend-asterisk'); - } + $(label).addClass('prepend-asterisk'); } - else if (!scope[attrs.awRequiredWhen]) { + else if (!isRequired) { elm.removeAttr('required'); - if ($(elm).hasClass('lookup')) { - label = $(elm).parent().parent().parent().find('label').first(); - label.removeClass('prepend-asterisk'); - } - else { - $(elm).parent().parent().find('label').first().removeClass('prepend-asterisk'); - } + $(label).removeClass('prepend-asterisk'); } - if (scope[attrs.awRequiredWhen] && (viewValue === undefined || viewValue === null || viewValue === '')) { + if (isRequired && (viewValue === undefined || viewValue === null || viewValue === '')) { validity = false; } ctrl.$setValidity('required', validity); } + scope.$watchGroup([attrs.awRequiredWhen, $(elm).attr('name')], function() { + // watch for the aw-required-when expression to change value + updateRequired(); + }); + if (attrs.awrequiredInit !== undefined && attrs.awrequiredInit !== null) { + // We already set a watcher on the attribute above so no need to call updateRequired() in here scope[attrs.awRequiredWhen] = attrs.awrequiredInit; - checkIt(); } - scope.$watch(attrs.awRequiredWhen, function() { - // watch for the aw-required-when expression to change value - checkIt(); - }); - - scope.$watch($(elm).attr('name'), function() { - // watch for the field to change value - checkIt(); - }); } }; }) diff --git a/awx/ui/client/src/shared/form-generator.js b/awx/ui/client/src/shared/form-generator.js index e7e686443b..f4a0e26bfb 100644 --- a/awx/ui/client/src/shared/form-generator.js +++ b/awx/ui/client/src/shared/form-generator.js @@ -263,9 +263,6 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat var label, span; if (Empty($(this).attr('aw-required-when'))) { label = $(this).closest('.form-group').find('label').first(); - if ($(this).attr('type') === 'radio') { - label = $(this).parent().parent().parent().find('label').first(); - } if (label.length > 0) { span = label.children('span'); if (span.length > 0 && !span.first().hasClass('prepend-asterisk')) { @@ -791,8 +788,10 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat html += (field.awSurveyQuestion) ? "aw-survey-question" : "" ; html += (field.ask) ? "ng-disabled=\"" + fld + "_ask\" " : ""; html += (field.autocomplete !== undefined) ? this.attr(field, 'autocomplete') : ""; - html += (field.awRequiredWhen) ? "data-awrequired-init=\"" + field.awRequiredWhen.init + "\" aw-required-when=\"" + - field.awRequiredWhen.variable + "\" " : ""; + if(field.awRequiredWhen) { + html += field.awRequiredWhen.init ? "data-awrequired-init=\"" + field.awRequiredWhen.init + "\" " : ""; + html += field.awRequiredWhen.reqExpression ? "aw-required-when=\"" + field.awRequiredWhen.reqExpression + "\" " : ""; + } html += (field.awValidUrl) ? "aw-valid-url " : ""; html += (field.associated && this.form.fields[field.associated].ask) ? "ng-disabled=\"" + field.associated + "_ask\" " : ""; html += ">\n"; @@ -939,8 +938,10 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat html += "ng-disabled='" + _disabled + "'"; } html += (field.autocomplete !== undefined) ? this.attr(field, 'autocomplete') : ""; - html += (field.awRequiredWhen) ? "data-awrequired-init='" + field.awRequiredWhen.init + "' aw-required-when='" + - field.awRequiredWhen.variable + "' " : ""; + if(field.awRequiredWhen) { + html += field.awRequiredWhen.init ? "data-awrequired-init=\"" + field.awRequiredWhen.init + "\" " : ""; + html += field.awRequiredWhen.reqExpression ? "aw-required-when=\"" + field.awRequiredWhen.reqExpression + "\" " : ""; + } html += (field.awValidUrl) ? "aw-valid-url " : ""; html += (field.associated && this.form.fields[field.associated].ask) ? "ng-disabled='" + field.associated + "_foo' " : ""; html += ">\n"; @@ -1050,8 +1051,10 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat html += (field.ngRequired) ? "ng-required=\"" + field.ngRequired +"\"" : ""; html += (field.readonly || field.showonly) ? "readonly " : ""; html += (field.awDropFile) ? "aw-drop-file " : ""; - html += (field.awRequiredWhen) ? "data-awrequired-init=\"" + field.awRequiredWhen.init + "\" aw-required-when=\"" + - field.awRequiredWhen.variable + "\" " : ""; + if(field.awRequiredWhen) { + html += field.awRequiredWhen.init ? "data-awrequired-init=\"" + field.awRequiredWhen.init + "\" " : ""; + html += field.awRequiredWhen.reqExpression ? "aw-required-when=\"" + field.awRequiredWhen.reqExpression + "\" " : ""; + } html += "aw-watch >\n"; @@ -1089,8 +1092,10 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat //used for select2 combo boxes html += (field.multiSelect) ? "multiple " : ""; html += (field.readonly) ? "disabled " : ""; - html += (field.awRequiredWhen) ? "data-awrequired-init=\"" + field.awRequiredWhen.init + "\" aw-required-when=\"" + - field.awRequiredWhen.variable + "\" " : ""; + if(field.awRequiredWhen) { + html += field.awRequiredWhen.init ? "data-awrequired-init=\"" + field.awRequiredWhen.init + "\" " : ""; + html += field.awRequiredWhen.reqExpression ? "aw-required-when=\"" + field.awRequiredWhen.reqExpression + "\" " : ""; + } html += ">\n"; if(!field.multiSelect){ html += "

"; - html += "
"; - html += (options.mode === 'edit') ? this.form.editTitle : this.form.addTitle; - if(this.form.name === "user"){ - html+= "Admin"; + if(!(this.form.showHeader !== undefined && this.form.showHeader === false)) { + html += "
"; + html += "
"; + html += (options.mode === 'edit') ? this.form.editTitle : this.form.addTitle; + if(this.form.name === "user"){ + html+= "Admin"; + } + html += "
\n"; + if(this.form.cancelButton !== undefined && this.form.cancelButton === false) { + html += "
"; + html += "
"; + } else { + html += "
"; + html += "
\n"; + } + html += "
\n"; //end of Form-header } - html += "
\n"; - if(this.form.cancelButton !== undefined && this.form.cancelButton === false) { - html += "
"; - html += "
"; - } else { - html += "
"; - html += "
\n"; - } - html += "
\n"; //end of Form-header if (!_.isEmpty(this.form.related)) { var collection;