Home > Back-end >  vue click sort by column clear value
vue click sort by column clear value

Time:11-13

I am working on a small project. What i want to do is when sorting happens @click event, sortcol column is given asc, desc, but. The thing I want is this, I want to clear the value of other columns except the clicked column.

I couldn't figure out how to get this done.

<template>
  <table>
    <thead>
    <tr>
      <th v-for="th in tableHeader" :key="th">
        <div  @click.prevent="sortByColumn(th.name)">
          <div >{{ th.text }}</div>
          <div v-if="sortcol[th.name]==='asc'">ArrowDownIcon</div>
          <div v-else-if="sortcol[th.name]==='desc'">ArrowUpIcon</div>
        </div>
      </th>
    </tr>
    </thead>
  </table>
</template>

<script>
export default {
  name: "Table",
  data() {
    return {
      columns: [
        {name: 'id', text: 'ID'},
        {name: 'name', text: 'Name'},
        {name: 'position', text: 'Position'},
        {name: 'office', text: 'Office'},
        {name: 'extension', text: 'Extension'},
        {name: 'startdate', text: 'Start Date'},
        {name: 'salary', text: 'Salary'},
      ],
      sortcol: {
        name: '',
        position: '',
        office: '',
        extension: '',
        startdate: '',
        salary: '',
      },
    }
  },
  methods: {
    sortByColumn(column) {
      let sortedColumn = this.sortcol[column]
      if (sortedColumn === '') {
        this.sortcol[column] = 'asc'
      } else if (sortedColumn === 'asc') {
        this.sortcol[column] = 'desc'
      } else if (sortedColumn === 'desc') {
        this.sortcol[column] = ''
      }
    },
  },
  computed: {
    tableHeader() {
      return this.columns
    },
  }
}
</script>

CodePudding user response:

First, create an array of available keys from sortcol. Then remove the th.name passed to the function. You can then remove the values of the sortcol after doing a for..of loop.

new Vue({
  el: "#app",
  data() {
    return {
      columns: [
        {name: 'id', text: 'ID'},
        {name: 'name', text: 'Name'},
        {name: 'position', text: 'Position'},
        {name: 'office', text: 'Office'},
        {name: 'extension', text: 'Extension'},
        {name: 'startdate', text: 'Start Date'},
        {name: 'salary', text: 'Salary'},
      ],
      sortcol: {
        name: '',
        position: '',
        office: '',
        extension: '',
        startdate: '',
        salary: '',
      },
    }
  },
  methods: {
    sortByColumn(column) {
      let sortedColumn = this.sortcol[column]
      // Solution
      const colArr = Object.keys(this.sortcol)
      const extra = colArr.filter(e => e !== column)
      for (i of extra) {
        this.sortcol[i] = ''
      }
      
      if (sortedColumn === '') {
        this.sortcol[column] = 'asc'
      } else if (sortedColumn === 'asc') {
        this.sortcol[column] = 'desc'
      } else if (sortedColumn === 'desc') {
        this.sortcol[column] = ''
      }
    },
  },
  computed: {
    tableHeader() {
      return this.columns
    },
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <table>
    <thead>
      <tr>
        <th v-for="th in columns" :key="th.name">
          <div  @click.prevent="sortByColumn(th.name)">
            <div >{{ th.text }}</div>
            <div v-if="sortcol[th.name]==='asc'">ArrowDownIcon</div>
            <div v-else-if="sortcol[th.name]==='desc'">ArrowUpIcon</div>
          </div>
        </th>
      </tr>
    </thead>
  </table>
</div>

CodePudding user response:

You can empty your sortcol object if property is there:

const app = Vue.createApp({
  data() {
    return {
      columns: [
        {name: 'id', text: 'ID'},
        {name: 'name', text: 'Name'},
        {name: 'position', text: 'Position'},
        {name: 'office', text: 'Office'},
        {name: 'extension', text: 'Extension'},
        {name: 'startdate', text: 'Start Date'},
        {name: 'salary', text: 'Salary'},
      ],
      sortcol: {},
      items: [{id: 1, name: 'aa', position: 2, office: 'AA', extension: 'tt', startdate: '12', salary: 55}, {id: 3, name: 'cc', position: 1, office: 'CC', extension: 'xx', startdate: '82', salary: 75}, {id: 2, name: 'bb', position: 8, office: 'BB', extension: 'zz', startdate: '15', salary: 35}]
    }
  },
  methods: {
    sortByColumn(column) {
      const selected = column === Object.keys(this.sortcol)[0]
      if(selected) {
        this.sortcol[column] = this.sortcol[column] === 'asc' ? 'desc' : 'asc'
      } else {
        this.sortcol = {}
        this.sortcol[column] = 'asc'
      }
      const way = this.sortcol[column]
      const col = Object.keys(this.sortcol)
      this.items = this.items.sort((a, b) => {
        if(this.sortcol[column] === 'asc') {
          return a[col] > b[col] 
        } else {
          return a[col] < b[col]
        }
      })
    },
  },
  computed: {
    tableHeader() {
      return this.columns
    },
  }
})
app.mount('#demo')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
  <table>
    <thead>
    <tr>
      <th v-for="th in tableHeader" :key="th">
        <div  @click.prevent="sortByColumn(th.name)">
          <div >{{ th.text }}</div>
          <div v-if="sortcol[th.name]==='asc'">ArrowDownIcon</div>
          <div v-else-if="sortcol[th.name]==='desc'">ArrowUpIcon</div>
        </div>
      </th>
    </tr>
    </thead>
    <tbody>
      <tr v-for="item in items">
        <td v-for="itm in item">
          {{ itm }}
        </td>
      </tr>
    </tbody>
  </table>
</div>

  • Related