How to add a v-autocomplete with color coded chips to the Vuetify Data Table
I love using the Vuetify v-data-table, as a result I’ve managed to get most of the functionality I need from it to work just how I like it.
By the end of this snippet, you would have learned how to create this customized v-auto-complete inside your v-data-table row column.
In the v-data-table we have column named Category. When that column is clicked, a v-edit-dialog is activated. This shows a v-autocomplete with color coded chips. When a user selects an item from the v-autocomplete, it is shown as a chip. Also each item in the v-autocomplete is shown as a chip. This is possible because of slots.
I will assume that you know how to create a v-data-table. If not, you can kindly check it out from the Vuetify documentation. There is also a section there of how to display chips within a row column matrix. For our exercise, we extend on that example and use item slots to achieve our objective.
Our table has a column named categoryid, what we will do is to redefine how the content on that column should be rendered.
Let’s get into it. Inside out v-data-table definition, we need to add a slot for the categoryid column we want to format. Inside the slot we will add an edit dialog which will be activated once a chip inside the row column matrix is clicked.
<template v-slot:item.categoryid="props"><v-edit-dialog id="categoryiddialog"
:return-value.sync="props.item.categoryid"
@save="tblchallenges_saveitem(props.item)" @cancel="tblchallenges_cancelitem(props.item)"
@open="tblchallenges_openitem(props.item)" @close="tblchallenges_closeitem(props.item)"
large lazy><v-chip elevation="0" :color="getcategoryidcolor(props.item)">
{{ getcategoryidvalue(props.item) }}
</v-chip><template v-slot:input>
<v-autocomplete item-text="name" item-value="id" item-color="color" :items="accategoryiditems"
:label="props.header.text"
:loading="props.item.loading" class="mt-2" outlined
v-model="props.item.categoryid"><template v-slot:selection="data"><v-chip v-bind="data.attrs"
:color="data.item.color"
:input-value="data.selected"
@click="data.select">{{ data.item.name }}
</v-chip>
</template><template v-slot:item="data">
<v-chip v-bind="data.attrs"
:color="data.item.color"
:input-value="data.item" @click="data.select">{{ data.item.name }}</v-chip></template>
</v-autocomplete>
</template>
</v-edit-dialog>
</template>
When ever a value changed, its going to be synced back to the category id, thus the return-value.sync directive.
I will assume that you know about computed properties. To get our color, we have defined some kind of callback function called getcatgoryidcolor. For example, the received color from the object from the array might be 1, 2, 3, 4, we then associate 1 to black, 2 to green, 3 to orange etc. You get my drift. That method then returns the color based on reading some property in the object passed.
The same applies to the text returned for the chip text, we use a compute named getcategoryidvalue, passing the object.
The first thing you see on the v-data-table for that column is the v-chip. This is defined as the first child inside the v-edit-dialog.
<v-chip :color="getcategoryidcolor(props.item)"> {{ getcategoryidvalue(props.item) }}</v-chip>
The second leg, deals with the input content of the v-edit-dialog. When a chip is clicked, an edit dialog appears with a v-auto-complete, an ok and cancel buttons. This v-autocomplete is defined by the input slot of the v-edit-dialog.
<v-autocomplete item-text="name" item-value="id" item-color="color" :items="accategoryiditems":label="props.header.text" :loading="props.item.loading" class="mt-2" outlined v-model="props.item.categoryid">
The label of the v-auto-complete is derived from the column heading. We have added a loading property with binding as we might need to change the status depending on the open, close, save, or cancel events of the v-edit-dialog, for that row and column.
When an item is selected on the v-auto-complete, we want it to show as a colored v-chip, so we bind the chip properties back to its parent item.
<template v-slot:selection="data"><v-chip v-bind="data.attrs" :color="data.item.color" :input-value="data.selected" @click="data.select">{{ data.item.name }}</v-chip></template>
Also each item in the v-autocomplete should be displayed as a color coded v-chip.
<template v-slot:item="data"><v-chip v-bind="data.attrs" :color="data.item.color" :input-value="data.item" @click="data.select">{{ data.item.name }}</v-chip></template>
Here is the complete HTML snippet.
https://github.com/Mashiane/My-Vuetify-Code-Snippets/blob/main/v-autocomplete-02.txt
You can find more information about the Vuetify 2 v-autocomplete component here.
You can follow me on Twitter @mashymbanga, LinkedIn (https://www.linkedin.com/in/anele-mashy-mbanga-4b639376/), on Github (https://github.com/Mashiane)
Happy Vuetify Coding.