How to set <v-data-table> columns to fit its content width? - vuetify.js

How to set v-data-table columns to fit its content width ?
<v-data-table
style="background: transparent"
dense
:headers="headers"
:items="items"
disable-pagination
hide-default-footer
no-data-text="No data available"
>
<!-- Titles -->
<template
v-slot:item.title="{ item }"
>
<div class="text-primary">
{{ item.title }}
</div>
</template>
</v-data-table>

Related

Responsive v-data-table with limited elements showing

I have a v-data-table that's supposed to display 42 elements.
I made it so it can display 10 elements minimum or 42 depending on the user's wishes.
<v-card-text>
<v-data-table
dark
:footer-props="{ 'items-per-page-options': [10, 25, -1] }"
dense
calculate-widths
fixed-header
height="498"
:headers="headers"
:items="res"
sort-by="publicationDate"
:sortDesc="sortVal"
class="elevation-1"
>
<template #item.video="{ item }">
<a
target="_blank"
v-if="item.video != ''"
class="links1 video-icon"
:href="item.video"
>
<v-btn dark icon>
<v-icon class="ic1">mdi-movie</v-icon>
</v-btn>
</a>
</template>
<template #item.title2="{ item }">
<!-- NEWS column -->
<a
target="_blank"
v-if="item.file != ''"
class="links1"
:href="item.file"
>
<span style="color:white"> {{ item.title }} </span>
</a>
</template>
</v-data-table>
</v-card-text>
</v-card>
When 10 items are displayed, I'd like my table to not be scrollable, that all 10 items are displayed and I'd like it to be scrollable when mre than 10 items are displayed.
Does anyone know how to do that ?

How to define the width of expandable panels in Vuetify

As you can see in the picture my expandable panels do not use the maximum available width.
I want the expandable panels to use the maximum width available in the data table and make the columns fit exactly the width of the header columns. In addition to that it would be great to hide the expand Button (and also make the panel not clickable) if there is not enough data to display. I know that there is a hide-actions prop for that but I do not know how to use that.
My code:
<template>
<div class="table table--fixed-layout d-flex flex-grow-1 overflow-hidden fill-height">
<div v-if="loading" class="d-flex ma-auto">
<v-progress-circular indeterminate color="primary" :width="3" />
</div>
<v-data-table
v-else
item-key="id"
hide-default-footer
fixed-header
disable-sort
:headers="headers"
:items="filteredItems"
:items-per-page="-1"
>
<template #[`header.ticketNumber`]="{ header }">
<data-table-filter :name="header.text" #change="ticketNumberFilter = $event" />
</template>
<template #[`header.title`]="{ header }">
<data-table-filter :name="header.text" #change="titleFilter = $event" />
</template>
<template #[`header.status`]="{ header }">
<data-table-filter
:name="header.text"
:default-values="filterableTicketServiceStatuses"
#change="statusFilter = $event"
>
<template #default="{ value }">{{ getTicketServiceStatusLabel(value) }}</template>
</data-table-filter>
</template>
<template #[`header.hostNames`]="{ header }">
<data-table-filter :name="header.text" #change="hostNameFilter = $event" />
</template>
<template #[`header.creator`]="{ header }">
<data-table-filter :name="header.text" #change="creatorFilter = $event" />
</template>
<template v-slot:body="{ items }">
<v-container fluid>
<tbody v-for="item in items" :key="item.id">
<v-expansion-panels>
<v-expansion-panel>
<v-expansion-panel-header>
<template v-slot:default="{ open }">
<v-col>
<ticket-number :ticket-number="item.ticketNumber" />
</v-col>
<v-col>
<td class="pl-4">{{ item.title }}</td>
</v-col>
<v-col>
<li v-for="hostName in getFirstFourTicketHostNames(item)" :key="hostName">
<div class="pt-md-2">{{ hostName }}</div>
</li>
<div v-if="item.hosts.length > 4">
<v-fade-transition leave-absolute>
<span v-if="open">
<li v-for="hostName in getRestOfTicketHostNames(item)" :key="hostName">
<div class="pt-md-2">{{ hostName }}</div>
</li>
</span>
</v-fade-transition>
</div>
</v-col>
<v-col>
{{ getTicketServiceStatusLabel(item.status) }}
</v-col>
<v-col>
{{ item.creator }}
</v-col>
<td class="table__date">{{ formatDateTime(item.creationDate) }}</td>
<v-col></v-col>
<v-col>
<td class="table__date">{{ formatDateTime(item.finishedDate) }}</td>
</v-col>
<v-col>
<td class="pl-4">
<v-icon v-if="item.notifyCustomer">{{ icons.mdiCheck }}</v-icon>
</td>
</v-col>
</template>
</v-expansion-panel-header>
</v-expansion-panel>
</v-expansion-panels>
</tbody>
</v-container>
</template>
</v-data-table>
</div>
</template>
How can I achieve that?

