I have to pass cell value to the function clicking on the cell. It can be done easily on good table, but I am trying to find the way do it on bootstrap-vue b-table.
table:
<b-table
striped
responsive
class="mb-0"
:items="permissionsData"
>
<template #cell(module)="data">
{{ data.value }}
</template>
<template
#cell()="data"
>
<b-form-checkbox
:checked="data.value"
/>
</template>
</b-table>
and the method:
methods: {
onPermissionClick(value) {
console.log("column name, row name and the value")
}
},
Is anyone know good way how to do that please?
<b-table
striped
responsive
class="mb-0"
:items="permissionsData"
>
<template #cell(module)="data">
<div #click="onPermissionClick">
{{ data.value }}
</div>
</template>
</b-table>
You will get all property in the data. but here I am mentioning cell, row, and column as per your question. other property you can see by console.log(data)
methods: {
onPermissionClick(data) {
console.log(data.value) // cell value
console.log(data.item) // row
console.log(data.field) // column
}
},
Related
I have an input and a click button.
When I click I request a database (async/await) and finally display a table with requested data.
At the same time I display the input keyword like "{{input}} was found X times".
But then I want to do another research but the text of input is reactive and change while I'am typing. I would like to only display the new keyword input after the click.
I'm struggling to do that.
<div class="q-pa-md">
<div class="q-gutter-md" style="max-width:600px">
<q-input outlined bottom-slots v-model="gene" label="Gene Symbol :" >
<template v-slot:before>
<q-icon name="search" />
</template>
<template v-slot:hint>
Ligand or Receptor
</template>
<template v-slot:after>
<q-btn #click="search" label="Search :" />
</template>
</q-input>
</div>
Elsewhere I have this for the display:
<div class="text-h6">
<q-badge align="middle" style="background-color:#FF4F00;font-size:20px;padding:12px">
Interactions > </q-badge> {{ gene }} was found XX times.
</div>
When you use v-model, the value changes with any input change. To avoid it you can define a new variable to store the gene value whenever q-btn is clicked; Like this:
<template>
<input v-model="gene" type="text">
<button #click="search">search</button>
<div v-if="searchedFor">
{{ searchedFor }} was found X times
</div>
</template>
<script>
export default {
data() {
return {
gene: "",
searchedFor: ""
}
},
methods: {
search() {
// Clear the previous one
this.searchedFor = ""
// API fetch ...
this.searchedFor = this.gene
}
}
}
</script>
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.
I am using vue-bootstrap https://bootstrap-vue.js.org/docs/components/table/ and have implemented a slot for the header so I can have a show and hide button in each column header that contains a search box. The header is in a slot. In the fields data I have added a showFilter property that is boolean. So the idea was that it toggled between true and false. Now this all works when in the child you emit the data change to the parent it updates. However the table itself does not update until you trigger another action like try and sort a header, then it updates. I have tried the Force refreshing of table data mentioned in the above url but that does not seem to work, or I can't figure out how to use it as there is not an example.
Parent
<template>
<b-table
ref="table"
:items="filtered"
:fields="fields"
sort-icon-left
responsive="sm"
>
<template v-slot:head()="data">
<TableHeader :data="data" :filters="filters" />
</template>
</b-table>
</template>
data() {
return {
fields: [
{
key: "name",
sortable: true,
showFilters: true,
},
{ key: "age", sortable: true, showFilters: true },
],
}
}
Child
<template>
<div>
<div class="text-info">{{ data.label.toUpperCase() }}</div>
<div>
<button #click="setUpdate(data.field)">filters</button>
</div>
<input
v-show="data.field.showFilters"
v-model="filters[data.field.key]"
:placeholder="data.label"
#keyup="$emit('update:filters[data.field.key]')"
/>
</div>
</template>
methods: {
setUpdate(field) {
this._originalField = Object.assign({}, field);
field.showFilters = !field.showFilters;
this.$root.$emit("update:field.showFilters", "bv::refresh::table");
console.log(field.showFilters);
}
}
I solved this by using a bootstrap collapse button and dealing with it all in the child which makes more sense I think!
<b-collapse :id="'collapse' + data.field.key">
<b-card>
<!-- content -->
</b-card>
</b-collapse>
I'm trying to make a condition to enable a named slot like this:
<template v-slot:item="{ item }" v-if="item.loading">
<v-progress-circular indeterminate color="primary"></v-progress-circular>
</template>
My use case is a Vuetify datatable: each item has a "loading" property, and I'd like to activate "item" slot only if the row is loading ("item" slot is Slot to replace the default rendering of a row)
The error is that item is undefined in the v-if, which seems logic : item is only defined for template children tag.
Is there a way to solve this problem?
You can filter the items that you pass to the datatable with a computed property.
Can you just not swap element based on loading ?
Vue.config.devtools = false;
Vue.config.productionTip = false;
var app = new Vue({
el: '#app',
data: {
items: [{data : "", loading: true}, {data : "Some data", loading: false}]
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="item in items">
<div>
<div v-if="item.loading">
Loading...
</div>
<div v-else>
{{item.data}}
</div>
</div>
</div>
</div>
I had a similar problem, and I solved it in Vuetify 2 by importing VDataTable/Row as 'v-data-table-row', and using it to render 'regular' table rows, and for custom rows I used my own template.
JavaScript
import Row from 'vuetify/lib/components/VDataTable/Row.js';
export default {
components: { 'v-data-table-row': Row },
data() {
return {
currentItemName: 'Ice cream sandwich'
}
}
// headers, items, etc...
}
HTML
<template v-slot:item="{ item }">
<tr v-if="item.name == currentItemName" class="blue-grey lighten-4">
<td>Custom prefix - {{ item.name }}</td>
<td colspan="2">{{ item.calories }} - Custom suffix</td>
</tr>
<v-data-table-row v-else :headers="headers" :item="item">
<template
v-for="(index, name) in $scopedSlots"
v-slot:[name.substr(5)]="data"
>
<slot
v-if="name.substr(0, 5) === 'item.'"
:name="name"
v-bind="data"
></slot>
</template>
</v-data-table-row> </template
You can check out working example here.
You can just put the v-if on the child element
<template #item="{ item }">
<v-progress-circular
v-if="item.loading"
color="primary"
indeterminate
></v-progress-circular>
</template>