Home > front end >  How to get input data from multiple inputs in dynamic form as a single object?
How to get input data from multiple inputs in dynamic form as a single object?

Time:07-09

How can I get all input values from dynamic form as a single object with key-values pairs? Where key is input name and value is user input.

I have a custom input component. In app component I dynamically render inputs from array:

<template>
  <div>
    <form @submit.prevent="submit">
      <ul>
        <li v-for="input in inputFields" :key="input.label">
          <base-input
            :placeholder="input.placeholder"
            :type="input.type"
            :name="input.name"
            v-model="userInput[input.name]"
          ></base-input>
        </li>
      </ul>
      <button type="submit">Console.log input</button>
    </form>
  </div>
</template>

<script>
import BaseInput from "./components/BaseInput.vue";
export default {
  components: { BaseInput },

  data() {
    return {
      inputFields: INPUT_FIELDS,
      userInput: {
        name: "",
        phone: "",
        email: "",
        location: "",
        address: "",
        comment: "",
      },
    };
  },

  methods: {
    submit() {
      console.log("userInput:", this.userInput);
    },
  },
};
</script>

Then in base-input component:

 <template>
      <input
        :type="type"
        :name="name"
        :placeholder="placeholder"
        @input="$emit('update:modelValue', $event.target.value)"
        :value="modelValue[name]"
      />
    </template>
    
    <script>
    export default {
      emits: ["update:modelValue"],
      props: {
        label: {
          type: String,
          required: false,
        },
        placeholder: {
          type: String,
          required: true,
        },
        type: {
          type: String,
          required: true,
        },
        name: {
          type: String,
          required: false,
        },
        modelValue: {},
      },
    };
    </script>

Expected behavior: click on submit --> get object like in console:

 {
    name: "user name",
    phone: "1111",
    email: "[email protected]",
    location: "World",
    address: "",
    comment: "no",
  },

Actual behavior: I can only type 1 letter in a field and no more.

Here's a codesandbox: https://codesandbox.io/s/optimistic-alex-dzw0mp?file=/src/App.vue

CodePudding user response:

You were close. You need to remove [name] from the end of :value="modelValue[name]" in the base-input component. Since you are already scoping to name in the parent component it is wrong to also look for a [name] prop on the value of modelValue within your child component.

See it working here: https://codesandbox.io/s/unruffled-cohen-bivefc?file=/src/components/BaseInput.vue

Your component template should be:

 <input
    :type="type"
    :name="name"
    :placeholder="placeholder"
    @input="$emit('update:modelValue', $event.target.value)"
    :value="modelValue"
  />
  • Related