3
votes

I have a Data table using BootstrapVue constructed from json items and the code is as follows:

<template>
  <div>
    <b-table small :fields="fields" :items="items" responsive="sm">
      <!-- A virtual column -->
      <template v-slot:cell(index)="data">
        {{ data.index + 1 }}
      </template>

      <!-- A custom formatted column -->
      <template v-slot:cell(name)="data">
        <b class="text-info">{{ data.value.last.toUpperCase() }}</b>, <b>{{ data.value.first }}</b>
      </template>

      <!-- A virtual composite column -->
      <template v-slot:cell(nameage)="data">
        {{ data.item.name.first }} is {{ data.item.age }} years old
      </template>

      <!-- Optional default data cell scoped slot -->
      <template v-slot:cell()="data">
        <b-form-input v-model="data.value" placeholder="Enter custom value" />
      </template>
    </b-table>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        outputItems: [],
        fields: [
          // A virtual column that doesn't exist in items
          'index',
          // A column that needs custom formatting
          { key: 'name', label: 'Full Name' },
          // A regular column
          'age',
          // A regular column
          'sex',
          // A virtual column made up from two fields
          { key: 'nameage', label: 'First name and age' }
        ],
        items: [
          { name: { first: 'John', last: 'Doe' }, sex: 'Male', age: 42 },
          { name: { first: 'Jane', last: 'Doe' }, sex: 'Female', age: 36 },
          { name: { first: 'Rubin', last: 'Kincade' }, sex: 'Male', age: 73 },
          { name: { first: 'Shirley', last: 'Partridge' }, sex: 'Female', age: 62 }
        ]
      }
    }
  }
</script>

The table here is custom rendered from items array. My question is .. How to get back array data items from the custom rendered table?

The output of above code looks like ????

enter image description here

From this table I want an array of json with new custom rendered data. So my output outputItems for above table should look like ????

outputItems = [
  {'Index': 1, 'Full Name': 'DOE,John', 'Age': 42, 'Sex': 'Male', 'First name and age': 'John is 42 years old'},
  {'Index': 2, 'Full Name': 'DOE,Jane', 'Age': 36, 'Sex': 'Female', 'First name and age': 'Jane is 36 years old'},
  {'Index': 3, 'Full Name': 'KINCADE,Rubin', 'Age': 73, 'Sex': 'Male', 'First name and age': 'Rubin is 73 years old'},
  {'Index': 4, 'Full Name': 'PATRIDGE,Shirley', 'Age': 62, 'Sex': '', 'First name and age': 'Shirley is 62 years old'}
]
1
Aren't those data change when you enter a new value to an input field?Daniyal Lukmanov
Can''t you just use computed? If you have items in your data and you just need to get outputItems it can be done with computed easily.Daniyal Lukmanov
@DaniyalLukmanov items are not updating when input fields in table columns are changedKingz
You should do something like: :slot="field.key" slot-scope="data" and <b-form-input v-model="data.item[field.key]"></b-form-input>Daniyal Lukmanov
data.value (from the scope) is after any formatting has happened and is a copy of the item record value (not a reference to it). To alter the actual item row value, use v-model="data.item.age". You will also need a specific slot for each input in the row... do not use v-slot:cell()="data" fallback slot. use v-slot:cell(age)="data"Troy Morehouse

1 Answers

1
votes

Use:

<template>
  <div>
    <b-table small :fields="fields" :items="items" responsive="sm">
      <!-- A virtual column -->
      <template v-slot:cell(index)="data">
        {{ data.index + 1 }}
      </template>

      <!-- A custom formatted column -->
      <template v-slot:cell(name)="data">
        <b class="text-info">{{ data.value.last.toUpperCase() }}</b>, <b>{{ data.value.first }}</b>
      </template>

      <!-- A virtual composite column -->
      <template v-slot:cell(nameage)="data">
        {{ data.item.name.first }} is {{ data.item.age }} years old
      </template>

      <template v-slot:cell(age)="data">
        <b-form-input v-model="data.item.age" placeholder="Enter age" />
      </template>
    </b-table>
  </div>
</template>

Note: Every time a user types a character into the input, the table will re-render. This is because of the underlying data model for items being updated (Vue reactivity)