Using schema to make a vue-form-generator section collapse-able

Viewed 509

I'm using the vue-form-generator library to create a form.

The problem is my form has 116 questions on it and I would like to collapse some questions, making the form more manageable for users.

My form has five sections. So each question in my form has the section attribute in the schema. However, the section part is not a form field such as label that you can modify. The sections are automatically generated into headings for you.

Apart from creating custom form fields, is there any way to make these sections collapse-able?

One route that I was thinking of trying would be to split my form into five forms, which will allow me to place a vue-bootstrap collapse element around each form. Something like:

<b-collapse id="collapse1" class="mt-2">
<vue-form-generator  :schema="survey.schema" :options="survey.formOptions" :model="survey.model"></vue-form-generator>
</b-collapse>

But this would then again make submission of the form more difficult, since I would have to splice the results of all five forms.

Is there any easier solution to this problem?

1 Answers

I had the same problem recently and this is the only way I found to solve it.

In the schema object add a .collapse class to the group like so:

const schema = {
  groups: [
    {
      styleClasses: 'collapse',
      legend: 'Group title',
      fields: [ ...

On the parent component add a collapse method and attach an onclick event to the fieldset's legend, you can access the form in the vue mounted lifecycle hook, like below:

    ...
    methods: {
        collapse(e) {
            const group = e.target.parentElement;
            group.classList.toggle("hide");
        }
    },
    mounted() {
        const collapsableLegends = this.$el.querySelectorAll('.vue-form-generator .collapse legend');
        collapsableLegends.forEach(legend => legend.onclick = this.collapse);
    }
    ...

Finally add a .hide class to your css:

.vue-form-generator .collapse.hide .form-group { display: none }

It's a bit hacky, but it get the job done.

Related