0

I am trying to hide and show a table column based on user selection. But it is not working as expected. Here is the link to the codepen file.

https://codepen.io/nigel1995/pen/XWKbqoe?editors=1111

<div id="app">
  <div v-for="item in columnHeaders">
    <label>
      <input type='checkbox' :value='item.value' v-model="selectedType"> {{ item.text }}
    </label>
  </div>

  <table class="selection-div">
    <tr>
      <template v-for="item in columnHeaders">
        <th v-if="showHeader(item)">{{ item.text }}</th>
      </template>
    </tr>
     <tr v-for="desert in deserts">
        <td v-if="!hideCol(desert)">{{ desert.name }}</td>
       <td v-if="!hideCol(desert)">{{ desert.fat }}</td>
    </tr>
  </table>
</div>
new Vue({
  el: '#app',
  data: {
    selectedType: [],
     columnHeaders: [
        { text: 'Name', value: 'name', show: true },
        { text: 'Fat (g)', value: 'fat', show:true },
      ],
      deserts: [
        {
          name: 'Frozen Yogurt',
          fat: 6.0,
        },
        {
           name: 'Golden Yogurt',
           fat: 6.0,
        },
        {
           name: 'Tasty Yogurt',
           fat: 6.0,
        }
      ]
  },
  
  
  methods: {
    hideCol(row){
      const t = Object.keys(row)[0];
      return this.selectedType.includes(t);
    },
    
    showHeader(val){
     return (val.show && !this.selectedType.includes(val.value));       
    } 
  },
});

What I want to do is making the display of table columns dynamic and not check it in each column as table headers will be dynamic in the future. Any direction would be appreciated.

2 Answers 2

1

By using a computed method, we can automatically create the visibleColumns data element. It defaults to all columns when there's no selected column, otherwise it returns only the selected columns.

The vue template then checks if the column is in visibleColumns. It also automatically creates data columns based on visibleColumns.

<div id="app">
  <div v-for="item in columnHeaders">
    <label>
      <input type='checkbox' :value='item.value' v-model="selectedType"> {{ item.text }}
    </label>
  </div>

  <table class="selection-div">
    <tr>
      <th 
        v-for="item in columnHeaders"
        v-if="visibleColumns.includes(item.value)">
        {{ item.text }}
      </th>
    </tr>
     <tr v-for="desert in deserts">
       <td v-for="column in visibleColumns">{{ desert[column] }}</td>
    </tr>
  </table>
</div>
new Vue({
  el: '#app',
  data: {
     selectedType: [],
     columnHeaders: [
        { text: 'Name', value: 'name' },
        { text: 'Fat (g)', value: 'fat' },
      ],
      deserts: [
        {
          name: 'Frozen Yogurt',
          fat: 6.0,
        },
        {
           name: 'Golden Yogurt',
           fat: 6.0,
        },
        {
           name: 'Tasty Yogurt',
           fat: 6.0,
        }
      ]
  },
  
  computed: {
    visibleColumns() {
      if(this.selectedType.length === 0) {
        return this.columnHeaders.map(c => c.value);
      }
      
      return this.selectedType;
    }
  },

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

3 Comments

Hi Patrick. Thank you very much for ur support. Just a query. How can I make the column dynamic and not check it for every field as column headers can be dynamic?
Just re-read your question and made the update. Two changes from your code: computed method to have default/selected columns, and dynamically display header and data columns based on visible columns method.
Thanks mate ur legend!
0

You need to pass the object key you want to hide:

 <tr v-for="desert in deserts">
    <td v-if="!hideCol('name')">{{ desert.name }}</td>
   <td v-if="!hideCol('fat')">{{ desert.fat }}</td>
</tr>

then check if that key should be visible or not:

hideCol(key){
  return this.selectedType.includes(key);
},

Comments

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.