Fixed form-generator and awRequiredWhen directive to not overlap when setting * on required field labels. Fixed job submission to work with new cloud credential implementation.

This commit is contained in:
Chris Houseknecht
2013-11-04 04:03:55 +00:00
committed by Chris Church
parent 0466629718
commit bac22205a8
12 changed files with 280 additions and 84 deletions

View File

@@ -12,7 +12,7 @@
function CredentialsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, CredentialList, function CredentialsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, CredentialList,
GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller,
ClearScope, ProcessErrors, GetBasePath, SelectionInit) ClearScope, ProcessErrors, GetBasePath, SelectionInit, GetChoices)
{ {
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
//scope. //scope.
@@ -33,20 +33,45 @@ function CredentialsList ($scope, $rootScope, $location, $log, $routeParams, Res
scope.removePostRefresh(); scope.removePostRefresh();
} }
scope.removePostRefresh = scope.$on('PostRefresh', function() { scope.removePostRefresh = scope.$on('PostRefresh', function() {
// After a refresh, populate the organization name on each row list.fields.kind.searchOptions = scope.credential_kind_options;
// Translate the kind value
for(var i=0; i < scope.credentials.length; i++) { for(var i=0; i < scope.credentials.length; i++) {
/*
if (scope.credentials[i].summary_fields.user) { if (scope.credentials[i].summary_fields.user) {
scope.credentials[i].user_username = scope.credentials[i].summary_fields.user.username; scope.credentials[i].user_username = scope.credentials[i].summary_fields.user.username;
} }
if (scope.credentials[i].summary_fields.team) { if (scope.credentials[i].summary_fields.team) {
scope.credentials[i].team_name = scope.credentials[i].summary_fields.team.name; scope.credentials[i].team_name = scope.credentials[i].summary_fields.team.name;
} }
*/
for (var j=0; j < scope.credential_kind_options.length; j++) {
if (scope.credential_kind_options[j].value == scope.credentials[i].kind) {
scope.credentials[i].kind = scope.credential_kind_options[j].label
break;
}
}
} }
}); });
SearchInit({ scope: scope, set: 'credentials', list: list, url: defaultUrl }); if (scope.removeChoicesReady) {
PaginateInit({ scope: scope, list: list, url: defaultUrl }); scope.removeChoicesReady();
scope.search(list.iterator); }
scope.removeChoicesReady = scope.$on('choicesReady', function() {
SearchInit({ scope: scope, set: 'credentials', list: list, url: defaultUrl });
PaginateInit({ scope: scope, list: list, url: defaultUrl });
scope.search(list.iterator);
});
// Load the list of options for Kind
GetChoices({
scope: scope,
url: defaultUrl,
field: 'kind',
variable: 'credential_kind_options',
callback: 'choicesReady'
});
LoadBreadCrumbs(); LoadBreadCrumbs();
@@ -84,7 +109,7 @@ function CredentialsList ($scope, $rootScope, $location, $log, $routeParams, Res
CredentialsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'CredentialList', 'GenerateList', CredentialsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'CredentialList', 'GenerateList',
'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors',
'GetBasePath', 'SelectionInit']; 'GetBasePath', 'SelectionInit', 'GetChoices'];
function CredentialsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, CredentialForm, function CredentialsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, CredentialForm,
@@ -171,23 +196,39 @@ function CredentialsAdd ($scope, $rootScope, $compile, $location, $log, $routePa
var data = {} var data = {}
for (var fld in form.fields) { for (var fld in form.fields) {
if (scope[fld] === null) { if (fld !== 'access_key' && fld !== 'secret_key' && fld !== 'ssh_username' &&
data[fld] = ""; fld !== 'ssh_password') {
} if (scope[fld] === null) {
else { data[fld] = "";
data[fld] = scope[fld]; }
else {
data[fld] = scope[fld];
}
} }
} }
if (!Empty(scope.team)) { if (!Empty(scope.team)) {
data.team = scope.team; data.team = scope.team;
data.user = "";
} }
else { else {
data.user = scope.user; data.user = scope.user;
data.team = "";
} }
data['kind'] = scope['kind'].value; data['kind'] = scope['kind'].value;
switch (data['kind']) {
case 'ssh':
data['username'] = scope['ssh_username'];
data['password'] = scope['ssh_password'];
break;
case 'aws':
data['username'] = scope['access_key'];
data['password'] = scope['secret_key'];
break;
}
if (Empty(data.team) && Empty(data.user)) { if (Empty(data.team) && Empty(data.user)) {
Alert('Missing User or Team', 'You must provide either a User or a Team. If this credential will only be accessed by a specific ' + Alert('Missing User or Team', 'You must provide either a User or a Team. If this credential will only be accessed by a specific ' +
'user, select a User. To allow a team of users to access this credential, select a Team.', 'alert-danger'); 'user, select a User. To allow a team of users to access this credential, select a Team.', 'alert-danger');
@@ -353,6 +394,29 @@ function CredentialsEdit ($scope, $rootScope, $compile, $location, $log, $routeP
scope['owner'] = 'team'; scope['owner'] = 'team';
} }
master['owner'] = scope['owner']; master['owner'] = scope['owner'];
for (var i=0; i < scope.credential_kind_options.length; i++) {
if (scope.credential_kind_options[i].value == data.kind) {
scope.kind = scope.credential_kind_options[i];
break;
}
}
master['kind'] = scope['kind'];
switch (data.kind) {
case 'aws':
scope['access_key'] = data.username;
scope['secret_key'] = data.password;
master['access_key'] = scope['access_key'];
master['secret_key'] = scope['secret_key'];
break;
case 'ssh':
scope['ssh_username'] = data.username;
scope['ssh_password'] = data.password;
master['ssh_username'] = scope['ssh_username'];
master['ssh_password'] = scope['ssh_password'];
break;
}
scope.$emit('credentialLoaded'); scope.$emit('credentialLoaded');
}) })
@@ -373,26 +437,43 @@ function CredentialsEdit ($scope, $rootScope, $compile, $location, $log, $routeP
// Save changes to the parent // Save changes to the parent
scope.formSave = function() { scope.formSave = function() {
generator.clearApiErrors(); generator.clearApiErrors();
var data = {} var data = {}
for (var fld in form.fields) { for (var fld in form.fields) {
if (scope[fld] === null) { if (fld !== 'access_key' && fld !== 'secret_key' && fld !== 'ssh_username' &&
data[fld] = ""; fld !== 'ssh_password') {
} if (scope[fld] === null) {
else { data[fld] = "";
data[fld] = scope[fld]; }
else {
data[fld] = scope[fld];
}
} }
} }
if (!Empty(scope.team)) { if (!Empty(scope.team)) {
data.team = scope.team; data.team = scope.team;
data.user = "";
} }
else { else {
data.user = scope.user; data.user = scope.user;
data.team = "";
} }
data['kind'] = scope['kind'].value; data['kind'] = scope['kind'].value;
switch (data['kind']) {
case 'ssh':
data['username'] = scope['ssh_username'];
data['password'] = scope['ssh_password'];
break;
case 'aws':
data['username'] = scope['access_key'];
data['password'] = scope['secret_key'];
break;
}
if (Empty(data.team) && Empty(data.user)) { if (Empty(data.team) && Empty(data.user)) {
Alert('Missing User or Team', 'You must provide either a User or a Team. If this credential will only be accessed by a specific ' + Alert('Missing User or Team', 'You must provide either a User or a Team. If this credential will only be accessed by a specific ' +
'user, select a User. To allow a team of users to access this credential, select a Team.', 'alert-danger'); 'user, select a User. To allow a team of users to access this credential, select a Team.', 'alert-danger');

View File

@@ -82,7 +82,8 @@ JobTemplatesList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$rout
function JobTemplatesAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm, function JobTemplatesAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm,
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope,
GetBasePath, InventoryList, CredentialList, ProjectList, LookUpInit, md5Setup, ParseTypeChange) GetBasePath, InventoryList, CredentialList, ProjectList, LookUpInit,
md5Setup, ParseTypeChange)
{ {
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
//scope. //scope.
@@ -123,23 +124,30 @@ function JobTemplatesAdd ($scope, $rootScope, $compile, $location, $log, $routeP
field: 'inventory' field: 'inventory'
}); });
LookUpInit({ // Clone the CredentialList object for use with cloud_credential. Cloning
url: GetBasePath('credentials') + '?cloud=false', // and changing properties to avoid collision.
scope: scope, var CloudCredentialList = {};
form: form, jQuery.extend(true, CloudCredentialList, CredentialList);
current_item: null, CloudCredentialList.name = 'cloudcredentials',
list: CredentialList, CloudCredentialList.iterator = 'cloudcredential',
field: 'credential'
});
LookUpInit({ LookUpInit({
url: GetBasePath('credentials') + '?cloud=true', url: GetBasePath('credentials') + '?cloud=true',
scope: scope, scope: scope,
form: form, form: form,
current_item: null, current_item: null,
list: CredentialList, list: CloudCredentialList,
field: 'cloud_credential' field: 'cloud_credential'
}); });
LookUpInit({
url: GetBasePath('credentials') + '?kind=ssh',
scope: scope,
form: form,
current_item: null,
list: CredentialList,
field: 'credential'
});
// Update playbook select whenever project value changes // Update playbook select whenever project value changes
var selectPlaybook = function(oldValue, newValue) { var selectPlaybook = function(oldValue, newValue) {
@@ -277,7 +285,8 @@ function JobTemplatesAdd ($scope, $rootScope, $compile, $location, $log, $routeP
JobTemplatesAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobTemplateForm', JobTemplatesAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobTemplateForm',
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope',
'GetBasePath', 'InventoryList', 'CredentialList', 'ProjectList', 'LookUpInit', 'md5Setup', 'ParseTypeChange' ]; 'GetBasePath', 'InventoryList', 'CredentialList', 'ProjectList', 'LookUpInit',
'md5Setup', 'ParseTypeChange' ];
function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm, function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm,

View File

@@ -75,15 +75,15 @@ angular.module('CredentialFormDefinition', [])
label: 'Access Key', label: 'Access Key',
type: 'text', type: 'text',
ngShow: "kind.value == 'aws'", ngShow: "kind.value == 'aws'",
awRequiredWhen: { variable: "aws_required", init: "false" }, awRequiredWhen: { variable: "aws_required", init: false },
autocomplete: false, autocomplete: false,
apiField: 'username' apiField: 'username'
}, },
secret_key: { secret_key: {
label: 'Secrent Key', label: 'Secret Key',
type: 'password', type: 'password',
ngShow: "kind.value == 'aws'", ngShow: "kind.value == 'aws'",
awRequiredWhen: { variable: "aws_required", init: "false" }, awRequiredWhen: { variable: "aws_required", init: false },
autocomplete: false, autocomplete: false,
ask: false, ask: false,
clear: false, clear: false,
@@ -97,9 +97,9 @@ angular.module('CredentialFormDefinition', [])
autocomplete: false autocomplete: false
}, },
"password": { "password": {
labelBind: 'passwordLabel', label: 'Password',
type: 'password', type: 'password',
ngShow: "kind.value && kind.value !== 'aws'", ngShow: "kind.value == 'rax' || kind.value == 'scm'",
awRequiredWhen: {variable: 'rackspace_required', init: false }, awRequiredWhen: {variable: 'rackspace_required', init: false },
ngChange: "clearPWConfirm('password_confirm')", ngChange: "clearPWConfirm('password_confirm')",
ask: false, ask: false,
@@ -108,15 +108,37 @@ angular.module('CredentialFormDefinition', [])
autocomplete: false autocomplete: false
}, },
"password_confirm": { "password_confirm": {
labelBind: 'passwordConfirmLabel', label: 'Confirm Password',
type: 'password', type: 'password',
ngShow: "kind.value && kind.value !== 'aws'", ngShow: "kind.value == 'rax' || kind.value == 'scm'",
addRequired: false, addRequired: false,
editRequired: false, editRequired: false,
awPassMatch: true, awPassMatch: true,
associated: 'password', associated: 'password',
autocomplete: false autocomplete: false
}, },
"ssh_password": {
label: 'SSH Password',
type: 'password',
ngShow: "kind.value == 'ssh'",
ngChange: "clearPWConfirm('password_confirm')",
addRequired: false,
editRequired: false,
ask: true,
clear: true,
associated: 'ssh_password_confirm',
autocomplete: false
},
"ssh_password_confirm": {
label: 'Confirm SSH Password',
type: 'password',
ngShow: "kind.value == 'ssh'",
addRequired: false,
editRequired: false,
awPassMatch: true,
associated: 'ssh_password',
autocomplete: false
},
"ssh_key_data": { "ssh_key_data": {
labelBind: 'sshKeyDataLabel', labelBind: 'sshKeyDataLabel',
type: 'textarea', type: 'textarea',

View File

@@ -87,7 +87,7 @@ angular.module('JobTemplateFormDefinition', [])
type: 'lookup', type: 'lookup',
sourceModel: 'cloud_credential', sourceModel: 'cloud_credential',
sourceField: 'name', sourceField: 'name',
ngClick: 'lookUpCredential()', ngClick: 'lookUpCloudcredential()',
addRequired: false, addRequired: false,
editRequired: false, editRequired: false,
column: 1 column: 1

View File

@@ -18,27 +18,20 @@ angular.module('CredentialsHelper', ['Utilities'])
// Put things in a default state // Put things in a default state
scope['usernameLabel'] = 'Username'; scope['usernameLabel'] = 'Username';
scope['passwordLabel'] = 'Password';
scope['passwordConfirmLabel'] = 'Confirm Password';
scope['aws_required'] = false; scope['aws_required'] = false;
scope['rackspace_required'] = false; scope['rackspace_required'] = false;
scope['sshKeyDataLabel'] = 'SSH Private Key'; scope['sshKeyDataLabel'] = 'SSH Private Key';
form.fields['password'].clear = true;
form.fields['password'].ask = true;
// Apply kind specific settings // Apply kind specific settings
switch(scope['kind'].value) { switch(scope['kind'].value) {
case 'aws': case 'aws':
scope['aws_required'] = true; scope['aws_required'] = true;
break; break;
case 'rax': case 'rax':
scope['rackspace_required'] = true; scope['rackspace_required'] = true;
form.fields['password'].ask = false;
break; break;
case 'ssh': case 'ssh':
scope['usernameLabel'] = 'SSH Username'; scope['usernameLabel'] = 'SSH Username';
scope['passwordLabel'] = 'SSH Password';
scope['passwordConfirmLabel'] = 'Confirm SSH Password';
break; break;
case 'scm': case 'scm':
scope['sshKeyDataLabel'] = 'SCM Private Key'; scope['sshKeyDataLabel'] = 'SCM Private Key';

View File

@@ -8,8 +8,8 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential
'LookUpHelper', 'ProjectFormDefinition', 'JobSubmissionHelper', 'GroupFormDefinition', 'GroupsHelper' ]) 'LookUpHelper', 'ProjectFormDefinition', 'JobSubmissionHelper', 'GroupFormDefinition', 'GroupsHelper' ])
.factory('PromptPasswords', ['CredentialForm', 'JobTemplateForm', 'GroupForm', 'ProjectsForm', '$compile', 'Rest', '$location', 'ProcessErrors', .factory('PromptPasswords', ['CredentialForm', 'JobTemplateForm', 'GroupForm', 'ProjectsForm', '$compile', 'Rest', '$location', 'ProcessErrors',
'GetBasePath', 'Alert', 'GetBasePath', 'Alert', 'Empty',
function(CredentialForm, JobTemplateForm, ProjectsForm, GroupForm, $compile, Rest, $location, ProcessErrors, GetBasePath, Alert) { function(CredentialForm, JobTemplateForm, ProjectsForm, GroupForm, $compile, Rest, $location, ProcessErrors, GetBasePath, Alert, Empty) {
return function(params) { return function(params) {
var scope = params.scope; var scope = params.scope;
@@ -73,7 +73,7 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential
value_supplied = true; value_supplied = true;
} }
}); });
if (passwords.length == 0 || value_supplied) { if (Empty(passwords) || passwords.length == 0 || value_supplied) {
Rest.setUrl(start_url); Rest.setUrl(start_url);
Rest.post(pswd) Rest.post(pswd)
.success( function(data, status, headers, config) { .success( function(data, status, headers, config) {
@@ -97,7 +97,7 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential
} }
} }
if (passwords.length > 0) { if (passwords && passwords.length > 0) {
// Prompt for passwords // Prompt for passwords
html += "<form class=\"form-horizontal\" name=\"password_form\" novalidate>\n"; html += "<form class=\"form-horizontal\" name=\"password_form\" novalidate>\n";
html += (extra_html) ? extra_html : ""; html += (extra_html) ? extra_html : "";
@@ -441,9 +441,9 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential
Rest.get() Rest.get()
.success( function(data, status, headers, config) { .success( function(data, status, headers, config) {
if (data.can_update) { if (data.can_update) {
var extra_html = "<div class=\"inventory-passwd-msg\">Starting inventory update for <em>" + group_name + //var extra_html = "<div class=\"inventory-passwd-msg\">Starting inventory update for <em>" + group_name +
"</em>. Please provide the " + group_source + " credentials:</div>\n"; // "</em>. Please provide the " + group_source + " credentials:</div>\n";
scope.$emit('InventorySubmit', data.passwords_needed_to_update, extra_html); scope.$emit('InventorySubmit', data.passwords_needed_to_update);
} }
else { else {
Alert('Permission Denied', 'You do not have access to run the update. Please contact your system administrator.', Alert('Permission Denied', 'You do not have access to run the update. Please contact your system administrator.',

View File

@@ -0,0 +1,75 @@
/*********************************************
* Copyright (c) 2013 AnsibleWorks, Inc.
*
* CloudCredentials.js
* List view object for Credential data model.
*
* @dict
*/
angular.module('CloudCredentialsListDefinition', [])
.value(
'CloudCredentialList', {
name: 'cloudcredentials',
iterator: 'cloudcredential',
selectTitle: 'Add Cloud Credentials',
editTitle: 'Cloud Credentials',
selectInstructions: '<p>Select existing credentials by clicking each credential or checking the related checkbox. When finished, click the blue ' +
'<em>Select</em> button, located bottom right.</p> <p>Create a brand new credential by clicking the green <em>Create New</em> button.</p>',
index: true,
hover: true,
fields: {
name: {
key: true,
label: 'Name'
},
description: {
label: 'Description',
excludeModal: false
},
team: {
label: 'Team',
ngBind: 'credential.team_name',
sourceModel: 'team',
sourceField: 'name',
excludeModal: true
},
user: {
label: 'User',
ngBind: 'credential.user_username',
sourceModel: 'user',
sourceField: 'username',
excludeModal: true
}
},
actions: {
add: {
icon: 'icon-plus',
label: 'Create New',
mode: 'all', // One of: edit, select, all
ngClick: 'addCredential()',
"class": 'btn-success btn-xs',
awToolTip: 'Create a new credential'
}
},
fieldActions: {
edit: {
ngClick: "editCredential(\{\{ credential.id \}\})",
icon: 'icon-edit',
label: 'Edit',
"class": 'btn-xs btn-default',
awToolTip: 'View/Edit credential'
},
"delete": {
ngClick: "deleteCredential(\{\{ credential.id \}\},'\{\{ credential.name \}\}')",
icon: 'icon-trash',
label: 'Delete',
"class": 'btn-xs btn-danger',
awToolTip: 'Delete credential'
}
}
});

View File

@@ -26,20 +26,31 @@ angular.module('CredentialsListDefinition', [])
}, },
description: { description: {
label: 'Description', label: 'Description',
excludeModal: true excludeModal: false
}, },
kind: {
label: 'Type',
searchType: 'select',
searchOptions: [], // will be set by Options call to credentials resource
excludeModal: true,
nosort: true
}
/*
team: { team: {
label: 'Team', label: 'Team',
ngBind: 'credential.team_name', ngBind: 'credential.team_name',
sourceModel: 'team', sourceModel: 'team',
sourceField: 'name' sourceField: 'name',
excludeModal: true
}, },
user: { user: {
label: 'User', label: 'User',
ngBind: 'credential.user_username', ngBind: 'credential.user_username',
sourceModel: 'user', sourceModel: 'user',
sourceField: 'username' sourceField: 'username',
excludeModal: true
} }
*/
}, },
actions: { actions: {

View File

@@ -41,7 +41,8 @@ angular.module('ProjectsListDefinition', [])
last_updated: { last_updated: {
label: 'Last Updated', label: 'Last Updated',
type: 'date', type: 'date',
excludeModal: true excludeModal: true,
searchable: false
} }
}, },

View File

@@ -448,8 +448,9 @@ angular.module('Utilities',['RestServices', 'Utilities'])
Rest.options() Rest.options()
.success( function(data, status, headers, config) { .success( function(data, status, headers, config) {
var choices = data.actions.GET[field].choices var choices = data.actions.GET[field].choices
// including 'name' property so list can be used by search
for (var i=0; i < choices.length; i++) { for (var i=0; i < choices.length; i++) {
scope[variable].push({ label: choices[i][1], value: choices[i][0] }); scope[variable].push({ label: choices[i][1], value: choices[i][0], name: choices[i][1]});
} }
if (callback) { if (callback) {
scope.$emit(callback); scope.$emit(callback);
@@ -490,7 +491,8 @@ angular.module('Utilities',['RestServices', 'Utilities'])
/* Empty() /* Empty()
* *
* Test if a value is 'empty'. Returns true if val is null | '' | undefined * Test if a value is 'empty'. Returns true if val is null | '' | undefined.
* Only works on non-Ojbect types.
* *
*/ */
.factory('Empty', [ function() { .factory('Empty', [ function() {

View File

@@ -107,26 +107,26 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'Hos
function checkIt () { function checkIt () {
var viewValue = elm.val(); var viewValue = elm.val();
var txt, label; var txt, label, p, l, s;
validity = true; validity = true;
if ( scope[attrs.awRequiredWhen] && (elm.attr('required') == null || elm.attr('required') == undefined) ) { if ( scope[attrs.awRequiredWhen] && (elm.attr('required') == null || elm.attr('required') == undefined) ) {
$(elm).attr('required','required'); $(elm).attr('required','required');
if ($(elm).hasClass('lookup')) { if ($(elm).hasClass('lookup')) {
$(elm).parent().parent().parent().find('label').addClass('prepend-asterisk'); $(elm).parent().parent().parent().find('label').first().addClass('prepend-asterisk');
} }
else { else {
$(elm).parent().parent().find('label').addClass('prepend-asterisk'); $(elm).parent().parent().find('label').first().addClass('prepend-asterisk');
} }
} }
else if (!scope[attrs.awRequiredWhen]) { else if (!scope[attrs.awRequiredWhen]) {
elm.removeAttr('required'); elm.removeAttr('required');
if ($(elm).hasClass('lookup')) { if ($(elm).hasClass('lookup')) {
label = $(elm).parent().parent().parent().find('label'); label = $(elm).parent().parent().parent().find('label').first();
label.removeClass('prepend-asterisk');
} }
else { else {
label = $(elm).parent().parent().find('label'); $(elm).parent().parent().find('label').first().removeClass('prepend-asterisk');
} }
label.removeClass('prepend-asterisk');
} }
if (scope[attrs.awRequiredWhen] && (viewValue == undefined || viewValue == null || viewValue == '')) { if (scope[attrs.awRequiredWhen] && (viewValue == undefined || viewValue == null || viewValue == '')) {
validity = false; validity = false;

View File

@@ -8,11 +8,11 @@
* *
*/ */
angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies']) angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies', 'Utilities'])
.factory('GenerateForm', [ '$location', '$cookieStore', '$compile', 'SearchWidget', 'PaginateWidget', 'Attr', 'Icon', 'Column', .factory('GenerateForm', [ '$location', '$cookieStore', '$compile', 'SearchWidget', 'PaginateWidget', 'Attr', 'Icon', 'Column',
'NavigationLink', 'HelpCollapse', 'Button', 'DropDown', 'NavigationLink', 'HelpCollapse', 'Button', 'DropDown', 'Empty',
function($location, $cookieStore, $compile, SearchWidget, PaginateWidget, Attr, Icon, Column, NavigationLink, HelpCollapse, Button, function($location, $cookieStore, $compile, SearchWidget, PaginateWidget, Attr, Icon, Column, NavigationLink, HelpCollapse, Button,
DropDown) { DropDown, Empty) {
return { return {
setForm: function(form) { setForm: function(form) {
@@ -102,18 +102,20 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies'])
// Prepend an asterisk to required field label // Prepend an asterisk to required field label
$('.form-control[required], input[type="radio"][required]').each(function() { $('.form-control[required], input[type="radio"][required]').each(function() {
var label = $(this).parent().parent().find('label'); if ( Empty($(this).attr('aw-required-when')) ) {
if ($(this).attr('type') == 'radio') { var label = $(this).parent().parent().find('label').first();
label = $(this).parent().parent().parent().find('label').first(); if ($(this).attr('type') == 'radio') {
} label = $(this).parent().parent().parent().find('label').first();
if (label) { }
var span = label.find('span'); if (label) {
if (span && !span.hasClass('prepend-asterisk')) { var span = label.find('span').first();
span.addClass('prepend-asterisk'); if (span && !span.hasClass('prepend-asterisk')) {
} span.addClass('prepend-asterisk');
else if (!label.hasClass('prepend-asterisk') && !label.find('.prepend-asterisk')) { }
label.addClass('prepend-asterisk'); else if (!label.hasClass('prepend-asterisk') && !label.find('.prepend-asterisk')) {
} label.addClass('prepend-asterisk');
}
}
} }
}); });
@@ -463,7 +465,7 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies'])
html += (field.labelBind) ? "ng-bind=\"" + field.labelBind + "\" " : ""; html += (field.labelBind) ? "ng-bind=\"" + field.labelBind + "\" " : "";
html += "for=\"" + fld + '">'; html += "for=\"" + fld + '">';
html += (field.icon) ? this.icon(field.icon) : ""; html += (field.icon) ? this.icon(field.icon) : "";
html += "<span>" + field.label + '</span></label>' + "\n"; html += "<span class=\"label-text\">" + field.label + '</span></label>' + "\n";
html += (field.awPopOver && field.awPopOverRight) ? this.attr(field, 'awPopOver', fld) : ""; html += (field.awPopOver && field.awPopOverRight) ? this.attr(field, 'awPopOver', fld) : "";
html += "</div>\n"; html += "</div>\n";
html += "<div "; html += "<div ";
@@ -776,7 +778,7 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies'])
html += (field.labelBind) ? "ng-bind=\"" + field.labelBind + "\" " : ""; html += (field.labelBind) ? "ng-bind=\"" + field.labelBind + "\" " : "";
html += "for=\"" + fld + '">'; html += "for=\"" + fld + '">';
html += (field.icon) ? this.icon(field.icon) : ""; html += (field.icon) ? this.icon(field.icon) : "";
html += '<span>' + field.label + '</span></label>' + "\n"; html += '<span class=\"label-text\">' + field.label + '</span></label>' + "\n";
html += (field.awPopOver && field.awPopOverRight) ? this.attr(field, 'awPopOver', fld) : ""; html += (field.awPopOver && field.awPopOverRight) ? this.attr(field, 'awPopOver', fld) : "";
html += "</div>\n"; html += "</div>\n";
html += "<div "; html += "<div ";
@@ -791,7 +793,7 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies'])
if (field.type == 'radio') { if (field.type == 'radio') {
html += "<label class=\"control-label " + getLabelWidth() + "\" for=\"" + fld + '">'; html += "<label class=\"control-label " + getLabelWidth() + "\" for=\"" + fld + '">';
html += (field.awPopOver) ? this.attr(field, 'awPopOver', fld) : ""; html += (field.awPopOver) ? this.attr(field, 'awPopOver', fld) : "";
html += '<span>' + field.label + '</span></label>' + "\n"; html += '<span class=\"label-text\">' + field.label + '</span></label>' + "\n";
html += "<div "; html += "<div ";
html += "id=\"" + this.form.name + "_" + fld + "_radio_grp\" "; html += "id=\"" + this.form.name + "_" + fld + "_radio_grp\" ";
html += (field.controlNGClass) ? "ng-class=\"" + field.controlNGClass + "\" " : ""; html += (field.controlNGClass) ? "ng-class=\"" + field.controlNGClass + "\" " : "";