How do I achieve v-autocomplete to show both the value and text when selecting?
Here is my code-
<v-autocomplete
v-model="request"
v-if="products.data"
:items="products.data"
outline
chips
label="Select item"
item-text="name"
item-value="id"
>
products: [
{
text: "Apple",
value: 209
},
{
text: "Banana",
value: 229
}
]
Currently, I am able to display only the text but I want two display both (text and value in the options) before selecting.
Using slots you can do this-
<v-autocomplete
:items="products"
label="Select"
item-text="text"
item-value="value"
>
<!-- If you want to modify the selected data -->
<template v-slot:selection="data">
{{ data.item.text }} {{ data.item.value }}
</template>
<!-- If you want to modify the list options -->
<template v-slot:item="data">
{{ data.item.text }} {{ data.item.value }}
</template>
</v-autocomplete>
Related
how can I add new chips with the same value in the Combobox that I am using? For example every time I add 200 and I want to add another 200 it is automatically deleted.
I want to save the user inputs in an array like [100, 200, 200, 300]
<v-combobox
v-if="points.number_compartments > 1"
v-model="compartments_detail"
chips
label="CAPACIDAD DE COMPARTIMIENTOS"
clearable
deletable-chips
append-icon=""
multiple
outlined
dense
class="mx-3"
>
<template v-slot:selection="{ attrs, item, selected, index }">
<v-chip
small
v-bind="attrs"
:input-value="selected"
close
#click:close="removeChips(index)"
color="primary"
>
<span>{{index + 1}} </span> - {{ item }} <span class="mx-1"> (gls) </span>
</v-chip>
</template>
</v-combobox>
If you would like to use duplicated items, it's better to use an array of objects data structure and give every duplicate item a unique value so the items can be identified by the item-value prop and allow selecting duplicates.
The component code would be like this-
<v-combobox
v-if="points.number_compartments > 1"
:items="items"
item-text="label"
item-value="id"
v-model="compartments_detail"
chips
label="CAPACIDAD DE COMPARTIMIENTOS"
clearable
deletable-chips
append-icon=""
multiple
outlined
dense
class="mx-3"
>
<-- YOUR CODE ->
</v-combobox>
And the structure of the items would be-
items: [
{
label: 100,
id: 1
},
{
label: 100,
id: 2
},
{
label: 200,
id: 3
},
{
label: 200,
id: 4
}
]
I have a role for a specific user with these numbers.
Instead of number 1 it will display the word "Super Admin"
Instead of number 2 it will display the word "Admin"
Instead of number 2 it will display the word "User"
and so on.
I am using q-table
<q-table
flat
bordered
title="USERS"
:data="allUsers"
:columns="columns"
:filter="filter"
:pagination.sync="initialPagination"
row-key="id"
>
<template v-slot:top-right>
<q-input
outlined
dense
debounce="300"
placeholder="Search"
v-model="filter"
>
<template v-slot:append>
<q-icon name="search" />
</template>
</q-input>
<div class="q-pa-sm q-gutter-sm"></div>
<q-btn
outline
color="white"
text-color="black"
#click="openCreateUserModal"
label="Create Users"
/>
</template>
<template v-slot:body="props">
<q-tr :props="props">
<q-td
v-for="col in props.cols.filter(col => col.name !== 'actions')"
:key="col.name"
>
{{ col.value }}
</q-td>
<td key="actions">
<q-btn dense flat color="primary" field="edit" icon="edit" />
<q-btn
dense
flat
color="negative"
field="delete"
icon="delete"
/>
</td>
</q-tr>
</template>
</q-table>
The role in my column
{
name: "role",
align: "center",
label: "Role",
field: "role",
sortable: true
},
Is this possible what I'm trying to achieve?
Column definition can contain format field to define a custom formatting function. The function is called with the 2 arguments - the value retrieved from field and row (which can be useful to create display values by combining data from multiple fields)
const roleIdToRoleName = {
1: "Super Admin",
2: "Admin",
3: "User"
}
...
{
name: "role",
align: "center",
label: "Role",
field: "role",
sortable: true,
format: (val, row) => roleIdToRoleName[val]
},
This works out of the box if you do not override default rendering by providing body slot. This is problematic because you will loose a lot of provided functionality:
field can be string but it can also be a function (useful to drill down to some nested object data)
format is of course not applied
Default "get cell value" functionality of q-table looks like something like this:
const getCellValue(row, col) {
const val = typeof col.field === 'function' ? col.field(row) : row[col.field]
return col.format ? col.format(val, row) : val
}
You can of course replicate it in your code and use it:
<q-td :props="props" // !! you are missing props here
v-for="col in props.cols.filter(col => col.name !== 'actions')"
:key="col.name"
>
{{ getCellValue(props.row, col) }}
</q-td>
but since it seems only reason you are overriding body slot is because you need custom rendering of the actions column, why not just use body-cell-actions slot instead? This will override only rendering of actions column and other columns will use default q-table rendering
Just add actions column in columns definition:
{ name: 'actions', label: 'Action', sortable: false}
<template v-slot:body-cell-actions="props">
<q-td :props="props">
<q-btn dense flat color="primary" field="edit" icon="edit" />
<q-btn dense flat color="negative" field="delete" icon="delete" />
</q-td>
</template>
Hello and thank you for reading my question! I am working with Vue.js, Vuetify and v-data-table and I am working on making my v-slot work with two different strings as the name of the header.
<template>
<v-container fluid>
<v-data-table
:options="data"
:headers="headers"
:items="data
:server-items-length="40"
:loading="loading"
:multi-sort="true"
#update:options="updateThePage"
>
<template v-slot:[`header.overalls`]="{ header }" class="flight-date-header">
<overallDatePicker
:options="data"
/>
{{ header.name }}
</template>
<template v-slot:[`item.name`]="{ item }">
<p class="company-name">
{{ item.companyName }}
</p>
</template>
<template v-slot:[`item.price`]="{ item }">
<p> {{ item.price }} </p>
</template>
<template v-slot:[`item.flightDate`]="{ item }">
<p class="style">
{{ item.startDate }}
</p>
</template>
</v-data-table>
</v-container>
</template>
and I store my headers like below
headers: [
{ text: 'Campaign Name', value: 'overalls' },
],
Ideally I would like the name of this slot
<template v-slot:[`header.overalls`]="{ header }" class="flight-date-header">
<overallDatePicker
:options="data"
/>
</template>
To work with two different data options. right now the name of the header is overalls but I want the name of the header so ['header.overalls'] to be like ['header.('overalls' || 'shoes')] ,
The reason I am doing this is right now when I click on the header the options.sortBy property of the table gets set to 'overalls', but I want the icon on the column to show up if the options.sortBy property of the table is "overalls" and also show up if it is "shoes"
Please help and thank you so much!
To reuse the slot content for multiple headers/columns, use Vue's dynamic slots names feature + v-for
data() {
return {
specialHeaders: ['overalls', 'shoes'],
}
}
<template v-for="column in specialHeaders" v-slot:[`header.${column}`]="{ header }">
Special:{{header.text}}
</template>
I'm using buefy to create a table with input filters in columns.
This is what it looks like:
<b-table
:data="cars"
:sticky-header="true"
:selected.sync="selected"
>
<template slot-scope="props">
<template v-for="column in columns">
<b-table-column :key="column.id" v-bind="column">
<template
v-if="column.searchable"
slot="searchable"
slot-scope="props"
>
<b-input
v-model="props.filters[props.column.field]"
placeholder="Search..."
icon="magnify"
size="is-small"
/>
</template>
{{ props.row[column.field] }}
</b-table-column>
</template>
</template>
</b-table>
...
...
data () {
return {
selected: null,
columns: [
{
field: 'constructor',
label: 'Constructor',
searchable: true
},
....
]
}
I would like to be able to clear the searched fields.
Any suggestions to achieve this please?
Your b-input is bound to props.filters[props.column.field], so it means that you should be able to add an icon to reset this value:
<b-input
v-model="props.filters[props.column.field]"
...
icon-right="close-circle"
icon-right-clickable
#icon-right-click="props.filters[props.column.field] = ''"
>
Please let me know if that works.
Is there a way to concatenate two fields together in a v-select's item-text field?
I have it working for the drop down list values, but the visible entry doesn't show the two fields.
Problem is here: item-text="'${data.item.name}, ${data.item.group}'"
Code:
`<v-select label="Select" v-bind:items="people" v-model="e11"
item-text="'${data.item.name}, ${data.item.group}'"
item-value="name" max-height="auto" autocomplete >
<template slot="item" slot-scope="data">
<v-list-tile-content>
<v-list-tile-title
v-html="`${data.item.name}, ${data.item.group}`">
</v-list-tile-title>
<v-list-tile-sub-title
v-html="data.item.group">
</v-list-tile-sub-title>
</v-list-tile-content>
</template>
</v-select>`
Pen Example: https://codepen.io/anon/pen/dJveWM?editors=1010
Thank you
You need to define a template not only for the slot item but also for the slot selection when using <v-select>:
<template slot="selection" slot-scope="data">
<v-chip
close
#input="data.parent.selectItem(data.item)"
:selected="data.selected"
class="chip--select-multi"
:key="JSON.stringify(data.item)"
>
<v-avatar>
<img :src="data.item.avatar">
</v-avatar>
{{ data.item.name }}
</v-chip>
</template>
See
https://vuetifyjs.com/components/selects#6-scoped-slots
for reference.
This can also be a much simpler solution like the one you're trying to achieve:
<template slot="selection" slot-scope="data">
{{ data.item.name }}, {{ data.item.group }}
</template>
Also see it in action:
https://codepen.io/anon/pen/PEpaMM?editors=1011
For David Folkner: you can add the :filter="customFilter" property to the autocomplete component and then add in the methods block the customFilter function that achieves the custom search.
For example, if your items list is composed by n item objects with id, function and description properties, you should do this for searching through both function and description properties:
Autocomplete component:
<v-autocomplete v-model="itemSelected" :items="items" required box chips label="Select an Item" item-value="id" item-text="description" :filter="customFilter">
<template slot="selection" slot-scope="data">
<v-chip :selected="data.selected" class="chip--select">
{{data.item.function}} - {{ data.item.description }}
</v-chip>
</template>
<template slot="item" slot-scope="data">
<v-list-tile-content>
<v-list-tile-title v-html="data.item.function +' - '+ data.item.description"></v-list-tile-title>
</v-list-tile-content>
</template>
</v-autocomplete>
methods:
methods: {
customFilter (item, queryText, itemText) {
const textOne = item.function.toLowerCase()
const textTwo = item.description.toLowerCase()
const searchText = queryText.toLowerCase()
return textOne.indexOf(searchText) > -1 || textTwo.indexOf(searchText) > -1
}
}
<v-select
:items="unitTypes"
item-text="value"
item-value="id"
v-model="formData.unit_type"
prepend-icon="mdi-ammunition"
label="Unit Types"
required
:error-messages="errors"
>
<template slot="selection" slot-scope="data">
{{ data.item.value }} {{ data.item.type }}
</template>
<template slot="item" slot-scope="data">
{{ data.item.value }} {{ data.item.type }}
</template>
</v-select>
We are using
"vue-cli-plugin-vuetify": "2.0.5",
"vue-eslint-parser": "^7.10.0",
"vue-template-compiler": "^2.6.11",
And the following worked well for us.
<v-autocomplete v-model="data.alarmInfoId" :items="dbQueryResult" item-value="prop3" :item-text="(row) => {return row.prop1+ ' - ' + row.prop2;}"/>
dbQueryResult is a list of items returned from an API call
prop1, prop2, and prop3 are properties on each row in dbQueryResult
I believe that this will work with v-select as well. Though we use v-autocomplete so that users can type search in larger lists.
use slot="selection"
<template slot="selection" slot-scope="item">
{{ item.name }}-{{ item.group }}
</template>
To know more slot
https://vuetifyjs.com/en/api/v-autocomplete/#slots
item-text can accept a function
:item-text="item => `${item.first_value} ${item.second_value}`"