Add working dynamic component insertion

This commit is contained in:
gconsidine 2017-05-16 17:00:49 -04:00
parent 17f6148c8d
commit 8b91b16bea
11 changed files with 144 additions and 85 deletions

View File

@ -23,7 +23,9 @@ function AddCredentialsController (models) {
};
vm.dynamic = {
model: credential
getInputs: credentialType.getTypeFromName,
source: vm.kind,
reference: 'vm.dynamic'
};
}

View File

@ -12,8 +12,7 @@
<at-input-text col="4" config="vm.description"></at-input-text>
<at-input-select col="4" config="vm.kind"></at-input-select>
<at-dynamic-input-group col="4" config="vm.dynamic" watch="vm.kind">
</at-dynamic-input-group>
<at-dynamic-input-group col="4" config="vm.dynamic"></at-dynamic-input-group>
<at-action-group col="12" pos="right">
<at-form-action type="cancel"></at-form-action>

View File

@ -1,36 +1,100 @@
function link (scope, el, attrs, controllers) {
let dynamicController = controllers[0];
let formController = controllers[0];
let dynamicController = controllers[1];
el = el[0];
dynamicController.init(scope);
dynamicController.init(scope, formController, el);
}
function atDynamicInputGroupController () {
function atDynamicInputGroupController ($scope, $compile) {
let vm = this || {};
let state;
let scope;
let input;
let source;
let form;
let el;
vm.init = (_scope_) => {
vm.init = (_scope_, _form_, _el_) => {
form = _form_;
scope = _scope_;
console.log(scope.watch);
// scope.form = form.use('input', state);
el = _el_;
scope.config.state = scope.config.state || {};
state = scope.config.state;
source = scope.config.source;
$scope.$watch('config.source.state.value', vm.update);
};
vm.update = () => {
if (!source.state.value || source.state.value === state.value) {
return;
}
state.value = source.state.value;
let inputs = scope.config.getInputs(source.state.value);
let components = vm.createComponentConfigs(inputs);
vm.insert(components);
scope.config.components = components;
vm.compile(components);
};
vm.createComponentConfigs = inputs => {
let components = [];
inputs.forEach((input, i) => {
if (input.type === 'string') {
if (input.secret) {
input.component = 'at-input-secret';
} else if (input.multiline) {
input.component = 'at-input-textarea';
} else {
input.component = 'at-input-text';
}
}
let html = angular.element(`
<${input.component}
col="${scope.col}"
config="${scope.config.reference}.components[${i}]">
</${input.component}>
`);
components.push({
options: input,
html
});
});
return components;
};
vm.insert = components => {
components.forEach(component => el.appendChild(component.html[0]));
};
vm.compile = components => {
components.forEach(component => $compile(component.html[0])(scope.$parent));
};
}
atDynamicInputGroupController.$inject = ['$scope', '$compile'];
function atDynamicInputGroup (pathService) {
return {
restrict: 'E',
replace: true,
require: ['atDynamicInputGroup'],
require: ['^^atForm', 'atDynamicInputGroup'],
templateUrl: pathService.getPartialPath('components/dynamic/input-group'),
controller: atDynamicInputGroupController,
controllerAs: 'vm',
link,
scope: {
config: '=',
watch: '='
col: '@'
}
};
}

View File

@ -1,4 +1,2 @@
<div>
{{ watch.state.value }}
{{ watch.data[watch.state.value] }}
</div>

View File

@ -10,7 +10,6 @@ function atFormActionController ($state) {
let form;
let scope;
let el;
let state;
vm.init = (_form_, _scope_) => {

View File

@ -1,59 +1,44 @@
function AtFormController () {
let vm = this || {};
vm.inputs = [];
vm.actions = [];
vm.components = [];
vm.state = {
isValid: false
};
vm.use = (type, component, el) => {
let state;
switch (type) {
case 'input':
state = vm.trackInput(component, el);
break;
case 'action':
state = vm.trackAction(component, el);
break;
default:
throw new Error('An at-form cannot use component type:', type);
}
return state;
return vm.trackComponent(type, component, el);
};
vm.trackInput = (input, el) => {
let form = {
vm.trackComponent = (type, component, el) => {
let meta = {
el,
type,
state: vm.state,
disabled: false
disabled: false,
tabindex: vm.components.length + 1
};
vm.inputs.push(input)
if (!vm.components.length) {
el.focus();
}
return form;
};
vm.components.push(meta)
vm.trackAction = action => {
let form = {
state: vm.state,
disabled: false
};
vm.actions.push(action);
return form;
return meta;
};
vm.validate = () => {
let isValid = true;
vm.inputs.forEach(input => {
if (!input.isValid) {
isValid = false;
}
});
vm.components
.filter(component => component.type === 'input')
.forEach(input => {
if (input.isValid) {
isValid = false;
}
});
return isValid;
};
@ -71,6 +56,10 @@ function AtFormController () {
};
}
function link (scope, el, attrs, controller, fn) {
//console.log(fn);
}
function atForm (pathService) {
return {
restrict: 'E',
@ -78,6 +67,7 @@ function atForm (pathService) {
templateUrl: pathService.getPartialPath('components/form/form'),
controller: AtFormController,
controllerAs: 'vm',
link,
scope: {
config: '='
}

View File

@ -25,15 +25,11 @@ function AtInputSelectController (eventService) {
scope.config.state = scope.config.state || {};
state = scope.config.state;
if (scope.tab === 1) {
select.focus();
}
state.isValid = state.isValid || false;
state.message = state.message || '';
state.required = scope.config.options.required || false;
scope.form = form.use('input', state);
scope.form = form.use('input', state, input);
vm.setListeners();
vm.check();

View File

@ -8,7 +8,8 @@
ng-change="vm.check()" />
<select class="form-control at-InputSelect-select" ng-model="config.state.value"
tabindex="{{::tab}}" ng-attr-autofocus="{{ tab == 1 || undefined }}"
ng-attr-tabindex="{{ form.tabindex || undefined }}"
ng-attr-autofocus="{{ form.autofocus || undefined }}"
ng-disabled="form.disabled">
<optgroup ng-repeat="group in config.data" label="{{::group.category | uppercase }}">
<option ng-repeat="item in group.data" value="{{ item.name }}">

View File

@ -23,10 +23,6 @@ function AtInputTextController () {
state = scope.config.state;
state.required = scope.config.options.required;
if (scope.tab === '1') {
input.focus();
}
state.isValid = state.isValid || false;
state.message = state.message || '';
state.required = state.required || false;

View File

@ -2,9 +2,10 @@
<div class="form-group at-u-flat">
<at-input-label config="config"></at-input-label>
<input type="text" class="form-control at-Input" ng-model="config.state.value"
ng-attr-autofocus="{{ tab == 1 || undefined }}"
ng-attr-autofocus="{{ form.autofocus || undefined }}"
ng-attr-maxlength="{{ config.options.max_length || undefined }}"
tabindex="{{::tab}}" placeholder="{{::config.placeholder}}"
tabindex="{{ form.tabindex || undefined }}"
placeholder="{{::config.placeholder}}"
ng-change="vm.check()" ng-disabled="form.disabled" />
</div>
</div>

View File

@ -1,30 +1,43 @@
function categorizeByKind () {
let group = {};
this.model.data.results.forEach(result => {
group[result.kind] = group[result.kind] || [];
group[result.kind].push(result);
});
return Object.keys(group).map(category => ({
data: group[category],
category
}));
}
function getTypeFromName (name) {
let type = this.model.data.results.filter(result => result.name === name);
return type.length ? type[0] : null;
}
function CredentialType (BaseModel) {
Object.assign(this, BaseModel());
this.path = this.normalizePath('credential_types');
this.categorizeByKind = categorizeByKind;
this.getTypeFromName = getTypeFromName;
this.categorizeByKind = () => {
let group = {};
this.model.data.results.forEach(result => {
group[result.kind] = group[result.kind] || [];
group[result.kind].push(result);
});
return Object.keys(group).map(category => ({
data: group[category],
category
}));
};
this.getTypeFromName = name => {
let type = this.model.data.results.filter(result => result.name === name);
if (!type.length) {
return null;
}
return this.mergeInputProperties(type[0]);
};
this.mergeInputProperties = type => {
return type.inputs.fields.map(field => {
if (!type.inputs.required || type.inputs.required.indexOf(field.id) !== -1) {
field.required = false;
} else {
field.required = true;
}
return field;
});
};
}
CredentialType.$inject = ['BaseModel'];