Nora
Nora

Reputation: 186

How to dynamically generate form elements and store values (Vue 3)

I am trying to create a modal component that does not use Vue slots and only takes a configuration object to determine the content of the modal. So far I've managed to figure out a way to fill the component with the required input fields and form elements but I'm having trouble with binding the data from the input to the v-model variables.

A person would use the component by passing a content array of objects as a prop:

<ReusableDialog
  :content="[ 
    {label: 'Text Field', type: 'inputField'}, 
    {label: 'Text Area', type: 'textArea'} 
  ]"
/>

And then I can access that prop in my ReusableDialog template and loop through the array. For each item in that array I will check the type of form element that was entered (e.g. "textArea", "inputField") and dynamically generate the element.

<div v-for="(item, index) in props.content" :key="item">
  <template v-if="item.type == 'inputField'" style="margin-top: 1rem;">
    <label>{{ item.label }}</label>
    <input
      type="text"
      :v-model="contentArray[index]"
      placeholder="Enter text"
    />
  </template>

  <template v-if="item.type == 'textArea'" style="margin-top: 1rem;">
    <label>{{ item.label }}</label>
    <textarea
      name="textarea"
      :v-model="contentArray[index]"
      cols="10"
      rows="10"
    ></textarea>
  </template>
</div>
<button label="submit" @click="getAllData" />

My setup looks like this:

    setup(props) {
            const displayDialog = ref(false);
            const contentArray = ref([null, null, null, null, null, null, null, null, null]);

            const open = () => {
                displayDialog.value = true;
            };
            const close = () => {
                displayDialog.value = false;
            };

            const getAllData = () => {
                console.log(contentArray.value);
            }

            return {
                displayDialog, open, close, props, getAllData, contentArray
            }
        }
    }

When the getAllData() method print the contentArray all the values remain null. Using my example above the first and the second values should change with the input but they do not. Not sure if I'm in the direction here but I need some suggestions on if there is a better way to do this?

Upvotes: 2

Views: 3594

Answers (1)

Daniel
Daniel

Reputation: 35684

Everything is setup correctly, it's just a small typo, if we can call it that.

v-model should not have the :

so

  :v-model="contentArray[index]"

should be

  v-model="contentArray[index]"

As an aside you can set length of array with

const contentArray = Vue.ref(new Array(props.content.length));

Upvotes: 2

Related Questions