Home > Blockchain >  Filter table rows with vuejs
Filter table rows with vuejs

Time:06-29

Hi i want to filter and sor a table in vue js. I do this but when i text in the textbox the letter that i want to search the table is empty. I want to filter the rows and display the ones that matches whatever is in this input. I hope I am making sense. I do not know how to proceed from here. Cookies and a big thank you to anyone who helps!

<script>
import axios from 'axios'
export default {
  name: 'Utenti',

  data() {
    return {
      utenti: [],
      modalTitle: '',
      UtenteTessera: 0,
      UtenteNome: '',
      UtenteCognome: '',
      UtenteEmail: '',
      UtenteTelefono: '',
      UtenteNomeFilter: '',
      UtenteTesseraFilter: '',
      utentiWithoutFilter: [],
    }
  },
  methods: {
    refreshData() {
      axios.post('https://localhost:7285/Utenti/GetDati').then((response) => {
        this.utenti = response.data.prova
        this.utentiWithoutFilter = response.data.prova
      })
    },
    FilterFn() {
      const UtenteTesseraFilter = this.UtenteTesseraFilter
      const UtenteNomeFilter = this.UtenteNomeFilter

      this.utenti = this.utentiWithoutFilter.filter(function (el) {
        return (
          el.UtenteTessera.toString()
            .toLowerCase()
            .includes(UtenteTesseraFilter.toString().trim().toLowerCase()) &&
          el.UtenteNome.toString()
            .toLowerCase()
            .includes(UtenteNomeFilter.toString().trim().toLowerCase())
        )
      })
    },
    sortResult(prop, asc) {
      this.utenti = this.utentiWithoutFilter.sort(function (a, b) {
        if (asc) {
          return a[prop] > b[prop] ? 1 : a[prop] < b[prop] ? -1 : 0
        } else {
          return b[prop] > a[prop] ? 1 : b[prop] < a[prop] ? -1 : 0
        }
      })
    },
  },
}
</script>
<template>
  <div>
    <table >
      <thead>
        <tr>
          <th>
            <div >
              <input
                v-model="UtenteTesseraFilter"
                
                placeholder="Filter"
                @keyup="FilterFn()"
              />

              <button
                type="button"
                
                @click="sortResult('UtenteTessera', true)"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="16"
                  height="16"
                  fill="currentColor"
                  
                  viewBox="0 0 16 16"
                >
                  <path
                    d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5a.5.5 0 0 1 1 0z"
                  />
                </svg>
              </button>

              <button
                type="button"
                
                @click="sortResult('UtenteTessera', false)"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="16"
                  height="16"
                  fill="currentColor"
                  
                  viewBox="0 0 16 16"
                >
                  <path
                    d="M2 16a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2zm6.5-4.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 1 0z"
                  />
                </svg>
              </button>
            </div>
            Tessera
          </th>
          <th>
            <div >
              <input
                v-model="UtenteNomeFilter"
                
                placeholder="Filter"
                @keyup="FilterFn()"
              />

              <button
                type="button"
                
                @click="sortResult('UtenteNome', true)"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="16"
                  height="16"
                  fill="currentColor"
                  
                  viewBox="0 0 16 16"
                >
                  <path
                    d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5a.5.5 0 0 1 1 0z"
                  />
                </svg>
              </button>

              <button
                type="button"
                
                @click="sortResult('UtenteNome', false)"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="16"
                  height="16"
                  fill="currentColor"
                  
                  viewBox="0 0 16 16"
                >
                  <path
                    d="M2 16a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2zm6.5-4.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 1 0z"
                  />
                </svg>
              </button>
            </div>
            UtenteNome
          </th>
          <th>Options</th>
        </tr>
      </thead>
    </table>
    <table  style="z-index: 1">
      <thead>
        <tr>
          <th>Tessera</th>
          <th>Nome</th>
          <th>Cognome</th>
          <th>Email</th>
          <th>Telefono</th>
        </tr>
      </thead>
      <tbody>
        <!--<tr v-for="info in info" :key="index">-->
        <tr v-for="utente in utenti" :key="title">
          <td>{{ utente.tessera }}</td>
          <td>{{ utente.nome }}</td>
          <td>{{ utente.cognome }}</td>
          <td>{{ utente.email }}</td>
          <td>{{ utente.telefono }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

CodePudding user response:

You treat "filter" and "sort" as two different operations but those are two operations that need to be applied at the same time (so that sorting does not overwrite filtering result and vice versa). Also you are not using Vue reactivity at all. This is perfect use case for computed

This computed has 3 inputs:

  1. unfiltered and no sorted original array
  2. active filter
  3. active sort
<script>
import axios from 'axios'
export default {
  name: 'Utenti',

  data() {
    return {
      utenti: [],
      modalTitle: '',
      UtenteTessera: 0,
      UtenteNome: '',
      UtenteCognome: '',
      UtenteEmail: '',
      UtenteTelefono: '',
      UtenteNomeFilter: '',
      UtenteTesseraFilter: '',
      // NEW
      sort: {
        prop: undefined,
        asc: true
      }
    }
  },
  computed: {
    utentiToDisplay() {
      // filter first - this creates new array
      const result = this.utenti.filter(el =>       
          el.UtenteTessera.toString()
            .toLowerCase()
            .includes(
              this.UtenteTesseraFilter.toString().trim().toLowerCase()
            ) 
          &&
          el.UtenteNome.toString()
            .toLowerCase()
            .includes(
              this.UtenteNomeFilter.toString().trim().toLowerCase()
          )
      )
      // now sort the results in-place if needed
      if(this.sort.prop) {
        result.sort((a, b) => {
          if (this.sort.asc) {
            return a[prop] > b[prop] ? 1 : a[prop] < b[prop] ? -1 : 0
          } else {
            return b[prop] > a[prop] ? 1 : b[prop] < a[prop] ? -1 : 0
          }
        })
      }
      
      return result      
    }
  },
  methods: {
    refreshData() {
      axios.post('https://localhost:7285/Utenti/GetDati').then((response) => { this.utenti = response.data.prova })
    },
    setSort(prop, asc) {
      this.sort.prop = prop
      this.sort.asc = asc
    }
  },
}
</script>
<div>
    <table >
      <thead>
        <tr>
          <th>
            <div >
              <input
                v-model="UtenteTesseraFilter"
                
                placeholder="Filter"
              />

              <button
                type="button"
                
                @click="setSort('UtenteTessera', true)"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="16"
                  height="16"
                  fill="currentColor"
                  
                  viewBox="0 0 16 16"
                >
                  <path
                    d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5a.5.5 0 0 1 1 0z"
                  />
                </svg>
              </button>

              <button
                type="button"
                
                @click="setSort('UtenteTessera', false)"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="16"
                  height="16"
                  fill="currentColor"
                  
                  viewBox="0 0 16 16"
                >
                  <path
                    d="M2 16a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2zm6.5-4.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 1 0z"
                  />
                </svg>
              </button>
            </div>
            Tessera
          </th>
          <th>
            <div >
              <input
                v-model="UtenteNomeFilter"
                
                placeholder="Filter"
              />

              <button
                type="button"
                
                @click="setSort('UtenteNome', true)"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="16"
                  height="16"
                  fill="currentColor"
                  
                  viewBox="0 0 16 16"
                >
                  <path
                    d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5a.5.5 0 0 1 1 0z"
                  />
                </svg>
              </button>

              <button
                type="button"
                
                @click="setSort('UtenteNome', false)"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="16"
                  height="16"
                  fill="currentColor"
                  
                  viewBox="0 0 16 16"
                >
                  <path
                    d="M2 16a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2zm6.5-4.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 1 0z"
                  />
                </svg>
              </button>
            </div>
            UtenteNome
          </th>
          <th>Options</th>
        </tr>
      </thead>
    </table>
    <table  style="z-index: 1">
      <thead>
        <tr>
          <th>Tessera</th>
          <th>Nome</th>
          <th>Cognome</th>
          <th>Email</th>
          <th>Telefono</th>
        </tr>
      </thead>
      <tbody>
        <!--<tr v-for="info in info" :key="index">-->
        <tr v-for="utente in utentiToDisplay" :key="title">
          <td>{{ utente.tessera }}</td>
          <td>{{ utente.nome }}</td>
          <td>{{ utente.cognome }}</td>
          <td>{{ utente.email }}</td>
          <td>{{ utente.telefono }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

CodePudding user response:

I've solved it.

<script>
        import axios from "axios"
        export default {
            name: "Utenti",
    
            data() {
                return {
                    utenti: [],
                    modalTitle: "",
                    UtenteTessera: 0,
                    UtenteNome: "",
                    UtenteCognome: "",
                    UtenteEmail: "",
                    UtenteTelefono: "",               
                    UtenteNomeFilter: "",
                    UtenteTesseraFilter: "",
                    sortKey: 'nome',
                    reverse:false
                    }
                },
        
            computed: {
                utentiToDisplay() {
                    return this.utenti.filter(this.filterByName)
                        .filter(this.filterByTessera)
                        .sort(this.orderBy);
                }
            },
        methods: {
            filterByName: function (utente) {
                if (this.UtenteNomeFilter.length === 0) {
                    return true;
                }
                return (utente.nome.toLowerCase().indexOf(this.UtenteNomeFilter.toLowerCase()) > -1);
            },
            filterByTessera: function (utente) {
                if (this.UtenteTesseraFilter.length === 0) {
                    return true;
                }
                return (utente.tessera.toLowerCase().indexOf(this.UtenteTesseraFilter.toLowerCase()) > -1);
            },
            orderBy: function (utenteA, utenteB) {
                let condition = (utenteA[this.sortKey] > utenteB[this.sortKey]);
                if (this.reverse) {
                    return !condition;
                }
                else {
                    return condition;
                }
            }
    }

And the template

<div>
    <table >
      <thead>
        <tr>
          <th>
            <div >
              <input
                v-model="UtenteTesseraFilter"
                
                placeholder="Filter"
              />

              <button
                type="button"
                
                @click="setSort('UtenteTessera', true)"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="16"
                  height="16"
                  fill="currentColor"
                  
                  viewBox="0 0 16 16"
                >
                  <path
                    d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5a.5.5 0 0 1 1 0z"
                  />
                </svg>
              </button>

              <button
                type="button"
                
                @click="setSort('UtenteTessera', false)"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="16"
                  height="16"
                  fill="currentColor"
                  
                  viewBox="0 0 16 16"
                >
                  <path
                    d="M2 16a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2zm6.5-4.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 1 0z"
                  />
                </svg>
              </button>
            </div>
            Tessera
          </th>
          <th>
            <div >
              <input
                v-model="UtenteNomeFilter"
                
                placeholder="Filter"
              />

              <button
                type="button"
                
                @click="setSort('UtenteNome', true)"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="16"
                  height="16"
                  fill="currentColor"
                  
                  viewBox="0 0 16 16"
                >
                  <path
                    d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5a.5.5 0 0 1 1 0z"
                  />
                </svg>
              </button>

              <button
                type="button"
                
                @click="setSort('UtenteNome', false)"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="16"
                  height="16"
                  fill="currentColor"
                  
                  viewBox="0 0 16 16"
                >
                  <path
                    d="M2 16a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2zm6.5-4.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 1 0z"
                  />
                </svg>
              </button>
            </div>
            UtenteNome
          </th>
          <th>Options</th>
        </tr>
      </thead>
    </table>
    <table  style="z-index: 1">
      <thead>
        <tr>
          <th>Tessera</th>
          <th>Nome</th>
          <th>Cognome</th>
          <th>Email</th>
          <th>Telefono</th>
        </tr>
      </thead>
      <tbody>
        <!--<tr v-for="info in info" :key="index">-->
        <tr v-for="utente in utentiToDisplay" :key="title">
          <td>{{ utente.tessera }}</td>
          <td>{{ utente.nome }}</td>
          <td>{{ utente.cognome }}</td>
          <td>{{ utente.email }}</td>
          <td>{{ utente.telefono }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>
  • Related