Skip to content

Commit 2d24b23

Browse files
committed
readonly on a form or schema should be inherited
This means settings "readOnly" on an entire schema now works.
1 parent 90e0343 commit 2d24b23

File tree

5 files changed

+161
-27
lines changed

5 files changed

+161
-27
lines changed

dist/schema-form.js

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -720,23 +720,27 @@ angular.module('schemaForm').provider('schemaForm',
720720

721721
var service = {};
722722

723-
service.merge = function(schema, form, ignore, options) {
723+
service.merge = function(schema, form, ignore, options, readonly) {
724724
form = form || ['*'];
725725
options = options || {};
726726

727+
// Get readonly from root object
728+
readonly = readonly || schema.readonly || schema.readOnly;
729+
727730
var stdForm = service.defaults(schema, ignore, options);
731+
728732
//simple case, we have a "*", just put the stdForm there
729733
var idx = form.indexOf('*');
730734
if (idx !== -1) {
731735
form = form.slice(0, idx)
732736
.concat(stdForm.form)
733737
.concat(form.slice(idx + 1));
734-
return form;
735738
}
736739

737740
//ok let's merge!
738741
//We look at the supplied form and extend it with schema standards
739742
var lookup = stdForm.lookup;
743+
740744
return postProcessFn(form.map(function(obj) {
741745

742746
//handle the shortcut with just a name
@@ -767,26 +771,32 @@ angular.module('schemaForm').provider('schemaForm',
767771
});
768772
}
769773

774+
//extend with std form from schema.
775+
776+
if (obj.key) {
777+
var strid = sfPathProvider.stringify(obj.key);
778+
if (lookup[strid]) {
779+
obj = angular.extend(lookup[strid], obj);
780+
}
781+
}
782+
783+
// Are we inheriting readonly?
784+
if (readonly === true) { // Inheriting false is not cool.
785+
obj.readonly = true;
786+
}
787+
770788
//if it's a type with items, merge 'em!
771789
if (obj.items) {
772-
obj.items = service.merge(schema, obj.items, ignore, options);
790+
obj.items = service.merge(schema, obj.items, ignore, options, obj.readonly);
773791
}
774792

775793
//if its has tabs, merge them also!
776794
if (obj.tabs) {
777795
angular.forEach(obj.tabs, function(tab) {
778-
tab.items = service.merge(schema, tab.items, ignore, options);
796+
tab.items = service.merge(schema, tab.items, ignore, options, obj.readonly);
779797
});
780798
}
781799

782-
//extend with std form from schema.
783-
if (obj.key) {
784-
var str = sfPathProvider.stringify(obj.key);
785-
if (lookup[str]) {
786-
obj = angular.extend(lookup[str], obj);
787-
}
788-
}
789-
790800
// Special case: checkbox
791801
// Since have to ternary state we need a default
792802
if (obj.type === 'checkbox' && angular.isUndefined(obj.schema['default'])) {

dist/schema-form.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/index.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,9 @@ General options most field types can handle:
309309
onChange: "valueChanged(form.key,modelValue)", // onChange event handler, expression or function
310310
feedback: false, // Inline feedback icons
311311
placeholder: "Input...", // placeholder on inputs and textarea
312-
ngModelOptions: { ... } // Passed along to ng-model-options
312+
ngModelOptions: { ... }, // Passed along to ng-model-options
313+
readonly: true // Same effect as readOnly in schema. Put on a fieldset or array
314+
// and their items will inherit it.
313315
}
314316
```
315317

src/services/schema-form.js

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -281,23 +281,27 @@ angular.module('schemaForm').provider('schemaForm',
281281

282282
var service = {};
283283

284-
service.merge = function(schema, form, ignore, options) {
284+
service.merge = function(schema, form, ignore, options, readonly) {
285285
form = form || ['*'];
286286
options = options || {};
287287

288+
// Get readonly from root object
289+
readonly = readonly || schema.readonly || schema.readOnly;
290+
288291
var stdForm = service.defaults(schema, ignore, options);
292+
289293
//simple case, we have a "*", just put the stdForm there
290294
var idx = form.indexOf('*');
291295
if (idx !== -1) {
292296
form = form.slice(0, idx)
293297
.concat(stdForm.form)
294298
.concat(form.slice(idx + 1));
295-
return form;
296299
}
297300

298301
//ok let's merge!
299302
//We look at the supplied form and extend it with schema standards
300303
var lookup = stdForm.lookup;
304+
301305
return postProcessFn(form.map(function(obj) {
302306

303307
//handle the shortcut with just a name
@@ -328,26 +332,32 @@ angular.module('schemaForm').provider('schemaForm',
328332
});
329333
}
330334

335+
//extend with std form from schema.
336+
337+
if (obj.key) {
338+
var strid = sfPathProvider.stringify(obj.key);
339+
if (lookup[strid]) {
340+
obj = angular.extend(lookup[strid], obj);
341+
}
342+
}
343+
344+
// Are we inheriting readonly?
345+
if (readonly === true) { // Inheriting false is not cool.
346+
obj.readonly = true;
347+
}
348+
331349
//if it's a type with items, merge 'em!
332350
if (obj.items) {
333-
obj.items = service.merge(schema, obj.items, ignore, options);
351+
obj.items = service.merge(schema, obj.items, ignore, options, obj.readonly);
334352
}
335353

336354
//if its has tabs, merge them also!
337355
if (obj.tabs) {
338356
angular.forEach(obj.tabs, function(tab) {
339-
tab.items = service.merge(schema, tab.items, ignore, options);
357+
tab.items = service.merge(schema, tab.items, ignore, options, obj.readonly);
340358
});
341359
}
342360

343-
//extend with std form from schema.
344-
if (obj.key) {
345-
var str = sfPathProvider.stringify(obj.key);
346-
if (lookup[str]) {
347-
obj = angular.extend(lookup[str], obj);
348-
}
349-
}
350-
351361
// Special case: checkbox
352362
// Since have to ternary state we need a default
353363
if (obj.type === 'checkbox' && angular.isUndefined(obj.schema['default'])) {

test/services/schema-form-test.js

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,5 +413,117 @@ describe('schemaForm', function() {
413413

414414
});
415415
});
416+
417+
it('should translate "readOnly" in schema to "readonly" on the merged form defintion',function(){
418+
inject(function(schemaForm){
419+
var schema = {
420+
"type": "object",
421+
"properties": {
422+
"name": {
423+
"title": "Name",
424+
"description": "Gimme yea name lad",
425+
"type": "string"
426+
},
427+
"gender": {
428+
"readOnly": true,
429+
"title": "Choose",
430+
"type": "string",
431+
"enum": [
432+
"undefined",
433+
"null",
434+
"NaN",
435+
]
436+
}
437+
}
438+
};
439+
440+
var merged = schemaForm.merge(schema, ['gender']);
441+
merged[0].should.have.property('readonly');
442+
merged[0].readonly.should.eq(true)
443+
});
444+
});
445+
446+
it('should push readOnly in schema down into objects and arrays', function() {
447+
inject(function(schemaForm) {
448+
var schema = {
449+
'type': 'object',
450+
'readOnly': true,
451+
'properties': {
452+
'sub': {
453+
'type': 'object',
454+
'properties': {
455+
'array': {
456+
'type': 'array',
457+
'items': {
458+
'type': 'object',
459+
'properties': {
460+
'foo': {
461+
'type': 'string'
462+
}
463+
}
464+
}
465+
}
466+
}
467+
}
468+
}
469+
};
470+
471+
var merged = schemaForm.merge(schema, ['*']);
472+
473+
//sub
474+
merged[0].should.have.property('readonly');
475+
merged[0].readonly.should.eq(true);
476+
477+
//array
478+
merged[0].items[0].should.have.property('readonly');
479+
merged[0].items[0].readonly.should.eq(true);
480+
481+
//array items
482+
merged[0].items[0].items[0].should.have.property('readonly');
483+
merged[0].items[0].items[0].readonly.should.eq(true);
484+
485+
});
486+
});
487+
488+
it('should push readonly in form def down into objects and arrays', function() {
489+
inject(function(schemaForm) {
490+
var schema = {
491+
'type': 'object',
492+
'properties': {
493+
'sub': {
494+
'type': 'object',
495+
'properties': {
496+
'array': {
497+
'type': 'array',
498+
'items': {
499+
'type': 'object',
500+
'properties': {
501+
'foo': {
502+
'type': 'string'
503+
}
504+
}
505+
}
506+
}
507+
}
508+
}
509+
}
510+
};
511+
512+
var merged = schemaForm.merge(schema, [{key: 'sub', readonly: true}]);
513+
514+
//sub
515+
merged[0].should.have.property('readonly');
516+
merged[0].readonly.should.eq(true);
517+
518+
//array
519+
merged[0].items[0].should.have.property('readonly');
520+
merged[0].items[0].readonly.should.eq(true);
521+
522+
//array items
523+
merged[0].items[0].items[0].should.have.property('readonly');
524+
merged[0].items[0].items[0].readonly.should.eq(true);
525+
526+
});
527+
});
416528
});
417-
});
529+
});

0 commit comments

Comments
 (0)