vuetify v-select multiple text values - vue.js

i am trying to set mutliple text items in a v-select.
at the moment this is my v-select and its working with one :item-text.
But i need to display two fields. so i was checking the documentation and tried to use slots.
<v-select
:disabled="isReadOnly()"
v-show="!isHidden()"
:label="getLabel()"
:hint="field.description"
:items="selectVal"
:item-value="field.options.select.ValueField"
:item-text="field.options.select.TextField"
:multiple="isType(FieldType.ManyToMany)"
:chips="isType(FieldType.ManyToMany)"
v-model="fieldValue"
:rules=rules()
return-object
>
</v-select>
But when i am doing this:
<template slot="selection" slot-scope="data">
{{ data.item.name }} - {{ data.item.description }}
</template>
<template slot="item" slot-scope="data">
{{ data.item.name }} - {{ data.item.description }}
</template>
the default behavior of v-select must be reimplemented. (chips, displaying checkboxes on multiple select....
is there another way to do this? without copying the default behaviors und have duplicated code for this simple task?
thanks in advance.
sorry for the beginner question.

item-text can also be a function so you can do something like this
<v-select
:disabled="isReadOnly()"
v-show="!isHidden()"
:label="getLabel()"
:hint="field.description"
:items="selectVal"
:item-value="field.options.select.ValueField"
:item-text="getFieldText"
:multiple="isType(FieldType.ManyToMany)"
:chips="isType(FieldType.ManyToMany)"
v-model="fieldValue"
:rules=rules()
return-object
>
</v-select>
methods:
{
getFieldText (item)
{
return `${item.name} - ${item.description}`
}
}

Related

How can we find out the parent element in which the vue draggable is dropped?

There are multiple v-autocompletes and I want to know which v-autocomplete is my draggable element dropped in So that I can rearrange them properly. If I try to move the v-chips (draggable component) into another v-autocomplete it does not get positioned properly. I am using vue-draggable library, any kind of help will be appreciated thanks!!
v-autocomplete(
v-for="(cabinet, index) in cabinets"
:key="index"
v-model="selectedSystemCabinets[cabinet-1]"
#input="updateSelectedSystems()"
:items="systems"
:label="$t('Controllers')"
:rules="rules.nonEmptyArray"
:id="cabinet"
chips
multiple
return-object
outlined
color="primary"
item-text="name"
item-value="systemID"
)
template(#selection="data")
draggable(
:id="data.index"
:list="selectedSystemCabinets[cabinet-1]"
v-bind="dragOptions"
:move="move"
:group="{name: 'controllers', put: true}"
#change="change(cabinet, $event)"
#start="isDragging = true"
#end="endDrag"
)
v-chip(
draggable
:ripple="false"
:key="data.index"
v-model="selectedSystemCabinets[cabinet-1][data.index]"
#mousedown.stop
#click:close="remove(cabinet, data.index)"
#click.stop
style="cursor: move;"
:color="((isDragging && data.index === dragged.from) ? 'success' : 'primary')"
close
outlined
).ma-2
span {{ data.item.name }}
v-chip(
x-small
color="primary"
).primary-chip
span(v-if="showPrimary(data) && cabinet === 1").text-uppercase {{ $t('primary') }}
span(v-else) {{ getOrderNumber(data.index) }}

How can I pass a v-data-table row information to child element

I have creating a list of users want to add them tags. I am using a data-table to display them and a combo box using chips to add or remove tags. How can I pass the user information to the method called when I add / remove a tag? Here is my code:
<v-data-table :headers="headers" :items="usersInfos" :search="search" :items-per-page="-1">
<template v-slot:[`item.tags`]="{ item }">
<v-combobox v-model="item.tags" :items="roles" chips clearable label="RĂ´les" multiple>
<template v-slot:selection="{ attrs, item, select, selected }">
<v-chip
v-bind="attrs"
:input-value="selected"
close
#click="select"
#click:close="removeRole(item)"
>
{{ item }} <!-- the tag -->
</v-chip>
</template>
</v-combobox>
</template>
</v-data-table>
Don't know if I understood it correctly but you can do following pass your item with your click event to your methods - call the function and use the passed parameter there.
in your template
#click=getSelectedItem(usersInfos)
in your script
methods: {
getSelectedItem(usersInfos) {
//do code here
console.log(usersInfos)
}
}
and than you have to use this where you have written your child element:
<child :usersInfo="usersInfo">
and in your child.vue you have to set props in your script like this:
props: ["usersInfo"]

vue.js how do I make a v-slot template dynamic?

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>

How to add more properties to a slot on Datatables Vuetify 2.0?

How to add two or more properties on the same slot on Datatable Vuetify 2.0
I use below code for only one property called active, but if I want to use it for few other properties means (like status, is_user and etc), how can I use that? any OR condition on v-slot
<template v-slot:item.active="{ item }">
<v-icon class="font--style"> {{ item.active ? 'done' : 'clear' }} </v-icon>
</template>
Thanks in advance!
Maybe this extended example can help you to figure it out.
Here is the link https://codepen.io/anon/pen/aeVjBK?editors=1010
<template v-slot:item.fat="{ item }">
<v-icon :color="item.fat > 10 ? 'red' : 'green'">{{ item.fat > 10 ? 'done' : 'clear' }}</v-icon>
<span>({{item.fat}}%)</span>
</template>
After the response from Vuetify Discord Chennal
We can do something like this to achieve by having a list of column names in the array,
let listOfColumns = ['isActive', 'isUser']
<template v-for="(column, index) in listOfColumns" #[`item.${column}`]="{ item }">
<v-icon class="font--style" :key="index"> {{ item[column] ? 'done' : 'clear' }} </v-icon>
</template>
Thanks !!!

Vuetify concatenate two fields in v-select's item-text

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}`"