tooltip on sortable header cells of BootstrapVue table - vue.js

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>

Related

Allow duplicated tags in bootstrap vue

I am in trouble with using duplicated tags in bootstrap Vue.
I am using the form tags in bootstrap Vue.
I cannot add the same value inside existing values.
['apple', 'orange', 'banana']
For example, I cannot add a new value of "apple" if the value of "apple" is already in the value array. This is because the form tag checks duplicated values and blocks to add them to the value array.
How can I add the same value to this array?
Here is the code I'm using:
<template>
<div>
<b-form-tags v-model="value" no-outer-focus class="mb-2">
<template v-slot="{ tags, inputAttrs, inputHandlers, tagVariant, addTag, removeTag }">
<b-input-group class="mb-2">
<b-form-input
v-bind="inputAttrs"
v-on="inputHandlers"
placeholder="New tag - Press enter to add"
class="form-control"
></b-form-input>
<b-input-group-append>
<b-button #click="addTag()" variant="primary">Add</b-button>
</b-input-group-append>
</b-input-group>
<div class="d-inline-block" style="font-size: 1.5rem;">
<b-form-tag
v-for="tag in tags"
#remove="removeTag(tag)"
:key="tag"
:title="tag"
:variant="tagVariant"
class="mr-1"
>{{ tag }}</b-form-tag>
</div>
</template>
</b-form-tags>
</div>
</template>
<script>
export default {
data() {
return {
value: ['apple', 'orange', 'banana']
}
}
}
</script>
This is because you are looping over a string array and using array elements as key. Please read this:
To give Vue a hint so that it can track each node’s identity, and thus reuse and reorder existing elements, you need to provide a unique key attribute for each item
Notice "you need to provide a unique key attribute for each item", but you are doing opposite and using array element as key, to handle this case you can always use the index from the loop, because index is unique for each element so:
<b-form-tag
v-for="(tag, index) in tags"
#remove="removeTag(tag)"
:key="index"
:title="tag"
:variant="tagVariant"
class="mr-1"
>{{ tag }}</b-form-tag>
</div>
Now this will not give you duplicate items error :)

vuetify datatable search cannot search the value

I found the miss function on vuetify datatable.
I think that my configuration is correct.
This is my datatable vuetify
<v-text-field v-model="search" append-icon="mdi-magnify" label="Search" single-line
hide-details></v-text-field>
</v-card-title>
<v-data-table loading loading-text="Loading... Please wait" :headers="headers"
:items="goodsData" :search="search" :items-per-page="10" class="elevation-1">
<template v-slot:item.typeOfGoods="{ item }">
<div class="userDatatable-inline-title my-3">
<a href="#" class="text-dark fw-500">
<h6 v-if="item.typeOfGoods == 1">Document
#{{item.receiptNumber}}</h6>
<h6 v-if="item.typeOfGoods == 2">Packet
#{{item.receiptNumber}}</h6>
</a>
<p class="pt-1 d-block mb-0">
<i class="fas fa-dolly"></i> via {{item.courier}} • Received at
{{item.created_at}}
</p>
</div>
</template>
<template v-slot:item.receiver="{ item }">
<img class="rounded-circle wh-34"
:src="`/dashboard/img/author/profile/`+item.receiver.avatar"
alt="author">
{{item.receiver.name}}
</template>
<template v-slot:item.status="{ item }">
<span class="media-badge color-white bg-primary" v-if="item.status==0">Available
at
receiptionist</span>
<span class="media-badge color-white bg-success" v-if="item.status==1">Well
received</span>
<span class="media-badge color-white bg-danger"
v-if="item.status==2">Terminated</span>
</template>
<template v-slot:item.actions="{item}">
<a href="#" v-on:click="receivedAction(item.id)" v-if="item.status==0"><span
style="color:blue;"><i class="far fa-check-circle"></i> Update
status</span></a>
<a v-if="item.status==1"><span style="color:green;"><i
class="fas fa-check-circle"></i>
Done</span></a>
</template>
</v-data-table>
This is my script data
// datatable
search: '',
goodsData: [],
headers: [{
text: 'Goods Type',
value: 'typeOfGoods'
}, {
text: 'Recipient',
value: 'receiver'
}, {
text: 'Status',
value: 'status'
}, {
text: 'Actions',
value: 'actions',
filterable: false,
sortable: false
}],
I already read the documentation on codepen and on https://vuetifyjs.com/en/components/data-tables/#api
Or you can see my repo,
https://github.com/bintangjtobing/boxity-app/blob/master/resources/js/components/goodsReceipt.vue
You can see my gif below
Thank you, everyone, hope you can help to solve this prob.
Thank you thank you.
The search only looks in fields you’ve defined. The text “Document” is not in a field, it’s in your template. The number comes from receiptNumber which is not defined in headers or anywhere, it’s just in the template. Therefore the search can’t know about that either.
You’ll need to provide your own filter function as the documentation you linked to explains in the beginning. I don’t see such defined here.
I found a simple solution for this by creating same header and value but hidden for the column used in template.
You can try this:
{ text: "", value: "header_value", align: ' d-none' },
{ text: "Header Name", value: "header_value" }
Wherein you have to hide the other one by using ' d-none' that will be use to still search the value of that column while the other one is use to display the value. Else if you don't want to use this, you can use the other solution stated here, by creating a custom filter/search.

Vuetify using one search / combo box to achieve multiple filtering like Gmail

Hi basically I would like to create functionality similar to Gmail search. So for example I will have a set list of columns that user can filter by i.e. id, name etc. So the way Gmail search works is that it give hits for example from:, subject:, date-begin: etc. which I believe can be achieved using autocomplete or combo box with vuetify. However I am struggling to use user input value as value for selected item which I then need to send to backend to fetch the results.
<v-combobox
:items="autoCompleteItems"
hide-selected
label="Search/Filter.."
:allow-overflow="false"
multiple
dense
clearable
:auto-select-first="true"
item-text="text"
item-value="value"
#update:search-input="fetch"
>
<template v-slot:selection="{ attrs, item, parent, selected }">
<v-chip
v-if="item === Object(item)"
v-bind="attrs"
:input-value="selected"
label
small
class="mt-3 mb-3"
>
<span class="pr-2">
{{ item.text }} {{ item.value }}
</span>
v-icon
small
#click="parent.selectItem(item)"
>
$delete
</v-icon>
</v-chip>
</template>
</v-combobox>
autoCompleteItems: [
{text: 'id:', value: 'id'},
{text: 'name:', value: 'name'},
{text: 'location:', value: 'location.name'},
]
So with the code above when user selects an item from available options the value will be whatever is in the value property of the selected option which is correct and expected behavior. However I would like it use user entered value like in Gmail app instead of a set value. For example, name: Paul, location: England. Is it possible to achieve this? Any help will be much appreciated.
Please see link to what I have so far:
https://codepen.io/harshpatel01/pen/xxdGydj

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>

Adding images to Vue Select dropdown?

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>