0

So I'm bringing in data from a CMS which is dynamically creating a title, a size and an input field which the user will be able to change.

When I increase the input value (1, 2, 3, 4 etc) the value changes in all inputs.

I need to take the number of individual inputs and do something with it.

I can kind of get this to work if I have my input type set to number but I want to keep it set to text so I can use custom increment and decrement buttons. As I said the buttons and the counter works but values clone to every input. I'm sure it's something to do with the increaseQty and decreaseQty functions..

I'm very new to Vue so be gentle. Thanks a million - Code below

<template>
  <div>
    <div id="step2items0" class="inventory">
      <div class="inner-wrap">
        <label>Choose Your {{ selected }} Items</label>
      </div>
      <div id="tabBtns" class="hr">
        <div class="inner-wrap mobile-center">
          <div v-for="(tab, index) in tabs" :key="index" @click="selectTab(tab)" class="tab" :class="selected_tab == tab ? 'selected' : ''" >
            {{ tab }}
          </div>
        </div>
      </div>

      <div class="items-wrap">
        <div class="item" v-for="(row, index) in items" :key="index">
          <span class="lbl">{{ row.item_title }}</span>

          <span class="input-wrap" style="display: flex; flex-direction: column">
            <input type="text" name="item_m3" class="number" :value="row.item_m3"/>
            <small>Item M3</small>
          </span>


          <span class="input-wrap">
            <i id="decreaseQty" aria-hidden="true" class="fa fa-caret-left prev-btn" @click="decreaseQty"></i>

            <input id="quantity" type="text" class="number" :value="quantity"/>

            <i id="increaseQty" aria-hidden="true" class="fa fa-caret-right nxt-btn" @click="increaseQty"></i>
          </span>

          <div class="clear"></div>
        </div>
      </div>
    </div>
  </div>
</template>






<script>
module.exports = {
  props: ["selected", "content", "value"],

  data: function () {
    return {
      tabs: [],
      selected_tab: "",
      items: [],
      quantity: 0,
    };
  },
  computed: {

  },

  methods: {
    //

    increaseQty() {
      this.quantity++;
      console.log("AMOUNT -", this.quantity);
    },
    decreaseQty() {
      if (this.quantity === 0) {
        alert("Negative quantity not allowed");
      } else {
        this.quantity--;
        console.log("AMOUNT -", this.quantity);
      }
    },
    //

    selectTab: function (value) {
      console.log("TAB: ", value);
      this.selected_tab = value;
      const { content } = this;
      let { items } = this;

      content.forEach(function (row) {
        if (row.room_name == value) {
          items = row.item;

          items.forEach(function (row) {
            item_title = row.item_title;
            item_m3 = row.item_m3;
            console.log(" - ", item_title, " - ", item_m3);
          });
        }
      });

      this.items = items;
    },
  },
  mounted: function () {
    const { selected, content, tabs } = this;
    let { selected_tab, items } = this;

    console.log("SELECTED: ", selected);

    if (selected === "Household") {
      content.forEach(function (row) {
        if (row.is_household == true) {
          tabs.push(row.room_name);

          if (selected_tab == "") {
            selected_tab = row.room_name;

            items = row.item;

            items.forEach(function (row) {
              item_title = row.item_title;
              item_m3 = row.item_m3;
              console.log(" - ", item_title, " - ", item_m3);
            });
          }
        }
      });
    } else if (selected === "Business") {
      content.forEach(function (row) {
        if (row.is_business == true) {
          tabs.push(row.room_name);

          if (selected_tab == "") {
            selected_tab = row.room_name;

            items = row.item;

            items.forEach(function (row) {
              item_title = row.item_title;
              item_m3 = row.item_m3;
              console.log(row.room_name, " - ", item_title, " - ", item_m3);
            });
          }
        }
      });
    }

    this.selected_tab = selected_tab;
    this.items = items;
  },
};
</script>

<style scoped>
</style>

Input increment is affecting all inputs

ID stay the same no matter what button is clicked on any item

  • 1
    you should do `@click="increaseQty(row)"`, then inside increaseQty, it has a param `increaseQty(row){}`, then inside the func, you do `this.$set(row, 'qty', typeof row.qty !== 'undefined' ? row.qty+1 : 1)` `:value="quantity"` then should be `:value="row.qty || 0"` – Lawrence Cherone Aug 12 '21 at 09:45
  • @LawrenceCherone that has done the job thank you! Would you mind explaining why it works? I know I had to pass something into the function but I would never have got the rest – Sam Donaghy-Bell Aug 12 '21 at 09:54
  • each item in `items` call it `row`, is an object, all its doing is passing the specific object to the function to be manipulated, the `this.$set`, is used because if a property doesn't exist already on the object then it's not reactive. – Lawrence Cherone Aug 12 '21 at 09:59

1 Answers1

1

You can get individual values inside the v-for by storing the values in an array.

data: {
    items: [],
    itemValues: [],
  },

And use v-model to bind the input (you are using v-bind:value, not v-model). You can check this answer to learn the difference.

<div class="item" v-for="(row, index) in items" :key="index">
    <input type="text" v-model="itemValues[index]">
</div>

Here's a fiddle: https://jsfiddle.net/jariway/jxv0k4y3/62/

Mikel Granero
  • 379
  • 6
  • 15
  • The problem I'm having is when I click the increment and decrement buttons I can see in the console that no matter which buttons I click it's only giving me the ID of the last one. I've updated the post to show – Sam Donaghy-Bell Aug 12 '21 at 09:42
  • @SamDonaghy-Bell Then you need to pass the index to the onClick listener. Check the updated fiddle in the answer. This way you can increase the values individually. – Mikel Granero Aug 12 '21 at 10:12
  • Thank you. I've got it working with Lawrence's answer but I'm sure I'll be back in here once I try and add more function to it and break things entirely! haha. – Sam Donaghy-Bell Aug 12 '21 at 10:19