Vuetify 2 rows but rendering like 2 columns

I'm using vuetify and have this:
<v-container
class="d-flex justify-center mb-6"
:color="$vuetify.theme.dark ? 'grey darken-3' : 'grey lighten-4'"
flat
tile
>
<v-row justify="center">
<v-col>
<h1>This is an about page</h1>
</v-col>
</v-row>
<v-row justify="center">
<v-col>
<p>
The logo is licensed with the
<a href="https://creativecommons.org/licenses/by-nc/3.0/" target="_blank">
Creative Commons License</a
>
and is provided by
<a href="https://www.iconfinder.com/laurareen/" target="_blank">
iconfinder</a
>
</p>
</v-col>
</v-row>
</v-container>
It renders like this:
How can I make this render 2 rows instead???
I tried adding sm="12" to each column but same thing.
to have a better understanding about vuetify's grid system you can read the doc here.
but in short according to the doc:
v-container provides the ability to center and horizontally pad your site’s contents.
you don't need to set class="d-flex justify-center" on this element.
also according to v-container API page, this component does not accept flat and tile as prop.
remove these props and classes and you should be good.
check the demo below:
Vue.config.productionTip = false;
new Vue({
el: '#app',
vuetify: new Vuetify(),
})
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<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>
<div id="app">
<v-app>
<v-main>
<v-container>
<v-row justify="center">
<v-col>
<h1>This is an about page</h1>
</v-col>
</v-row>
<v-row justify="center">
<v-col>
<p>
The logo is licensed with the
<a href="https://creativecommons.org/licenses/by-nc/3.0/" target="_blank">
Creative Commons License</a>
and is provided by
<a href="https://www.iconfinder.com/laurareen/" target="_blank">
iconfinder</a>
</p>
</v-col>
</v-row>
</v-container>
</v-main>
</v-app>
</div>

Vuetify Data Table Header Customization - "hide-default-header" removes sort functionality

