0
<b-row>
                    <b-form-group class="col-md-12" id="input-group-12">
                      <h2 class="h2">Přidání příloh</h2>
                      <a
                        href="#"
                        class="plus-minus-toggle collapsed"
                        @click="addRow"
                      >
                      </a>
                      <table class="table">
                        <tbody>
                          <div class="container-fluid" style="padding-left:0">
                            <div class="row">
                              <tr
                                v-for="(row, index) in rows"
                                :key="index.toString()"
                                class="col-md-6 form-group form-group-block"
                              >
                                <td>
                                 <b-form-file
                                    v-model="row.id"
                                    accept=".pdf"
                                    placeholder="Vyberte PDF soubor"
                                    drop-placeholder="Drop file here..."
                                  ></b-form-file>
                                </td>
                                <td>
                                  <a
                                    @click="removeElement(index)"
                                    class="plus-minus-toggle"
                                  ></a>
                                </td>
                              </tr>
                            </div>
                          </div>
                        </tbody>
                      </table>

                      <div></div>
                    </b-form-group>
                  </b-row>

export default {
  components: { Multiselect /*pdf*/ },
  data() {
    return {
      rows: [],
    }
  },
  methods: {
    addRow: function(event) {
      event.preventDefault()

      var elem = document.createElement('tr')
      console.log(elem)
      this.rows.push({
        title: '',
        description: '',
        file: {
          name: 'Vyberte přílohu'
        }
      })
    },
    removeElement: function(index) {
      console.log(index)
      /*   if (index >= 0) {

      }
      index + 1
      return false*/
      this.rows.splice(index, 1)
      index + 1
    },
    setFilename: function(event, row) {
      //var file
      /* if (event.target.files[0] !== 1) {
        this.$refs.index.innerText = 'Vyberte přílohu'
        return
      }
*/
      var file = event.target.files[0]
      row.file = file
    }
  }
}

**I have this code but it is not deleting properly when I have standart input type text the function removeElement is working properly. I just don't know where the fault is Any suggestions please ? I did research on google but with no luck. Can you please help me ? I edited code now i have methods and also data. **

15
  • Jakub, could you post your code exactly is as in the file? The 'removeElement' should be a method. Commented Dec 6, 2019 at 10:51
  • i edited post and added data and methods Commented Dec 6, 2019 at 11:26
  • What do you mean with "not working properly"? Does it sometimes work, but other times not? And what do you mean with when you have "standart input type text"? How does the text input relate to the table rows? Commented Dec 6, 2019 at 11:42
  • it is not deleting the proper row when i click delete button, when i am using input text it is working normally Commented Dec 6, 2019 at 11:45
  • 2
    Do not use the table index to indicate row keys. During the splice operation on the array, these indexes change, they are numbered from the beginning. If you delete the middle item, all others update their index -1. Commented Dec 6, 2019 at 12:27

1 Answer 1

3

An example illustrating my suggestion

Vue.config.productionTip = false;
Vue.use(BootstrapVue);

new Vue({
  template: "#main",
  data() {
    return {
      text: "",
      items: [],
      index: 1
    };
  },
  methods: {
    addRow(text) {
      this.items.push({
        text: text || this.text,
        index: this.index++,
        file: null
      });
    },
    removeRow(index) {
      this.items = this.items.filter(item => item.index !== index);
    }
  },
  mounted() {
    this.addRow("Foo");
    this.addRow("Bar");
    this.addRow("Fus");
    this.addRow("Ro");
    this.addRow("Dah");
  }
}).$mount("#app");
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" />
<script src="//polyfill.io/v3/polyfill.min.js?features=es2015%2CIntersectionObserver" crossorigin="anonymous"></script>
<script src="//unpkg.com/vue@latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>

<div id="app">Vue App</div>

<script type="text/x-template" id="main">
  <div>
    <input v-model="text" />
    <button @click="addRow()">Add</button>
    <table class="table">
      <tbody>
        <tr v-for="item in items" :key="`file-row-${item.index}`">
          <td>{{item.text}}</td>
          <td>{{item.index}}</td>
          <td><b-form-file v-model="item.file" accept=".pdf"></b-form-file></td>
          <td><button @click="removeRow(item.index)">x</button></td>
        </tr>
      </tbody>
    </table>
  </div>
</script>

Sign up to request clarification or add additional context in comments.

9 Comments

thank you but i need add input file to table not just plain text
Here you are. File field added.
thank you so much but one more thing compiler si giving me error:Elements in iteration expect to have 'v-bind:key' directives in tr
Add something like <tr v-for="(item, index) in items" :key="`file-row-${index}`"> so your TR has a unique key. Though using index is usually a bad idea, so if your item object contains something unique use that instead like :key="`file-row-${item.id}`" if your item contains a unique id
@JakubBocek, If my answer has been helpful, accept it as a solution.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.