Render Dynamic Input Values - Vuejs

Asked

Viewed 489 times

0

I am doing a project with Vuejs that has 1 form and its data is rendered on the screen, however, this form has options to add more inputs and consequently render this data as well.

Then I get input values by a v-model, through the function insertData() I inserted them into a Object and re-address in a loop by v-for. By function input++ i add more inputs in the form.

BUG:
The problem that is occurring is that when adding more inputs in the form, the data repeats, because the v-model is the same
Excerpt from the Code:

<ul>
  <li v-for="(valor, index) in objFeature" :key="index">
    <p>Funcionalidade: {{valor.feature}}</p>
    <p>Horas de Desenvolvimento: {{valor.devHours}}</p>
    <p>Horas de Teste: {{valor.qaHours}}</p>
  </li>
</ul>


<form v-for="i in input" :key="i" type="text" class="form-control" :id='"item"+i'>
  <label for="features">Funcionalidade:</label>
  <input id="features" type="text" v-model.lazy="features" />

  <label for="dev-hours">Horas de Desenvolvimento:</label>
  <input id="dev-hours" type="number" v-model.lazy.number="devHours" class="test" />

  <label for="qa-hours">Horas de Teste:</label>
  <input id="qa-hours" type="number" v-model.lazy.number="qaHours" />
</form>
<button @click="insertData">Inserir</button>
<button @click="input++" type="button">Adicionar</button>

<script>
export default {
  data() {
    return {
      objFeature: null,
      input: 1
    };
  }
  insertData() {
    this.objFeature = [
      {
        feature: this.features,
        devHours: this.devHours,
        qaHours: this.qaHours
      }
    ];
    return this.objFeature;
  }
};
</script>



I tried to do without v-model, taking input values with JS Vanilla itself (Document.querySelectorAll), but in this situation only the last form was displayed within the <li></li>
Excerpt from the Code:

<ul>
  <li v-for="(valor, index) in objFeature" :key="index">
    <p>Funcionalidade: {{valor.feature}}</p>
    <p>Horas de Desenvolvimento: {{valor.devHours}}</p>
    <p>Horas de Teste: {{valor.qaHours}}</p>
  </li>
</ul>


<form v-for="i in input" :key="i" type="text" class="form-control" :id='"item"+i'>
  <label for="features">Funcionalidade:</label>
  <input id="features" type="text" class="features" />

  <label for="dev-hours">Horas de Desenvolvimento:</label>
  <input id="dev-hours" type="number" class="dev-hours" />

  <label for="qa-hours">Horas de Teste:</label>
  <input id="qa-hours" type="number" class="qa-hours" />
</form>
<button @click="insertData">Inserir</button>
<button @click="input++" type="button">Adicionar</button>

<script>
export default {
  data() {
    return {
      objFeature: null,
      input: 1
    };
  }
  insertData() {
    const elFeatures = document.querySelectorAll('.features');
    const elDevHours = document.querySelector('.dev-hours');
    const elQAHours = document.querySelector('.qa-hours');

    for (let i = 0; i < elFeatures.length; i++) {
      this.objFeature = [
        {
          feature: elFeatures[i].value
        }
      ]
    }
  }
};
</script>



In short, I need to have the option to add more inputs to the form and render this data on the screen.
Follow the full code: https://github.com/GuiiHenriq/he4rtlabs-challenges-02/blob/master/src/components/Main.vue

<template>
  <div class="main">
    <div class="row">
      <section class="actions">
        <button>Inserir</button>
        <button>Apagar</button>
        <button>Importar</button>
        <button @click="createJson">Exportar</button>
      </section>

      <section class="valor-hora">
        <label for="price-hour">Valor Hora:</label>
        <input id="price-hour" type="text" v-model="priceHour" />
      </section>
    </div>

    <div class="row">
      <main>
        <ul>
          <li v-for="(valor, index) in objFeature" :key="index">
            <p>Funcionalidade: {{valor.feature}}</p>
            <p>Horas de Desenvolvimento: {{valor.devHours}}</p>
            <p>Horas de Teste: {{valor.qaHours}}</p>
          </li>
        </ul>
      </main>

      <aside>
        <h2>Funcionalidades:{{features}}</h2>
        <h2>Horas de Desenvolvimento:{{devHours}}</h2>
        <h2>Horas de Teste:{{qaHours}}</h2>
        <h2>Valor Total:{{priceHour}}</h2>
      </aside>
    </div>

    <div class="form">
      <form v-for="i in input" :key="i" type="text" class="form-control" :id='"item"+i'>
        <label for="features">Funcionalidade:</label>
        <input id="features" type="text" v-model.lazy="features" />

        <label for="dev-hours">Horas de Desenvolvimento:</label>
        <input id="dev-hours" type="number" v-model.lazy.number="devHours" class="test" />

        <label for="qa-hours">Horas de Teste:</label>
        <input id="qa-hours" type="number" v-model.lazy.number="qaHours" />
      </form>
      <!--<form v-for="i in input" :key="i" type="text" class="form-control" :id='"item"+i'>
        <label for="features">Funcionalidade:</label>
        <input id="features" type="text" class="features" />

        <label for="dev-hours">Horas de Desenvolvimento:</label>
        <input id="dev-hours" type="number" class="dev-hours" />

        <label for="qa-hours">Horas de Teste:</label>
        <input id="qa-hours" type="number" class="qa-hours" />
      </form>-->

      <button @click="insertData">Inserir</button>
      <button @click="input++" type="button">Adicionar</button>
    </div>
  </div>
</template>

<script>
export default {
  name: "Main",
  data() {
    return {
      priceHour: 0,
      features: "",
      devHours: 0,
      qaHours: 0,
      objFeature: null,
      input: 1
    };
  },
  methods: {
    insertData() {
      this.objFeature = [
        {
          feature: this.features,
          devHours: this.devHours,
          qaHours: this.qaHours
        }
      ];
      return this.objFeature;

      /*const elFeatures = document.querySelectorAll('.features');
      const elDevHours = document.querySelector('.dev-hours').value;
      const elQAHours = document.querySelector('.qa-hours').value;
      for (let i = 0; i < elFeatures.length; i++) {
        this.objFeature = [
          {
            feature: elFeatures[i].value
          }
        ]
      }*/
    },
    createJson() {
      const jsonExport = {
        feature: this.features,
        devHours: parseFloat(this.devHours),
        testHours: parseFloat(this.qaHours)
      };
      console.log(jsonExport);
    }
  }
};
</script>

1 answer

1


I didn’t get your code, because, you’re going the wrong way, the example below will show you how render items from a simple form with a text box.

This minimal example will give you a north that can help solve your problem, check the example:

Vue.config.devtools = false;
Vue.config.productionTip = false
var vm = new Vue({
  el: '#app',
  data: {
    todos: [{
      'id': 1,
      'name': 'name 1'
    }],
    name: ''
  },
  methods: {
    handleSubmit: function(e) {
      e.preventDefault();
      if (this.name.trim().length) {
        const obj = {
          'id': this.todos.length + 1,
          'name': this.name
        }
        this.todos.push(
          obj
        );
        this.name = '';
      }
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <form @submit="handleSubmit">
    <input type="text" v-model="name" placeholder="name" />
    <button>Adicionar</button>
  </form>
  <ul v-for="item in todos" :key="item.id">
    <li>{{item.name}}</li>
  </ul>
</div>

  • Thanks, really with that logic worked!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.