angular2-json-schema-form
Version:
Angular 2 JSON Schema Form builder
330 lines • 16.3 kB
JavaScript
;
var forms_1 = require("@angular/forms");
var _ = require("lodash");
var index_1 = require("./index");
function buildFormGroupTemplate(jsf, setValues, mapArrays, schemaPointer, dataPointer, templatePointer) {
if (setValues === void 0) { setValues = null; }
if (mapArrays === void 0) { mapArrays = true; }
if (schemaPointer === void 0) { schemaPointer = ''; }
if (dataPointer === void 0) { dataPointer = ''; }
if (templatePointer === void 0) { templatePointer = ''; }
var schema = index_1.JsonPointer.get(jsf.schema, schemaPointer);
var useValues = jsf.globalOptions.setSchemaDefaults ?
mergeValues(index_1.JsonPointer.get(schema, '/default'), setValues) : setValues;
var schemaType = index_1.JsonPointer.get(schema, '/type');
var controlType;
if (schemaType === 'object' && index_1.hasOwn(schema, 'properties')) {
controlType = 'FormGroup';
}
else if (schemaType === 'array' && index_1.hasOwn(schema, 'items')) {
controlType = 'FormArray';
}
else if (!schemaType && index_1.hasOwn(schema, '$ref')) {
controlType = '$ref';
}
else {
controlType = 'FormControl';
}
if (dataPointer !== '' && !jsf.dataMap.has(dataPointer)) {
jsf.dataMap.set(dataPointer, new Map);
jsf.dataMap.get(dataPointer).set('schemaPointer', schemaPointer);
jsf.dataMap.get(dataPointer).set('schemaType', schema.type);
if (controlType) {
jsf.dataMap.get(dataPointer).set('templatePointer', templatePointer);
jsf.dataMap.get(dataPointer).set('templateType', controlType);
}
var genericDataPointer = index_1.JsonPointer.toGenericPointer(dataPointer, jsf.arrayMap);
if (!jsf.dataMap.has(genericDataPointer)) {
jsf.dataMap.set(genericDataPointer, new Map);
jsf.dataMap.get(genericDataPointer).set('schemaPointer', schemaPointer);
jsf.dataMap.get(genericDataPointer).set('schemaType', schema.type);
}
}
var controls;
var validators = index_1.getControlValidators(schema);
switch (controlType) {
case 'FormGroup':
controls = {};
if (jsf.globalOptions.setSchemaDefaults) {
useValues = mergeValues(index_1.JsonPointer.get(schema, '/properties/default'), useValues);
}
index_1.forEach(schema.properties, function (item, key) {
if (key !== 'ui:order') {
controls[key] = buildFormGroupTemplate(jsf, index_1.JsonPointer.get(useValues, [key]), mapArrays, schemaPointer + '/properties/' + key, dataPointer + '/' + key, templatePointer + '/controls/' + key);
}
});
jsf.globalOptions.fieldsRequired =
setRequiredFields(schema, controls);
return { controlType: controlType, controls: controls, validators: validators };
case 'FormArray':
var minItems = schema.minItems || 0;
var maxItems = schema.maxItems || 1000000;
if (index_1.isArray(schema.items)) {
if (mapArrays && !jsf.arrayMap.get(dataPointer)) {
jsf.arrayMap.set(dataPointer, schema.items.length);
}
controls = [];
for (var i = 0, l = schema.items.length; i < l; i++) {
if (i >= minItems &&
!index_1.JsonPointer.has(jsf.templateRefLibrary, [dataPointer + '/' + i])) {
jsf.templateRefLibrary[dataPointer + '/' + i] =
buildFormGroupTemplate(jsf, null, mapArrays, schemaPointer + '/items/' + i, dataPointer + '/' + i, templatePointer + '/controls/' + i);
}
if (i < maxItems) {
var useValue = index_1.isArray(useValues) ? useValues[i] : useValues;
controls.push(buildFormGroupTemplate(jsf, useValue, false, schemaPointer + '/items/' + i, dataPointer + '/' + i, templatePointer + '/controls/' + i));
}
}
if (schema.items.length < maxItems &&
index_1.hasOwn(schema, 'additionalItems') && index_1.isObject(schema.additionalItems)) {
var l = Math.max(schema.items.length + 1, index_1.isArray(useValues) ? useValues.length : 0);
for (var i = schema.items.length; i < l; i++) {
var useValue = index_1.isArray(useValues) ? useValues[i] : useValues;
controls.push(buildFormGroupTemplate(jsf, useValue, false, schemaPointer + '/additionalItems', dataPointer + '/' + i, templatePointer + '/controls/' + i));
if (index_1.isArray(useValues)) {
useValues = null;
}
}
if (!index_1.JsonPointer.has(jsf, ['templateRefLibrary', dataPointer + '/-'])) {
jsf.templateRefLibrary[dataPointer + '/-'] =
buildFormGroupTemplate(jsf, null, mapArrays, schemaPointer + '/additionalItems', dataPointer + '/-', templatePointer + '/controls/-');
}
}
}
else {
if (mapArrays && !jsf.arrayMap.get(dataPointer)) {
jsf.arrayMap.set(dataPointer, 0);
}
if (!index_1.JsonPointer.has(jsf.templateRefLibrary, [dataPointer + '/-'])) {
jsf.templateRefLibrary[dataPointer + '/-'] =
buildFormGroupTemplate(jsf, null, mapArrays, schemaPointer + '/items', dataPointer + '/-', templatePointer + '/controls/-');
}
controls = [];
if (jsf.globalOptions.setSchemaDefaults) {
useValues = mergeValues(index_1.JsonPointer.get(schema, '/items/default'), useValues);
}
if (index_1.isArray(useValues) && useValues.length) {
for (var _i = 0, _a = Object.keys(useValues); _i < _a.length; _i++) {
var i = _a[_i];
controls.push(buildFormGroupTemplate(jsf, useValues[i], false, schemaPointer + '/items', dataPointer + '/' + i, templatePointer + '/controls/' + i));
}
useValues = null;
}
}
var initialItemCount = Math.max(minItems, index_1.JsonPointer.has(schema, '/items/$ref') ? 0 : 1);
if (controls.length < initialItemCount) {
for (var i = controls.length, l = initialItemCount; i < l; i++) {
controls.push(buildFormGroupTemplate(jsf, useValues, false, schemaPointer + '/items', dataPointer + '/' + i, templatePointer + '/controls/' + i));
}
}
return { controlType: controlType, controls: controls, validators: validators };
case 'FormControl':
var value = {
value: index_1.isPrimitive(useValues) ? useValues : null,
disabled: schema['disabled'] ||
index_1.JsonPointer.get(schema, '/x-schema-form/disabled') || false
};
return { controlType: controlType, value: value, validators: validators };
case '$ref':
var schemaRef = index_1.JsonPointer.compile(schema.$ref);
if (!index_1.hasOwn(jsf.templateRefLibrary, schemaRef)) {
jsf.templateRefLibrary[schemaRef] = null;
var newTemplate = buildFormGroupTemplate(jsf, null, false, schemaRef);
if (newTemplate) {
jsf.templateRefLibrary[schemaRef] = newTemplate;
}
else {
delete jsf.templateRefLibrary[schemaRef];
}
}
return null;
default:
return null;
}
}
exports.buildFormGroupTemplate = buildFormGroupTemplate;
function buildFormGroup(template) {
var validatorFns = [];
var validatorFn = null;
if (index_1.hasOwn(template, 'validators')) {
index_1.forEach(template.validators, function (parameters, validator) {
if (typeof index_1.JsonValidators[validator] === 'function') {
validatorFns.push(index_1.JsonValidators[validator].apply(null, parameters));
}
});
if (validatorFns.length &&
index_1.inArray(['FormGroup', 'FormArray'], template.controlType)) {
validatorFn = validatorFns.length > 1 ?
index_1.JsonValidators.compose(validatorFns) : validatorFns[0];
}
}
if (index_1.hasOwn(template, 'controlType')) {
switch (template.controlType) {
case 'FormGroup':
var groupControls_1 = {};
index_1.forEach(template.controls, function (controls, key) {
var newControl = buildFormGroup(controls);
if (newControl) {
groupControls_1[key] = newControl;
}
});
return new forms_1.FormGroup(groupControls_1, validatorFn);
case 'FormArray':
return new forms_1.FormArray(_.filter(_.map(template.controls, function (controls) { return buildFormGroup(controls); })), validatorFn);
case 'FormControl':
return new forms_1.FormControl(template.value, validatorFns);
}
}
return null;
}
exports.buildFormGroup = buildFormGroup;
function mergeValues() {
var valuesToMerge = [];
for (var _i = 0; _i < arguments.length; _i++) {
valuesToMerge[_i] = arguments[_i];
}
var mergedValues = null;
for (var index = 0, length_1 = arguments.length; index < length_1; index++) {
var currentValue = arguments[index];
if (!index_1.isEmpty(currentValue)) {
if (typeof currentValue === 'object' &&
(index_1.isEmpty(mergedValues) || typeof mergedValues !== 'object')) {
if (index_1.isArray(currentValue)) {
mergedValues = [].concat(currentValue);
}
else if (index_1.isObject(currentValue)) {
mergedValues = Object.assign({}, currentValue);
}
}
else if (typeof currentValue !== 'object') {
mergedValues = currentValue;
}
else if (index_1.isObject(mergedValues) && index_1.isObject(currentValue)) {
Object.assign(mergedValues, currentValue);
}
else if (index_1.isObject(mergedValues) && index_1.isArray(currentValue)) {
var newValues = [];
for (var _a = 0, currentValue_1 = currentValue; _a < currentValue_1.length; _a++) {
var value = currentValue_1[_a];
newValues.push(mergeValues(mergedValues, value));
}
mergedValues = newValues;
}
else if (index_1.isArray(mergedValues) && index_1.isObject(currentValue)) {
var newValues = [];
for (var _b = 0, mergedValues_1 = mergedValues; _b < mergedValues_1.length; _b++) {
var value = mergedValues_1[_b];
newValues.push(mergeValues(value, currentValue));
}
mergedValues = newValues;
}
else if (index_1.isArray(mergedValues) && index_1.isArray(currentValue)) {
var newValues = [];
var l = Math.max(mergedValues.length, currentValue.length);
for (var i = 0; i < l; i++) {
if (i < mergedValues.length && i < currentValue.length) {
newValues.push(mergeValues(mergedValues[i], currentValue[i]));
}
else if (i < mergedValues.length) {
newValues.push(mergedValues[i]);
}
else if (i < currentValue.length) {
newValues.push(currentValue[i]);
}
}
mergedValues = newValues;
}
}
}
return mergedValues;
}
exports.mergeValues = mergeValues;
function setRequiredFields(schema, formControlTemplate) {
var fieldsRequired = false;
if (index_1.hasOwn(schema, 'required') && !index_1.isEmpty(schema.required)) {
fieldsRequired = true;
var requiredArray = index_1.isArray(schema.required) ? schema.required : [schema.required];
requiredArray = index_1.forEach(requiredArray, function (key) { return index_1.JsonPointer.set(formControlTemplate, '/' + key + '/validators/required', []); });
}
return fieldsRequired;
}
exports.setRequiredFields = setRequiredFields;
function formatFormData(formData, dataMap, recursiveRefMap, arrayMap, fixErrors) {
if (fixErrors === void 0) { fixErrors = false; }
var formattedData = {};
index_1.JsonPointer.forEachDeep(formData, function (value, dataPointer) {
if (typeof value !== 'object') {
var genericPointer = index_1.JsonPointer.has(dataMap, [dataPointer, 'schemaType']) ?
dataPointer :
index_1.resolveRecursiveReferences(dataPointer, recursiveRefMap, arrayMap);
if (index_1.JsonPointer.has(dataMap, [genericPointer, 'schemaType'])) {
var schemaType = dataMap.get(genericPointer).get('schemaType');
if (schemaType === 'null') {
index_1.JsonPointer.set(formattedData, dataPointer, null);
}
else if (index_1.hasValue(value) &&
index_1.inArray(schemaType, ['string', 'integer', 'number', 'boolean'])) {
var newValue = fixErrors ?
index_1.toSchemaType(value, schemaType) :
index_1.toJavaScriptType(value, schemaType);
if (index_1.isDefined(newValue)) {
index_1.JsonPointer.set(formattedData, dataPointer, newValue);
}
}
}
else {
console.error('formatFormData error: Schema type not found ' +
'for form value at "' + genericPointer + '".');
console.error(formData);
console.error(dataMap);
console.error(recursiveRefMap);
console.error(arrayMap);
}
}
});
return formattedData;
}
exports.formatFormData = formatFormData;
function getControl(formGroup, dataPointer, returnGroup) {
if (returnGroup === void 0) { returnGroup = false; }
var dataPointerArray = index_1.JsonPointer.parse(dataPointer);
var subGroup = formGroup;
if (dataPointerArray !== null) {
var l = dataPointerArray.length - (returnGroup ? 1 : 0);
for (var i = 0; i < l; ++i) {
var key = dataPointerArray[i];
if (subGroup.hasOwnProperty('controls')) {
subGroup = subGroup.controls;
}
if (index_1.isArray(subGroup) && (key === '-')) {
subGroup = subGroup[subGroup.length - 1];
}
else if (subGroup.hasOwnProperty(key)) {
subGroup = subGroup[key];
}
else {
console.error('getControl error: Unable to find "' + key +
'" item in FormGroup.');
console.error(dataPointer);
console.error(formGroup);
return;
}
}
return subGroup;
}
console.error('getControl error: Invalid JSON Pointer: ' + dataPointer);
}
exports.getControl = getControl;
function fixJsonFormOptions(layout) {
if (index_1.isObject(layout) || index_1.isArray(layout)) {
index_1.forEach(layout, function (value, key) {
if (index_1.isObject(value) && index_1.hasOwn(value, 'options') && index_1.isObject(value.options)) {
value.titleMap = value.options;
delete value.options;
}
}, 'top-down');
}
return layout;
}
exports.fixJsonFormOptions = fixJsonFormOptions;
//# sourceMappingURL=form-group.functions.js.map