Vuetify DataTable sorting - vue.js

i'm working with https://vuetifyjs.com/en/components/data-tables/ and i set prop
:options.sync="filter_values"
#update:options="updateFilterValues()"
the problem i have, is that i want to disable the sorting for some columns, so i set the headers as this, with prop sortable: false:
headers: [
{
value: "checkbox",
sortable: false,
width: '10%'
},
{
value: "userId",
sortable: true,
width: '30%'
},
{
value: "clientId",
sortable: true,
width: '30%'
},
{
value: "clientInformation",
sortable: false,
width: '30%',
},
],
I don't know exactly why this is not getting my prop sortable: false and all the columns are sortable, i'm trying to find documentation but there is nothing related to this.

Ideally it should work, Here is the working demo. Kindly have a look and please try to find out the root cause of the issue you are facing by referencing the below demo.
new Vue({
el: "#app",
vuetify: new Vuetify(),
data: () => ({
headers: [ { text: 'Bool', sortable: false, value: 'status' }, { text: 'String', sortable: true, value: 'val' } ],
items: [ { status: "True", val: "Alpha" }, { status: "False", val: "Beta" }, { status: "True", val: "Gamma" } ],
})
});
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<v-app id="app">
<v-data-table
:headers="headers"
:items="items"
>
</v-data-table>
</v-app>

Check this codepen I made: https://codepen.io/cmfc31/pen/zYjKOjx?editors=1010
<v-data-table
dense
:headers="headers"
:items="desserts"
:options.sync="filter_values"
item-key="name"
class="elevation-1"
></v-data-table>
If you use the .sync modifier in your options prop, theres no need to listen for the #update:options event. Your variable filter_values will automatically be in sync with the component and update on changes.

Related

Vuetify datatable not show custom cells with v-slot

I have an asp .net web forms app with Vue 2.7.14 and Vuetify 2.6.13.
I have a table and I want to implement v-slot:item.fieldName to style certain cells but it doesn't work.
<v-data-table :footer-props="{ 'items-per-page-options': [10, 50, 100, 500, 1000] }" :items-per-page="10" :headers="headers" :items="supplierList" :loading="loadingGrid" :loading-text="$t('gral_loading')" :options.sync="options" :server-items-length="totalItems">
<template v-slot:item.businessName="{item}">
Hola
</template>
</v-data-table
headers: [
{ text: this.$t('supplier_code'), value: 'code' },
{ text: this.$t('supplier_businessName'), value: 'businessName' },
{ text: this.$t('supplier_alias'), value: 'alias' },
{ text: this.$t('supplier_isDirect'), value: 'isDirect' },
{ text: this.$t('supplier_isAppendFile'), value: 'isAppendFile' },
{ text: this.$t('supplier_isSendEDINotification'), value: 'isSendEDINotification' },
{ text: this.$t('supplier_cat_PlantId'), value: 'plantName' },
{ text: this.$t('supplier_cat_AnalystId'), value: 'analystProcess' },
{ text: this.$t('supplier_cat_supplierTypeId'), value: 'supplierTypeName' },
{ text: this.$t('supplier_isActive'), value: 'isActive' },
{
text: this.$t('gral_acciones'),
value: 'action',
sortable: false
},
],
This is the array data items :
supplierList: [{
"supplierTypeId": 1,
"name": "Transportista",
"description": "Transportista",
"isScrap": false,
"isSystem": false,
"isActive": true,
"isDelete": false,
"creationDate": "0001-01-01T00:00:00",
"lastUpdate": "0001-01-01T00:00:00",
"createdBy": 1,
"lastUpdateBy": 0,
"systemId": null,
"sessionData": null,
"item": null,
"page": null,
"size": null,
"sortBy": null,
"ascending": null,
"alertNotification": null
}]
After spending some time and play around with the v-data-table demo, I found that as long as the headers value is in lowercase the issue doesn't appear.
Working Demo :
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
headers: [{ text: 'Code', value: 'code' },
{ text: 'Business Name', value: 'businessname' },
{ text: 'Alias', value: 'alias' },
{ text: 'Is Direct', value: 'isDirect' },
{ text: 'Is Append File', value: 'isAppendFile' },
{ text: 'Notification', value: 'isSendEDINotification' },
{ text: 'Plant Name', value: 'plantName' },
{ text: 'Analyst Process', value: 'analystProcess' },
{ text: 'Supplier Type Name', value: 'supplierTypeName' },
{ text: 'Is Active', value: 'isActive' },
{ text: 'Action', value: 'action' }],
supplierList: [{
"supplierTypeId": 1,
"name": "Transportista",
"description": "Transportista",
"isScrap": false,
"isSystem": false,
"isActive": true,
"isDelete": false,
"creationDate": "0001-01-01T00:00:00",
"lastUpdate": "0001-01-01T00:00:00",
"createdBy": 1,
"lastUpdateBy": 0,
"systemId": null,
"sessionData": null,
"item": null,
"page": null,
"size": null,
"sortBy": null,
"ascending": null,
"alertNotification": null
}],
}
}
})
<script src="https://unpkg.com/vue#2.x/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#2.6.14/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify#2.6.14/dist/vuetify.min.css"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"/>
<div id="app">
<v-app id="inspire">
<v-data-table
:headers="headers"
:items="supplierList"
:items-per-page="5">
<template v-slot:item.businessname="{item}">
<span>Hola</span>
</template>
</v-data-table>
</v-app>
</div>

