You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have been working with dynamically rendering Tabs in Formio which has thrown up a lot of issues. Eventually I landed on a solution of amending the schema directly and using setForm.
This has worked smoothly however when adding in an 'editgrid' component. When the form.setForm() functionality is called it breaks the functionality of the Edit Grid component. None of the HTML gets injected into the Edit Grid component and the components are not rendered.
As you can see, it is still possible to add the new components however the HTML / JS templating that is in the templates appears to be broken and does not render the actual component. I have isolated this behaviour to specifically only break on form.setForm(newFormSchema) being called.
Code
Below is a stripped down version of my code that highlights the relevant parts. I have included the JSON for my Edit Grid Component. Some of the Templating has been deleted to avoid confusion.
import { cloneDeep } from 'lodash';
const editGrid = {
"label": "some_sample_label",
"labelPosition": "left-left",
"labelWidth": 30,
"openWhenEmpty": false,
"tableView": false,
"rowDrafts": false,
"key": "some_sample_key",
"type": "editgrid",
"displayAsTable": false,
"input": true,
"templates": {
"header": "<div class=\"row\">\n {% util.eachComponent(components, function(component) { %}\n {% if (displayValue(component)) { %}\n <div class=\"col-sm-5\">{{ t(component.label) }}</div>\n {% } %}\n {% }) %}\n </div>",
"row": "<div class=\"row\">\n {% util.eachComponent(components, function(component) { %}\n {% if (displayValue(component)) { %}\n <div class=\"col-sm-5\">\n {{ isVisibleInRow(component) ? getView(component, row[component.key]) : ''}}\n </div>\n </div>"
},
"components": [
{
"label": "Code",
"labelPosition": "left-left",
"labelWidth": 30,
"widget": "choicesjs",
"tableView": true,
"dataSrc": "url",
"data": {
"url": "somedataurl"
},
"dataType": "object",
"validate": {
"required": true
},
"key": "code",
"template": "<span>{{ item.value }} - {{ item.label }}</span>",
"type": "select",
"input": true,
"lazyLoad": false,
"disableLimit": false
},
{
"label": "Quantity",
"labelPosition": "left-left",
"labelWidth": 30,
"mask": false,
"tableView": true,
"defaultValue": "1",
"truncateMultipleSpaces": false,
"validate": {
"required": true
},
"key": "quantity",
"calculateValue": "if (value) { value = value.replace(/[^0-9]/g, ''); }",
"type": "textfield",
"input": true
}
]
}
// this is the callback function of the form.createForm()
const doCustomFormLogic = (form) => {
//simplified version of what is happening
form.on('initialized', () => handleInitialize(form));
};
// in this situation we are trying to dynamically add multiple tabs to a tabs component.
//I have tried many different ways and this is the only one that I could get working that also managed data and validation properly
const handleInitialize = (form) => {
//custom component to insert into our tabs component
const customComponent = { someComponentJSON: 'substituting this for actual component' };
// avoid directly mutating our original schema
const newFormSchema = cloneDeep(form.schema);
// append the new JSON into the form schema
newFormSchema.components[4].components[2].push(customComponent);
// setForm, this attaches listeners, enable validation etc. This is the part that overwrite the editgrid component
form.setForm(newFormSchema);
//redraw the form to finalise everything
form.redraw();
}
Avenues that I have explored
I am open to other ways of managing the Dynamic Tabs however I have tried many options so am not hopeful that there are many avenues
It doesn't seem possible to selectively setForm() and exclude certain components
I have attempted to extract the edit grid component and reinsert it following the rebuild
I have attempted to manually trigger the Edit Grid build process, editGrid.build(); editgrid.render(); editgrid.attach(); editgrid.redraw(); however this throws up the error involving querySelectorAll and loadRefs() so I don't know what is happening there.
I have tried to exclude different stages of the setForm() cycle eg. {noRebuild:true}
Thoughts
As far as I can guess, calling form.setForm() sets the form schema but in such a way that the Edit Grid templating is not called, so whatever part of the render cycle triggers the Edit Grid templating insertion does not get triggered.
Thanks in advance for the help!
The text was updated successfully, but these errors were encountered:
Background
I have been working with dynamically rendering Tabs in Formio which has thrown up a lot of issues. Eventually I landed on a solution of amending the schema directly and using setForm.
This has worked smoothly however when adding in an 'editgrid' component. When the form.setForm() functionality is called it breaks the functionality of the Edit Grid component. None of the HTML gets injected into the Edit Grid component and the components are not rendered.
As you can see, it is still possible to add the new components however the HTML / JS templating that is in the templates appears to be broken and does not render the actual component. I have isolated this behaviour to specifically only break on form.setForm(newFormSchema) being called.
Code
Below is a stripped down version of my code that highlights the relevant parts. I have included the JSON for my Edit Grid Component. Some of the Templating has been deleted to avoid confusion.
Avenues that I have explored
Thoughts
As far as I can guess, calling form.setForm() sets the form schema but in such a way that the Edit Grid templating is not called, so whatever part of the render cycle triggers the Edit Grid templating insertion does not get triggered.
Thanks in advance for the help!
The text was updated successfully, but these errors were encountered: