yoon_ie
yoon_ie

Reputation: 39

Vuetify column cannot be searched or sorted

I have a Vuetify data table, and I have a feature that toggles whether editing is turned on or off.

For one of my columns (Roles), it will toggle between showing just text (editing disabled) or a selection dropdown (editing enabled). The toggle is set using a boolean, and I toggle the components' visibility using a v-if and v-else attribute.

Editing disabled Editing off

Editing enabled (user can then select the new value in each dropdown) Editing on

However, this seems to have a conflict with whether it can be sorted or searched. The other columns are unaffected and can be searched/sorted normally. Please help me to see if there are any errors, thank you.

Table

<v-data-table :headers="headers" :items="users" :items-per-page="10" :search="search">
     <template v-slot:item.role="{ item }">
       <v-select
         :items="roles"
         item-text="roleName"
         item-value="roleId"
         v-model="item"
         v-if="!editIsDisabled"
       ></v-select>
       <div v-else v-for="role in roles" :key="role.roleId">
         <span v-if="role.roleId === item.roleId">{{ role.roleName }}</span>
       </div>
     </template>
...
</v-data-table>

Script tag

export default {
  data() {
    return {
      editIsDisabled: true,
      search: "",
      roles: [
        {
          roleId: 1,
          roleName: "Procurement"
        },
        {
          roleId: 2,
          roleName: "Fulfilment"
        },
        {
          roleId: 3,
          roleName: "Human Resources"
        }
      ],
      headers: [
        {
          text: "User ID",
          value: "userId"
        },
        {
          text: "User",
          value: "userName"
        },
        {
          text: "Role",
          value: "role",
          sortable: false
        }
      ],
      users: [
        {
          userId: 122,
          userName: "John Lim",
          roleId: 1
        },
        {
          userId: 125,
          userName: "Amy Lee",
          roleId: 1
        },
        {
          userId: 102,
          userName: "Ben Tan",
          roleId: 2
        },
        {
          userId: 156,
          userName: "Cindy Ng",
          roleId: 2
        },
        {
          userId: 89,
          userName: "Chris Lee",
          roleId: 3
        }
      ]
    };
  }
};

Upvotes: 1

Views: 372

Answers (1)

chans
chans

Reputation: 5260

The search items should be a part of users object, In you case, the roles are mapped based on roleId in users array and roles array

I've refactored the above code to include role as a property on created hook , so that roles will be a part of users array and it is eligible for search

Working codepen here: https://codepen.io/chansv/pen/zYYPrqL?editors=1010

<div id="app">
  <v-app id="inspire">
    <v-card>
      <v-card-title>
        Users
        <v-spacer></v-spacer>
        <v-text-field
          v-model="search"
          append-icon="search"
          label="Search"
          single-line
          hide-details
        ></v-text-field>
        <v-btn color="primary" @click="editIsDisabled = !editIsDisabled"> Edit</v-btn>
      </v-card-title>

    <v-data-table :headers="headers" :items="users" :items-per-page="10" :search="search">
     <template v-slot:item.role="{ item }">
       <v-select
         :items="roles"
         item-text="roleName"
         item-value="roleId"
         v-model="item"
         v-if="!editIsDisabled"
       ></v-select>
       <span v-else>{{item.role}}</span>
     </template>
</v-data-table>
      </v-card>
  </v-app>
</div>

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      editIsDisabled: true,
      search: "",
      roles: [
        {
          roleId: 1,
          roleName: "Procurement"
        },
        {
          roleId: 2,
          roleName: "Fulfilment"
        },
        {
          roleId: 3,
          roleName: "Human Resources"
        }
      ],
      headers: [
        {
          text: "User ID",
          value: "userId"
        },
        {
          text: "User",
          value: "userName"
        },
        {
          text: "Role",
          value: "role",
          sortable: false,
        }
      ],
      users: [
        {
          userId: 122,
          userName: "John Lim",
          roleId: 1
        },
        {
          userId: 125,
          userName: "Amy Lee",
          roleId: 1
        },
        {
          userId: 102,
          userName: "Ben Tan",
          roleId: 2
        },
        {
          userId: 156,
          userName: "Cindy Ng",
          roleId: 2
        },
        {
          userId: 89,
          userName: "Chris Lee",
          roleId: 3
        }
      ]
    }
  },
  created() {
    var rolesObj = {};
    this.roles.map(x => rolesObj[x.roleId] = x.roleName);
    this.users.forEach(x => {
      x.role = rolesObj[x.roleId];
    })
  },
})

Upvotes: 1

Related Questions