Vue, Vuetify table make headers bold

I am using Vue and Vuetify to generate a table which I do.
I want to make the headers of the table bold. Hence, I am thinking of passing a class to the headers and customize the headers from the CSS. Despite the fact that when I inspect the page(F12-> inspector) on the header my custom class has been passed but it don't do what I want it to do I feel like the code is overridden somehow. Can you please help ?
HTML:
<v-data-table
:headers="headers"
:items="myDataPSUTwo"
:search="search"
></v-data-table>
the script:
data() {
return {
search: "",
headers: [
{
text: "Name",
align: "center",
filterable: true,
value: "name",
class:"header-of-chart"
},
{ text: "Value", value: "value" },
{ text: "Unit", value: "units" },
],
};
},
the CSS:
<style scoped>
.header-of-chart {
font-weight: bold;
}
</style
v-data-table have a header slot. You can use it to modify header style.
<template>
<div id="app">
<v-app id="inspire">
<v-data-table
:headers="headers"
:items="desserts"
:sort-by="['calories', 'fat']"
:sort-desc="[false, true]"
multi-sort
hide-default-header
class="elevation-1"
>
<template v-slot:header="{ props }">
<th v-for="head in props.headers">{{ head.text.toUpperCase() }}
</template>
</v-data-table>
</v-app>
</div>
</template>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
headers: [
{
text: 'Dessert (100g serving)',
align: 'start',
sortable: false,
value: 'name',
},
{ text: 'Calories', value: 'calories' },
{ text: 'Fat (g)', value: 'fat' },
{ text: 'Carbs (g)', value: 'carbs' },
{ text: 'Protein (g)', value: 'protein' },
{ text: 'Iron (%)', value: 'iron' },
],
desserts: [
{
name: 'Frozen Yogurt',
calories: 200,
fat: 6.0,
carbs: 24,
protein: 4.0,
iron: '1%',
}
],
}
},
})
v-data-table already have header text in bold that's the reason it is not impact anything. You want to increase the font size ? You can use it like this :
.header-of-chart {
font-size: 25px !important;
}

How to make multiple search filters work with a for loop in Vue Bootstrap?

I have a table with some filters in each column but when I type anything all the items disappear. The console does not return any error.
Here’s the code:
<template>
<div>
<b-table
id="the-table"
:per-page="perPage"
:current-page="currentPage"
:items="filteredItems"
:fields="fields"
>
<template slot="top-row" slot-scope="{ fields }">
<td v-for="field in fields" :key="field.key">
<input v-model="filters[field.key]" :placeholder="field.label" />
</td>
</template>
</b-table>
<b-pagination v-model="currentPage" :total-rows="rows" :per-page="perPage" aria-controls="the-table"></b-pagination>
</div>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
filters: {
option: "",
style: "",
stock: "",
},
items: [],
fields: [
{ key: "options", label: "Options", sortable: true },
{ key: "style", label: "Style", sortable: true },
{ key: "stock", label: "Stock", sortable: true },
{ key: "type", label: "Type", sortable: true },
{ key: "class", label: "Class.", sortable: true },
],
perPage: 15,
currentPage: 1,
};
},
created() {
this.getTable();
},
methods: {
getTable() {
axios
.get("./data/options.json")
.then((res) => (this.items = res.data))
.catch((error) => console.log(error));
},
},
computed: {
rows() {
return this.items.length;
},
filteredItems() {
return this.items.filter((d) => {
return Object.keys(this.filters).every((f) => {
return this.filters[f].length < 1 || this.filters[f].includes(d[f]);
});
});
},
},
};
</script>
I am trying to filter an array of objects like this:
[{"option": "ABEVH160", "style": "American", "stock": "ABEV3", "type": "CALL", "class": "ITM"},
{"option": "BBAS230", "style": "European", "stock": "BBAS3", "type": "PUT", "class": "ATM"},
{"option": "BBDC180", "style": "American", "stock": "BBDC4", "type": "CALL", "class": "OTM"}]
My goal is to be able to filter each of the columns individually:
Does anyone know what I’m missing?
The problem is with the condition:
return this.filters[f].length < 1 || this.filters[f].includes(d[f]);
d[f] is the full value and this.filters[f] is the search string. Obviously this does not work since it checks if the full word is contained in a substring. Simply invert the condition:
return this.filters[f].length < 1 || d[f].includes(this.filters[f]);
You can see it working here.
What you want seems to be something like DataTable Filter | Filter Row in PrimeVue. I tried to find something similar in the documentation of bootstrap-vue (documentation), but couldn´t find anything like that.
Maybe you are in a stage where you can still implement PrimeVue in your project. I´m using Filter Row from PrimeVue by myself and can recommend it.

Show/Hide columns dynamically with a bootstrap-vue component and bootstrap 3

