/**
* Converts FormIO schema into JSONForm format
*/
const FormIOConverter = function() {
}
FormIOConverter.typeMap = {
// formIoType : JSONFormType
"textfield" : "text",
"selectboxes" : "checkboxes",
"radio" : "radios",
"well": "section",
"panel": "fieldset",
}
FormIOConverter.prototype.formIOtoJSONForm = function(formIOSchema) {
const JSONForm = {
schema: {},
form: []
}
const convertType = (type)=> {
if (FormIOConverter.typeMap[type]) return FormIOConverter.typeMap[type];
return type;
}
if (typeof formIOSchema !== "object") return JSONForm;
if (Array.isArray(formIOSchema)) {
// assume components
formIOSchema = {
components : formIOSchema
}
}
const fetchComponents = (formIOComponents, JSONFormForm, parentComponent)=> {
for (let i in formIOComponents) {
let thisComponent = formIOComponents[i];
JSONForm.schema[thisComponent.key] = {
type: "string", // default
title: thisComponent.label,
default: thisComponent.defaultValue,
}
let JSONFormSchema = JSONForm.schema[thisComponent.key]
let thisForm = {}
thisForm = thisComponent;
// translates validation
if (thisComponent.validate) {
if (typeof thisComponent.validate.required !== "undefined") JSONFormSchema.required = thisComponent.validate.required;
}
//translate html attributes
if (thisComponent.attributes) {
thisForm.htmlMetaData = thisComponent.attributes
}
//translate custom class
//FormIO only applies classes on the wrapper and not on the field
if (thisComponent.customClass) {
thisForm.htmlClass = thisComponent.customClass
}
if (["checkbox"].includes(thisComponent.type)) {
JSONFormSchema.type = "boolean"
thisForm.inlinetitle = thisComponent.label
} else if (["number"].includes(thisComponent.type)) {
JSONFormSchema.type = "number"
} else if (["selectboxes"].includes(thisComponent.type)) {
// map selection
let thisEnum = []
let titleMap = {}
for (let x in thisComponent.values) {
let thisKey = thisComponent.values[x].value;
thisEnum.push(thisKey);
titleMap[thisKey] = thisComponent.values[x].label;
}
JSONFormSchema.items = {
type: "string",
title: thisComponent.label,
enum:thisEnum
}
thisForm.titleMap = titleMap;
} else if (["radio"].includes(thisComponent.type)) {
// map selection
let thisEnum = []
let titleMap = {}
for (let x in thisComponent.values) {
let thisKey = thisComponent.values[x].value;
thisEnum.push(thisKey);
titleMap[thisKey] = thisComponent.values[x].label;
}
JSONFormSchema.enum = thisEnum;
thisForm.titleMap = titleMap;
} else if (["select"].includes(thisComponent.type)) {
let thisEnum = []
let titleMap = {}
if (thisComponent?.data?.values) {
for (let x in thisComponent.data.values) {
let thisKey = thisComponent.data.values[x].value;
thisEnum.push(thisKey);
titleMap[thisKey] = thisComponent.data.values[x].label;
}
}
JSONFormSchema.enum = thisEnum;
thisForm.titleMap = titleMap;
}
// if has components then recursively translate FormIO components to JSONForm's items
if (thisComponent.components) {
//recursive
thisForm.items = [];
// view only shouldn't have key
if (thisForm.key) {
thisForm.formIOKey = thisForm.key;
delete thisForm.key;
}
fetchComponents(thisComponent.components, thisForm.items, thisComponent)
}
if (parentComponent?.type == "tabs") {
// formIO don't have form type for immidiate tabs's child
thisForm.type = "tab"
thisForm.id = thisForm.formIOKey;
} else {
// translate types according to the FormIOConverter.typeMap definition
thisForm.type = convertType(thisForm.type)
}
JSONFormForm.push(thisForm);
}
return JSONForm;
}
return fetchComponents(formIOSchema.components, JSONForm.form);
}
module.exports = FormIOConverter;