When adding "hide-default-header" to the v-data-table, I've noticed the sort function for all columns are removed. I'd like to keep that functionality, is there a simple way to re-include sort?
It's tricky because I'm also attempting to add an additional icon with search features next to it, hence the need for a custom th template in the header.
In the code below, the 1st column is attempting to use the sort function to no avail. Any help would be appreciated in getting it working.
<v-data-table
#click:row="rowClick"
:headers="headers"
:items="arrangedList"
:search="search"
:items-per-page="10"
class="outlined elevation-0"
hide-default-header
>
<template>
<thead>
<tr>
<th :class="[
'column sortable',
pagination.descending ? 'desc' : 'asc',
headers[0].value === pagination.sortBy
? 'active'
: '',
]">
<!-- Foo1 -->
{{ headers[0].text }}
<template>
<v-btn :ripple="false" x-small icon>
<v-icon #click="changeSort(headers[0].value)" color="grey darken-1">fa-arrow-up</v-icon>
</v-btn>
</template>
<v-menu attach="#menuAnchor" :close-on-content-click="false" :nudge-height="200" offset-y content-class="gridfilter-dd" style="display: inline-block">
<template v-slot:activator="{ on }" id="menuAnchor">
<v-btn :ripple="false" x-small icon v-on="on">
<v-icon color="grey darken-1">mdi-filter-outline</v-icon>
</v-btn>
</template>
<v-card class="gridfilter-card">
<v-list-item class="gridfilter-list-item">
<v-list-item-content class="gridfilter-list-item-content">
<v-text-field v-model="filterCandyValue" label="Enter Candy #" :clearable="true"></v-text-field>
</v-list-item-content>
</v-list-item>
<v-card-actions class="gridfilter-card__actions">
<v-spacer></v-spacer>
<button type="button" class="btn btn-primary" #click="onCandyFilterApply()">
<i class="fa fa-floppy-o"></i>
Apply
</button>
</v-card-actions>
</v-card>
</v-menu>
</th>
<!-- Foo2 -->
<th>
<v-menu :close-on-content-click="false" :nudge-height="200" offset-y content-class="gridfilter-dd" style="display: inline-block">
<template v-slot:activator="{ on }" id="menuAnchor1">
<span v-on="on">{{ headers[1].text }}</span>
<v-btn :ripple="false" x-small icon v-on="on">
<v-icon color="grey darken-1">mdi-filter-outline</v-icon>
</v-btn>
</template>
<v-card class="gridfilter-card">
<v-list-item class="gridfilter-list-item">
<v-list-item-content class="gridfilter-list-item-content">
<v-text-field label="Enter Foo2 #" :clearable="true"></v-text-field>
</v-list-item-content>
</v-list-item>
<v-card-actions class="gridfilter-card__actions">
<v-spacer></v-spacer>
<button type="button" class="btn btn-primary" #click="onFilterApply()">
<i class="fa fa-floppy-o"></i>
Apply
</button>
</v-card-actions>
</v-card>
</v-menu>
</th>
</tr>
<template slot="items" slot-scope="props">
<tr :active="props.selected" #click="props.selected = !props.selected">
<td class="text-xs-right">{{ props.item.Foo1 }}</td>
<td class="text-xs-right">{{ props.item.Foo2 }}</td>
</tr>
</template>
</thead>
</template>
</v-data-table>
P.S. I was using this page as a starting point in getting the table set up: https://codepen.io/mikecole/pen/zLNKbG
Looks like you want to remove the header row, however you still want keep the sort.
So without adding hide-default-header option and keeping the header text value as empty string, you can keep the sort functionality.
HTML
<v-data-table
#click:row="rowClick"
:headers="headers"
:items="arrangedList"
:search="search"
:items-per-page="10"
class="outlined elevation-0"
>
JS
headers: [
{
text: '',align: 'left', value: 'name'
},
{ text: '', value: 'calories' },
.
.
],

Big gap between Vuetify <v-select> component and its selectable content

Why do I have such a big distance between my select box and it's selectable content ?
I'm using Vuetify in VueJS component in Laravel 7.
<template>
<v-app class="container">
<v-data-table
hide-default-header
hide-default-footer
:headers="headers"
:items="items"
:items-per-page="filter.items_per_page"
#click:row="getData"
no-data-text="No data."
dense
style="background: transparent"
>
<template
v-slot:footer
v-if="items.length"
>
<v-row no-gutters>
<v-col cols="2">
<v-select
:items=[10,50,100]
v-model="filter.items_per_page"
#change="onPageChange(1)"
label="Rows per page"
outlined
dense
></v-select>
</v-col>
</v-row>
</template>
</v-data-table>
</v-app>
</template>
=== EDIT ===
Vuetify variables are loaded as below:
resources/sass/app.scss
#import '~vuetify/dist/vuetify.min.css';
#import '~#mdi/font/css/materialdesignicons.min.css';

Resources