Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically create Input Fields in VueJS

I'm trying to dynamically add or remove input fields on the go.

I got a simple solution from here https://smarttutorials.net/dynamically-add-or-remove-input-textbox-using-vuejs/, which works. However saving input values in the database stops it's functionality.

Component Code:

<div class="form-group" v-for="(input,k) in inputs" :key="k">
  <input type="text" class="form-control" v-model="input.name" />
  <input type="text" class="form-control" v-model="input.party" />
  <span>
    <i
      class="fas fa-minus-circle"
      @click="remove(k)"
      v-show="k || ( !k && inputs.length > 1)"
    ></i>
    <i
      class="fas fa-plus-circle"
      @click="add(k)"
      v-show="k == inputs.length-1"
    ></i>
  </span>
</div>
<button @click="addCandidate">
  Submit
</button>

<script>
  export default {
    data() {
      return {
        inputs: [
          {
            name: "",
            party: ""
          }
        ]
      };
    },
    methods: {
      add(index) {
        this.inputs.push({ name: "", party: "" });
      },
      remove(index) {
        this.inputs.splice(index, 1);
      },
      addCandidate() {
        axios
          .post("/candidates", this.inputs)
          .then(response => {})
          .catch(error => {});
      }
    }
  };
</script>

I always get a 422 error, saying the input field is empty.

like image 713
LDUBBS Avatar asked Jul 16 '19 16:07

LDUBBS


People also ask

How do I create a dynamic component in VUE 3?

To create a dynamic component, we use the component element and bind the is prop to it to specify which component we want to render. note The component and slot elements aren't true components, they are component-like features of Vue's template syntax. We do not have to import them like we do with regular components.

What is $V in Vue?

$v is an object that calls vuelidate (at the time of writing the comment, supported in version Vue. js 2.0), which is intended to check every input, which is made in a non-html form.


1 Answers

This is not a Vue problem. Before you send an array you'll need to call JSON.stringify() on it, then decode it on the server with Laravel. Example:

foreach(json_decode($request -> input('my_prop_name ')) as $my_object_in_array)
{
  print_r($my_object_in_array); // this is your object name/party
}

Vue code working like magic. :)

new Vue({
  el: '#app',

  data () {
    return {
      inputs: [{
        name: '',
        party: ''
      }]
    }
  },

  methods: {
    add () {
      this.inputs.push({
        name: '',
        party: ''
      })
      console.log(this.inputs)
    },

    remove (index) {
      this.inputs.splice(index, 1)
    },

    addCandidate () {
      axios
        .post('/candidates', {
          my_prop_name: JSON.stringify(this.inputs)
        })
        .then(response => {})
        .catch(error => {})
    }
  }
})
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id=app>
  <div class="form-group" v-for="(input,k) in inputs" :key="k">
    <input type="text" class="form-control" v-model="input.name">
    <input type="text" class="form-control" v-model="input.party">
    <span>
      <i class="fas fa-minus-circle" @click="remove(k)" v-show="k || ( !k && inputs.length > 1)">Remove</i>
      <i class="fas fa-plus-circle" @click="add(k)" v-show="k == inputs.length-1">Add fields</i>
    </span>
  </div>
  <button @click="addCandidate">
    Submit
  </button>
</div>
like image 137
Sabee Avatar answered Oct 23 '22 13:10

Sabee