formio / vue

Javascript Powered forms and JSON form builder for Vue.js
MIT License
119 stars 65 forks source link

[BUG] FormBuilder: Duplicate settings modals #35

Closed cymen closed 8 months ago

cymen commented 4 years ago

Environment

Please provide as many details as you can:

Steps to Reproduce

  1. Create a form using wizard
  2. Add multiple panels
  3. Click settings for first panel
  4. Close settings, observe same settings panel behind one you just closed

(same thing sometimes happens with form fields)

Expected behavior

To only have one settings modal open.

Observed behavior

Often, two settings modals open.

cymen commented 4 years ago

One way to work around this is, with two steps, clicking back and forth a couple of times on the steps and then clicking settings. That results in a single modal.

cymen commented 4 years ago

Debugging from the browser side, when I get two modals, I do indeed see an extra listener present:

Screen Shot 2019-11-11 at 2 40 01 PM

And after clicking back and forth to make it only show one modal, we see:

Screen Shot 2019-11-11 at 2 39 54 PM

cymen commented 4 years ago

I loaded the form in direct vanilla JavaScript with the formio.js FormBuilder and it didn't have this problem.

starker-xp commented 4 years ago

i have the same issue

Environment

Please provide as many details as you can:

Steps to Reproduce

  1. Create a form with one textfield
  2. Retrieve JSON Data
  3. Load builder with JSON Data
  4. Try to edit text field

Expected behavior

When i click on edit button i expected one modal.

Observed behavior

Two modal

Example

<template>
  <div id="app">
    <FormBuilder
      :form="{display: 'form', components: myFormData}"
      :options="{}"
      :change="(schema) => console.log(schema)"
    ></FormBuilder>
  </div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { FormBuilder } from 'vue-formio';

@Component({
  components: { FormBuilder },
})
export default class App extends Vue {
  myFormData = [
    {
      label: 'Firstname',
      labelPosition: 'top',
      placeholder: '',
      description: '',
      tooltip: '',
      prefix: '',
      suffix: '',
      widget: { type: 'input' },
      inputMask: '',
      allowMultipleMasks: false,
      customClass: '',
      tabindex: '',
      hidden: false,
      hideLabel: false,
      showWordCount: false,
      showCharCount: false,
      mask: false,
      autofocus: false,
      spellcheck: true,
      disabled: false,
      alwaysEnabled: false,
      tableView: false,
      multiple: false,
      defaultValue: '',
      persistent: true,
      inputFormat: 'plain',
      protected: false,
      dbIndex: false,
      case: '',
      encrypted: false,
      redrawOn: '',
      clearOnHide: true,
      customDefaultValue: '',
      calculateValue: '',
      allowCalculateOverride: false,
      validateOn: 'change',
      validate: {
        required: false,
        pattern: '',
        customMessage: '',
        custom: '',
        customPrivate: false,
        json: '',
        strictDateValidation: false,
        minLength: '',
        maxLength: '',
      },
      unique: false,
      errorLabel: '',
      key: 'prenom',
      tags: '',
      properties: {},
      conditional: { show: '', when: '', eq: '', json: '' },
      customConditional: '',
      type: 'textfield',
      input: true,
      refreshOn: '',
      attributes: {},
      overlay: { style: '', left: '', top: '', width: '', height: '' },
      inputType: 'text',
      id: 'en5dmlf',
    },
  ];
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
starker-xp commented 4 years ago

Thanks @cymen, considering the delay that I overloaded the formbuilder with the code below:

<template>
  <div ref="builder"></div>
</template>
<script lang="ts">
/* globals console, Promise */
import Vue from 'vue';
import { Component, Prop, Watch } from 'vue-property-decorator';
import FormioFormBuilder from 'formiojs/FormBuilder';
import AllComponents from 'formiojs/components';
import Components from 'formiojs/components/Components';
Components.setComponents(AllComponents);

@Component({})
export default class FormBuilder extends Vue {
  builder?: any;

  @Prop()
  form?: any;

  @Prop()
  options?: any;

  mounted() {
    this.initializeBuilder().catch((err: any) => {
      /* eslint-disable no-console */
      console.warn(err);
      /* eslint-enable no-console */
    });
  }

  async initializeBuilder(): Promise<any> {
    if (this.form) {
      // @ts-ignore
      this.builder = window.Formio.builder(
        this.$refs.builder,
        this.form,
        this.options,
      ).then((builder: any) => {
        builder.on('saveComponent', () => {
          this.$emit('change', builder.schema);
        });
      });
    }
    // If we get to here there is no src or form
    return Promise.reject('Must set form attribute');
  }
}
</script>
jeriah-formio commented 8 months ago

We're currently addressing a backlog of GitHub issues. Closing this thread as it is outdated. Please re-open if it is still relevant. Thank you for your contribution!