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

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

Related

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>

vuetify v-select multiple text values

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

Wants to highlight only chars the user types in the input v-autocomplete

I have made a v-autocomplete but it highlights words/chars in the list that the user haven't typed.
the v-autocomplete code:
<v-autocomplete
:filter="() => true"
item-text="states.text"
:items="states"
filled
rounded
v-model="model"
:search-input.sync="search">
<template
slot="item"
slot-scope="{ parent,item }"
>
<v-list-tile-content >
<v-list-tile-title v-html="`${parent.genFilteredText(item.text)}`">
</v-list-tile-title>
</v-list-tile-content>
</template>
</v-autocomplete>
You can se it all in the codepen: https://codepen.io/maikenmadsen92/pen/ZEEZjYM?editors=1010
Is it possible just to highlight the words the user have typed in the input?
There are some issue with the implementation of you v-autocomplete.
You filter is useless since it will alway return true with is why all words/chars is highlights.
And the main issue is you item-text since following the doc vuetify
item-text :
Set property of items's text value
With mean you item-text=text since the items is already set to states.
<v-autocomplete
item-text="text"
:items="states"
filled
rounded
v-model="model"
:search-input.sync="search">
<template
slot="item"
slot-scope="{ parent,item }"
>
<v-list-tile-content >
<v-list-tile-title v-html="`${parent.genFilteredText(item.text)}`">
</v-list-tile-title>
</v-list-tile-content>
</template>
</v-autocomplete>
i am able to use getMaskedCharacters to do the trick

vue scoped slot not being exposed

I am trying to build a stepper component, where the stepper will expose to the child component the step, so it can display certain things. However, the child component is not receiving the step.
Child component:
<template>
<v-stepper v-model="e1">
<v-stepper-header>
<template v-for="i in steps.length">
<v-stepper-step
:key="`${i}-step`"
:complete="e1 > i"
:step="i"
complete-icon="$vuetify.icons.check"
>
{{steps[i-1].text}}
</v-stepper-step>
<v-divider
v-if="i < steps.length"
:key="i"
></v-divider>
</template>
</v-stepper-header>
<v-stepper-items>
<v-stepper-content
v-for="(step, i) in steps"
:key="`$step_content_${i}`"
:step="i+1"
>
{{step}}
<slot :step="step"></slot>
<v-btn
v-if="i+1 < steps.length"
color="primary"
#click="nextStep"
:disabled="step.disabled"
>
{{$t('conditions.stepper_continue')}}
</v-btn>
<v-btn
:disabled="e1 < 2"
#click="prevStep"
flat>
{{$t('conditions.stepper_back')}}
</v-btn>
</v-stepper-content>
</v-stepper-items>
</v-stepper>
</template>
Parent:
<StepperComp v-if="mode !=='list'" :steps="steps">
<template v-if="mode !== 'list'" scoped-slot="step">
{{step}}
</template>
</StepperComp>
I am getting the following error:
Property or method "step" is not defined on the instance but referenced during render.
Why is the parent unable to access the step from the scoped slot?
It looks like you misspelled slot-scope (you incorrectly used scoped-slot). In addition, the attribute value is an object of scope data, so you would have to reference step within that object:
<template slot-scope="scopeData">
{{ scopeData.step }}
</template>
<!-- or use object destructuring -->
<template slot-scope="{ step }">
{{ step }}
</template>
The syntax above is actually deprecated since Vue 2.6.0, so you should migrate to the new recommended syntax:
<template v-slot="scopeData">
{{ scopeData.step }}
</template>
<!-- or use object destructuring -->
<template v-slot="{ step }">
{{ step }}
</template>
<!-- or v-slot shorthand: https://v2.vuejs.org/v2/guide/components-slots.html#Named-Slots-Shorthand -->
<template #default="{ step }">
{{ step }}
</template>

Vuetify Autocomplete, item-slot , keep the highlighting of character

How would one keep the default highlighting of characters ones you replace the scoped-slot of the item.
https://vuetifyjs.com/en/components/autocompletes#scopedSlots
Default , will output a v-list where every character from the input is "higlighted" in the output.
<v-autocomplete
v-model="model"
:items="items"
:loading="isLoading"
:search-input.sync="SomeApiDataCall"
item-text="name"
item-value="id"
>
</v-autocomplete>
Custom scoped-slot : I want to change the design of the list , but would like to keep the "highlighted" output
<v-autocomplete
v-model="model"
:items="items"
:loading="isLoading"
:search-input.sync="SomeApiDataCall"
item-text="name"
item-value="id"
>
<template slot="item"
slot-scope="{ item, tile }"
>
<v-list-tile-content >
<!--the html output needs to be highlighted-->
<v-list-tile-title v-html="item.name"></v-list-tile-title>
</v-list-tile-content>
</template>
</v-autocomplete>
VAutocomplete imports > VSelect, imports > VSelectList
VSelectList has a function called genFilteredText
https://github.com/vuetifyjs/vuetify/blob/dev/src/components/VSelect/VSelectList.js#L112
That will do what I want. How would one implement this in the custom scoped-slot ?
Thanks.
The slot-scope Item can also receive the "parent".
After that you can access any methods on it.
<template
slot="item"
slot-scope="{ parent, item, tile }"
>
<v-list-tile-content>
<!-- Highlight output item.name -->
<v-list-tile-title
v-html="parent.genFilteredText(item.name)"
>
</v-list-tile-title>
</v-list-tile-content>
</template>
I am quite new to vue and it took me a while to translate this question/solution into the new Slots syntax.
For anyone that is also using the new v-slot:item="data" syntax, you can receive the parent as follows:
<template v-slot:item="{ parent, item }">
<v-list-tile-content >
<!--Highlight output item.name-->
<v-list-tile-title
v-html="`${parent.genFilteredText(item.name)}`"
></v-list-tile-title>
</v-list-tile-content>
</template>