Adding images to Vue Select dropdown? - vue.js

I am using vue-select component as my dropdowns and giving it :options as the data to put in the dropdown. I am using it for a credit card dropdown right now and want to add the card type image in in each dropdown row. Is this possible?

You could use the scoped option slot that vue-select provides for creating custom dropdown templates.
Assuming that your options data looked like this:
options: [
{
title: "Visa",
cardImage: "https://codeclimate.com/github/sagalbot/linktoimage.png"
},
{
title: "Mastercard",
cardImage: "https://codeclimate.com/github/sagalbot/linktoimage.png"
}
];
Then you could use it as such:
<v-select :options="options" label="title">
<template slot="option" slot-scope="option">
<img :src="option.cardImage" />
{{ option.title }}
</template>
</v-select>

Related

How do set a default value in select option in element UI for Vue?

I am working on a Vue app made with element UI and I have a bunch of el-select whose el-options need to have default values, meaning the form select fields already have one option pre-selected (of course the user can still choose other options).
I cannot find any attribute in the official doc https://element.eleme.io/#/en-US/component/select#select
But there should be a way to achieve this right?
This is my code
<el-form-item label="some label" prop="someprop">
<el-select v-model="form.status" filterable clearable>
<el-option
v-for="(item, index) in config.status"
:key="index"
:label="item"
:value="index"
how to have default option here??
>
</el-option>
</el-select>
</el-form-item>
Just put in the form.status the indexes that should be pre-selected. Vue will take care of the rest.
data(){
return {
form: { status: ['thisWillBePreSelected'], },
}
}

Vuetify change checkbox icon in v-select / v-combobox

I use Vuetify but disabled the import of all icons since treeshaking wasn't working properly in Nuxt, instead I followed the advice and import them manually as stated in this thread: vuetifyjs: Adding only used icons to build
However, this means that a lot of components that require icons, e.g v-checkbox, v-select or v-combobox (which uses v-checkbox in their dropdown menus) need their icons added manually. Just using v-checkbox allows for :on-icon & :off-icon props to be used but I can't figure out how I'd reach them when the checkboxes are used by other components.
I've been attempting to change the behaviour in both v-select and v-combobox.
This is as far as I got but clearly this doesn't add the checked icon, just the blank one.
<v-combobox outlined multiple chips v-model="select" :items="items">
<template v-slot:item="{ item }">
<v-icon>{{mdiCheckboxBlankOutline}}</v-icon>{{ item }}
/template>
</v-combobox>
import { mdiCheckboxBlankOutline, mdiCheckboxMarked } from "#mdi/js";
Data(){
select: ["Stockholm"],
items: [
"Stockholm",
"London",
],
}
My question is therefore, how can replicate the default checkbox behaviour for the combobox menu using imported icons?
This thread seems to talk about it but never ends up showing a code example:
https://github.com/vuetifyjs/vuetify/issues/10904
(Meaning it should look like this)
You can use the item slot, where you are provided with the item, on and attrs object, to replicate the default behaviour.
You bind the on (events) and attrs (properties) objects to the custom list item, to send click events from your list item to combobox component.
Next you set the appropriate icon depending on the selected values. See the code below and the code sandbox.
<template>
<v-app>
<v-combobox
label="Label"
outlined
multiple
chips
v-model="select"
:items="items"
>
<template v-slot:item="{ item, on, attrs }">
<v-list-item v-on="on" v-bind="attrs">
<v-list-item-icon>
<v-icon>
{{ select.includes(item) ? checkIcon : uncheckIcon }}
</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title v-text="item" class="text-left"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</template>
</v-combobox>
</v-app>
</template>
<script>
import { mdiCheckboxBlankOutline, mdiCheckboxMarked } from "#mdi/js";
export default {
name: "HelloWorld",
data() {
return {
items: ["One", "Two", "Three"],
select: [],
uncheckIcon: mdiCheckboxBlankOutline,
checkIcon: mdiCheckboxMarked,
};
},
};
</script>
CodeSandbox: https://codesandbox.io/s/recursing-banach-cb7ys?file=/src/components/HelloWorld.vue

Is there a better way to support label subscripts in dynamically generated b-form-groups with BootstrapVue?

