Skip to content

Commit 9d58aca

Browse files
committed
Basic anyOf suport WIP
It renders! But it needs some more love: * a directive that figures out exactly which of the anyOf schemas forms to show when model is not empty * adressing with {index} is a bit quirky, takes ., maybe should be as array * choosing another form, should it empty the model? Should we temporarily store the values so you don't loose them?
1 parent 14f4aaa commit 9d58aca

File tree

5 files changed

+81
-7
lines changed

5 files changed

+81
-7
lines changed

src/directives/decorators/bootstrap/bootstrap-decorator.js

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ angular.module('schemaForm').config(['schemaFormDecoratorsProvider', function(de
99
console.log('fieldset children frag', children.childNodes)
1010
args.fieldFrag.appendChild(children);
1111
}},*/
12+
anyOf: {template: base + 'someof.html', replace: false},
1213
array: {template: base + 'array.html', replace: false},
1314
tabarray: {template: base + 'tabarray.html', replace: false},
1415
tabs: {template: base + 'tabs.html', replace: false},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<div class="panel panel-default {{form.htmlClass}} schema-form-{{form.type}}">
2+
<div class="panel-body form-group "
3+
ng-class="{'has-error': form.disableErrorState !== true && hasError(), 'has-success': form.disableSuccessState !== true && hasSuccess(), 'has-feedback': form.feedback !== false}">
4+
<div class="row">
5+
<div class="col-md-4">
6+
<h4 class="{{form.labelHtmlClass}}" ng-show="showTitle()">
7+
{{form.title}}
8+
</h4>
9+
</div>
10+
<!--
11+
this is jus a proof of concept, a directive for choosing correct form to be selected is
12+
needed as well.
13+
-->
14+
<div class="col-md-8">
15+
<select ng-model="form.selected"
16+
ng-disabled="form.readonly"
17+
class="form-control {{form.fieldHtmlClass}}"
18+
ng-options="item.value as item.name group by item.group for item in form.titleMap"
19+
name="{{form.key.slice(-1)[0]}}">
20+
</select>
21+
</div>
22+
</div>
23+
<div class="help-block" sf-message="form.description"></div>
24+
25+
<hr>
26+
<sf-decorator ng-repeat="item in form.items" form="item" ng-if="$index === form.selected"></sf-decorator>
27+
</div>
28+
</div>

src/services/builder.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@ angular.module('schemaForm').factory('sfBuilder',
5353
var div = document.createElement('div');
5454
var template = templateFn(field.template) || templateFn([decorator['default'].template]);
5555
if (f.key) {
56-
var key = f.key ?
57-
sfPath.stringify(f.key).replace(/"/g, '&quot;') : '';
56+
57+
var key = f.key.filter(function(p) { console.log(p,p.test(/\{[0-9]+\}/)); return !p.test(/\{[0-9]+\}/); });
58+
key = sfPath.stringify(key).replace(/"/g, '&quot;');
59+
5860
template = template.replace(
5961
/\$\$value\$\$/g,
6062
'model' + (key[0] !== '[' ? '.' : '') + key
@@ -134,7 +136,7 @@ var transclusion = function() {
134136
* Builds a form from a canonical form definition
135137
*/
136138
build: function(form, decorator, slots) {
137-
console.warn(slots)
139+
console.warn(form)
138140
return build(form, decorator, function(url) {
139141
return $templateCache.get(url) || '';
140142
}, slots);

src/services/decorators.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,10 @@ angular.module('schemaForm').provider('schemaFormDecorators',
184184

185185
templatePromise.then(function(template) {
186186
if (form.key) {
187-
var key = form.key ?
188-
sfPathProvider.stringify(form.key).replace(/"/g, '&quot;') : '';
187+
188+
var key = form.key.filter(function(p) { console.log(p,/\{[0-9]+\}/.test(p)); return !/\{[0-9]+\}/.test(p); });
189+
key = sfPath.stringify(key).replace(/"/g, '&quot;');
190+
189191
template = template.replace(
190192
/\$\$value\$\$/g,
191193
'model' + (key[0] !== '[' ? '.' : '') + key

src/services/schema-form.js

+43-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ angular.module('schemaForm').provider('schemaForm',
4444
};
4545

4646
var defaultFormDefinition = function(name, schema, options) {
47-
var rules = defaults[stripNullType(schema.type)];
47+
var rules = schema.type ? defaults[stripNullType(schema.type)] : defaults.schema;
4848
if (rules) {
4949
var def;
5050
for (var i = 0; i < rules.length; i++) {
@@ -228,6 +228,46 @@ angular.module('schemaForm').provider('schemaForm',
228228

229229
};
230230

231+
var anyOf = function(name, schema, options) {
232+
if (schema.anyOf && angular.isArray(schema.anyOf)) {
233+
var f = stdFormObj(name, schema, options);
234+
f.type = 'anyOf';
235+
f.key = options.path;
236+
options.lookup[sfPathProvider.stringify(options.path)] = f;
237+
238+
var required = schema.required &&
239+
schema.required.indexOf(options.path[options.path.length - 1]) !== -1;
240+
241+
f.titleMap = [];
242+
f.items = [];
243+
244+
f.selected = 0; // FIXME: directive to choose the correct one
245+
246+
schema.anyOf.forEach(function(sub, index) {
247+
var subPath = options.path.slice();
248+
subPath.push('{' + index + '}');
249+
250+
f.titleMap.push({
251+
name: sub.title || f.title + ' ' + index,
252+
value: index
253+
});
254+
255+
f.items.push(defaultFormDefinition(name, sub, {
256+
path: subPath,
257+
required: required || false, //TODO: validate that this is what we want.
258+
lookup: options.lookup,
259+
ignore: options.ignore,
260+
global: options.global
261+
}));
262+
});
263+
264+
return f;
265+
}
266+
};
267+
268+
var oneOf = function(name, schema, options) {
269+
};
270+
231271
//First sorted by schema type then a list.
232272
//Order has importance. First handler returning an form snippet will be used.
233273
var defaults = {
@@ -236,7 +276,8 @@ angular.module('schemaForm').provider('schemaForm',
236276
number: [number],
237277
integer: [integer],
238278
boolean: [checkbox],
239-
array: [checkboxes, array]
279+
array: [checkboxes, array],
280+
schema: [anyOf, oneOf]
240281
};
241282

242283
var postProcessFn = function(form) { return form; };

0 commit comments

Comments
 (0)