3

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 class="flex" @click.prevent="sortByColumn(th.name)">
          <div class="sort-header-content">{{ 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>

2 Answers 2

2

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: {
    sortItems(column, col) {
      this.items = this.items.sort((a, b) => {
        return this.sortcol[column] === 'asc' ? a[col] > b[col] : a[col] < b[col] 
      })
    },
    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'
      }
      this.sortItems(column, Object.keys(this.sortcol))
    },
  },
  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 class="flex" @click.prevent="sortByColumn(th.name)">
          <div class="sort-header-content">{{ 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>

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

2 Comments

thank you for the answer. will it be this way? let sortedEntries = this.getCurrentEntries() const sortedColumn = column === Object.keys(this.sortcol)[0] if (sortedColumn) { this.sortcol[column] = this.sortcol[column] === 'asc' ? 'desc' : 'asc' sortedEntries = $array.sorted(this.getCurrentEntries(), column, 'desc') } else { sortedEntries = $array.sorted(this.getCurrentEntries(), column, 'asc') this.sortcol = {} this.sortcol[column] = 'asc' }
$array.sorted Are if and else in the right place, I can't understand it right now
2

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 class="flex" @click.prevent="sortByColumn(th.name)">
            <div class="sort-header-content">{{ 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>

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.