I'm writing a Vue.js app using BootstrapVue. I'm dynamically generating a form based on a simple "field" data structure (see code and screenshot below). The label for each <b-form-group> comes from a label attribute in my field object. It worked fine until I needed a subscript in the label. I'm using the <sub> HTML tag, but v-bind-ing the label treats the HTML as plain text. See the first column of inputs:
Next I tried using <b-form-group>'s label slot instead, using mustache templates. As documented, this also interprets the value as plain text, so I get the same result -- see the second column.
Finally, I was able to achieve the result I wanted using v-html in a span inside the label slot. This works (see the third column), but it seems a bit convoluted, and it's not making the linter happy (yes, I can always turn it off).
Is there a better way to achieve this? I'm relatively new to Vue.js.
(Note that I've simplified the example for brevity, omitting id's, etc.)
<template>
<div class="m-4">
<b-container>
<b-form-row class="round-border">
<b-col
cols="4"
>
<b-form class="mr-4">
<b-form-group
v-for="(field, index) in fields"
:key="index"
:label="field.label"
>
<b-form-input
v-model.number="form[field.model]"
v-bind="field.atts"
/>
</b-form-group>
</b-form>
</b-col>
<b-col
cols="4"
>
<b-form class="mr-4">
<b-form-group
v-for="(field, index) in fields"
:key="index"
>
<label>{{ field.label }}</label>
<b-form-input
v-model.number="form[field.model]"
v-bind="field.atts"
/>
</b-form-group>
</b-form>
</b-col>
<b-col
cols="4"
>
<b-form class="mr-4">
<b-form-group
v-for="(field, index) in fields"
:key="index"
>
<label><span v-html="field.label" /></label>
<b-form-input
v-model.number="form[field.model]"
v-bind="field.atts"
/>
</b-form-group>
</b-form>
</b-col>
</b-form-row>
</b-container>
</div>
</template>
<script>
export default {
components: {},
data () {
return {
form: {
Length: 1,
Width: 4,
Height: 9
},
fields: [
{ label: 'Label<sub>1</sub>', model: 'Length', atts: { type: 'number', step: 1 } },
{ label: 'Label<sub>2</sub>', model: 'Width', atts: { type: 'number', step: 1 } },
{ label: 'Label<sub>3</sub>', model: 'Height', atts: { type: 'number', step: 1 } }
]
};
}
};
</script>
As #Ian Cho says, if the content of field.label property is html as string, the only way to solve it in vue.js is using v-html.
If you are able to change the field item structure to something like {label: 'Label', sub: 1, ...}, you can use label slot as following:
<b-form-group v-for="(f, i) in fields">
<template slot="label">{{f.label}} <sub>{{f.sub}}</sub></template>
<!-- rest of your code -->
</b-form-group>
DEMO: https://jsfiddle.net/4xmr35p0/
If you have to use HTML tags as parameter, v-html is the only way.
If there's another way, please anyone let me know. ;)

tooltip on sortable header cells of BootstrapVue table

I would like to add tooltips for some of the header cells of my BootstrapVue sortable table. The table is tagged like this:
<b-table
striped
small
hover
sticky-header
sort-icon-left
selectable
id="search_results_table_id"
select-mode="single"
:items="person_list"
:fields="person_fields">
I tried to accomplish this using v-slot:head(), but wasn't able to make it work. Here is how my person_fields object is currently looking.
person_fields: [{key: 'name', label: 'Person ID', sortable: true, tooltip: 'Eureka!'},...],
And here was my v-slot:head...
Here is my v-slot:head...
<template v-slot:head()="data">
<span v-b-tooltip.hover :title='data.tooltip'>{{ data.label}}
</span>
</template>
Thanks in advance for the help!
It's because you're binding your title to an undefined property inside your slot.
The tooltip property, is nested inside a field object, which contains all the data for the field.
<template v-slot:head()="data">
<span v-b-tooltip.hover :title='data.field.tooltip'>
{{ data.label }}
</span>
</template>

Vuejs Vuetify how to access properties of object in v-select

My use case.
I got an array of objects from a back-end api.
I want to render those objects in a v-select
This is my code.
<v-select
:items="categories"
name="category"
label="Select a category"
v-model="category"
v-validate="'required'"
>
</v-select>
But it gives me the output.
But I wants objects name property to be display in the v-select
We would do this in vanilla Vue.js
<li v-for="cat in categories" :key="cat.name">{{cat.name}}</li>
But here with vuetify we can't do this.
:items="categories.name"
Vuetify documentation
Can be an array of objects or array of strings. When using objects,
will look for a text and value field. This can be changed using the
item-text and item-value props.
What they actually mean by item-text and item-value
How do I achieve this using item-text
Your category has name attribute, you can pass to item-text:
<v-select
:items="categories"
v-model="category"
name="category"
v-validate="'required'"
item-text="name"
label="Select a category"
/>
I'd seen a similar solution on an example on codepen, but for some reason it did not work to merely assign the "name" to my item-text. Adding single quotes around the name attribute, thus making it a string, is what worked for me (but I don't know why that is):
<v-select v-if="categories"
:items="categories"
:item-text="'name'"
:item-value="'name'"
v-model="selectedCategory"
name="selectedCategory"
label="Select categories"
solo
dark
>
</v-select>
<script> ...
categories: [
{ name: "test", path: "test" },
{ name: "test1", path: "test1" }
],
</script>
For those still looking, the item-name and item-value props are used to specify what value to return for the name and value from the item. If you want to display only the name, but keep the entire object as the value, the return-object prop will return the entire object in the v-model.
Check out the documentation at: https://vuetifyjs.com/en/components/selects/#custom-text-and-value
<v-select :items="categories" v-model="category" name="category"
v-validate="'required'" item-text="name" return-object label="Select a category"
/>
For Vuetify 2.x use <v-slot:item> slot to customize the list and <v-slot:selection> to customize the selection. check v-select slot list in the docs
<v-select
:items="categories"
name="category"
label="Select a category"
v-model="category"
v-validate="'required'"
>
<template v-slot:item="{item}">
{{item.name}}
</template>
<template v-slot:selection="{item}">
{{item.name}}
</template>
</v-select>
To be clear here's with script
<template>
<v-select
outlined
:items="areas"
v-model="area"
name="area"
item-text="text"
label="Area"
return-object
></v-select>
</template>
<script>
export default {
data: () => ({
area: { text: 'area', disabled: false, status: false },
areas: [
{ text: 'Pre-op', disabled: false },
{ text: 'Operational', disabled: false },
{ text: 'USDA', disabled: false },
],
}),
}
</script>