I am currently trying to show/hide dynamically with a bootstrap-vue table (https://bootstrap-vue.js.org/docs/components/table).
So far, I only managed to hide the header but the cells won't disappear, which is a problem because the cells are not in front of the good headers (the numbers should be under days and 'ingredient' should be under item.
Here what's 'worked':
fields: [
{key: "day", label: "Day",sortable: true, thStyle:"display:none"},
{key: "item", label: "Item",sortable: true}
]
I was wondering if it was possible to maybe do that outside of vueJS, and change the properties of the column with CSS directly..
Thanks for the help !
Louis
You could add an additional property to your fields. For example visible and create a computed property that filters out all fields with visible: false.
That way you can simply toggle this property to show/hide your columns.
window.onload = () => {
new Vue({
el: '#app',
computed: {
visibleFields() {
return this.fields.filter(field => field.visible)
}
},
data() {
return {
items: [
{ id: 1, first: 'Mike', last: 'Kristensen', age: 16 },
{ id: 2, first: 'Peter', last: 'Madsen', age: 52 },
{ id: 3, first: 'Mads', last: 'Mikkelsen', age: 76 },
{ id: 4, first: 'Mikkel', last: 'Hansen', age: 34 },
],
fields: [
{ key: 'id', label: 'ID', visible: true },
{ key: 'first', label: 'First Name', visible: true },
{ key: 'last', label: 'Last Name', visible: true },
{ key: 'age', label: 'Age', visible: true },
]
}
}
})
}
<link href="https://unpkg.com/bootstrap#4.4.1/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://unpkg.com/bootstrap-vue#2.2.2/dist/bootstrap-vue.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue#2.2.2/dist/bootstrap-vue.min.js"></script>
<div id='app'>
<b-checkbox
:disabled="visibleFields.length == 1 && field.visible"
v-for="field in fields"
:key="field.key"
v-model="field.visible"
inline
>
{{ field.label }}
</b-checkbox>
<br /><br />
<b-table :items="items" :fields="visibleFields" bordered>
</b-table>
</div>

Create highcharts vue component

in my page i need to show many charts, so i would like to create an Highcharts component and use it inside my .vue file within a v-for cicle.
how could i achieve this? here is what i did:
in my .vue page I have:
<v-flex ma-3 v-for="(el,index) in Items">
<my-chart-component
:series="el.series"
:xlabels="el.Labels"
:height="'300px'"
width="100%"
></my-chart-component>
</v-flex>
inside my component i have:
<template>
<chart
:series="mySeries"
:xlabels="myXlabels"
:options="myChartOptions"
:height="height"
width="100%"
></chart>
</template>
<script>
import VWidget from '#/components/VWidget';
import {Chart} from 'highcharts-vue'
import Highcharts from 'highcharts/highcharts';
import loadExporting from 'highcharts/modules/exporting';
import brokenAxis from 'highcharts/modules/broken-axis';
export default {
name: 'my-chart-component',
components: {
VWidget,
Chart,
Highcharts,
loadExporting,
brokenAxis,
},
props: {
mySeries:Array,
myXlabels:Array,
height:String
},
data() {
return {
myChartOptions: {
chart: {
type: 'column'
},
legend: {
align: 'left',
verticalAlign: 'top',
layout: 'vertical',
x: 100,
y: 30,
floating: true
},
navigation: {
buttonOptions: {
enabled: true
}
},
credits: {
enabled: false
},
xAxis: {
xAxis: {
categories: props.myXlabels
},
},
yAxis: [{
title: {
text: '%',
align: 'middle',
rotation: 0,
},
type: 'linear',
}],
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
}
},
series: {
pointWidth: 15,
borderWidth: 0,
dataLabels: {
enabled: false,
format: '{point.y:.0f}%'
},
cursor: 'pointer',
point: {
events: {
click: ''
}
}
}
},
exporting: {
sourceWidth: 1000,
sourceHeight: 600,
},
tooltip: {
shared: true,
valueSuffix: ' %',
followPointer: false,
},
title: {
text: '',
align: 'left',
margin: 30
},
colors: [
'#00c104',
'#d45087',
],
series: props.mySeries
},
};
},
created(){
loadExporting(Highcharts);
},
methods: {
}
};
</script>
now, i have many errors in the console, i have this error:
Error in data(): "ReferenceError: props is not defined"
in
at src/components/MyChartComponent.vue
and then [Vue warn]: Property or method "myChartOptions" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property
it seems i can't pass the chartOptions by props, how can i workaround this?
thank you
The props that you are passing to your child component should be named as props in the child component.
If props are called mySeries, myXlabels and height, than you should pass it like :my-series, :my-xlabels and :height.
<v-flex ma-3 v-for="(el,index) in Items">
<my-chart-component
:my-series="el.series"
:my-xlabels="el.Labels"
:height="'300px'"
width="100%"
></my-chart-component>
</v-flex>
need to define
<script>
export default {
props: {
Items: Array,
},
}
</script>
then need to pass your variable from parent vue page into this page or component:
<MegaMenu :categories="categories"/>