简体   繁体   中英

Filters for table columns with Vue

I've successfully built a table with Vue which has dropdowns as the header for each column. The values for each dropdown are coming from different axios calls as arrays, and they are filled properly.

THe problem I have is that the second I filter any column it hides the whole table and there's no way to reset it to get it back. SO it's not filtering at all properly and it also doesn't go back to a 'show all' option.

What am I doing wrong here:

<table style="width:100%; text-align:center;">
      <thead>
          <tr>    
              <th>
                  <select v-model="filters.resource">
                    <option v-for="resource in resources" :value="resource">{{ resource.name }}</option>
                  </select>
              </th>
              <th>
                  <select v-model="filters.location">
                    <option v-for="location in locations" :value="location">{{ location.name }}</option>
                  </select>
              </th>
              <th></th>
              <th>
                  <select v-model="filters.status">
                    <option v-for="status in statuses" :value="status">{{ status }}</option>
                  </select>
              </th>
              <th></th>
          </tr>
      </thead>
      <tbody  v-for="event in filtered">
          <tr>
              <td>{{ event.resource }}</td>
              <td>{{ event.location }}</td>
              <td>{{ event.status }}</td>
          </tr>
      </tbody>
  </table>


  <script>
  export default {
      data () {
          return {
              events: [],
              locations: [],
              resources: [],
              filters: {
                title: null,
                resource: null,
                location: null,
                status: null,
              },
          }
      },
      created() {
          this.fetchTasks();
          this.fetchLocations();
          this.fetchresources();
      },
      computed: {
        filtered() {
          return this.events
            .filter(event => !this.filters.resource || event.resource === this.filters.resource)
            .filter(event => !this.filters.location || event.location === this.filters.location)
        },

        resources() {
          return this.resources
            .map(resource => resource.name)
            .filter((resource, index, self) => self.indexOf(resource) === index);
        },

        locations() {
          return this.locations
            .map(location => location.name)
            .filter((location, index, self) => self.indexOf(location) === index);
        },
      },
      methods: {
        fetchItems() {
          axios.get('/items')
          .then(response => {
            this.events = response.data
          })
      },
      fetchLocations() {
          axios.get('/locations')
          .then(response => {
            this.locations = response.data
          })
      },
      fetchresources() {
          axios.get('/resources')
          .then(response => {
            this.resources = response.data
          })
      }
    },
  }
  </script>

First thing, don't name computed properties the same as data properties. Vue will pick up data properties instead of computed ones with the same name.

The values of this.filters.location and this.filters.resource are objects since you defined value of <option /> as:

<option v-for="resource in resources" :value="resource">{{ resource.name }}</option>

So if user choose resource option "Resource A", the value of this.filters.resource would be { name: "Resource A" } or something similar. And in javascript, object comparison cannot be done simply by == operator. That means the value of

!this.filters.resource || event.resource === this.filters.resource

will always be false.

Consider comparing only the name instead, ie this.filters.resource.name .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM