I have a vuetify data table, I've set width for every column and I want to fixed column's width of my table but it has grown up because of their content and it doesn't matter what is the width of them.
how can fixed column's width?
<template>
<v-data-table
v-if="physicianAccountsLocalData"
:headers="headers"
:items="physicianAccountsLocalData"
hide-default-footer
class="data-table"
:items-per-page="-1"
>
<template #[`item.isActive`]="props">
<BaseSwitch
v-model="props.item.isActive"
class="switch-siam-table"
#change="changeModel($event, props)"
/>
</template>
<template #[`item.location`]="props">
<span
class="location"
:class="{'text-disable-state': !props.item.isActive}"
>
{{ props.item.location }}
</span>
</template>
<template #[`item.name`]="props">
<span
class="name"
:class="{'text-disable-state': !props.item.isActive}"
>
{{ props.item.name }}
</span>
</template>
</v-data-table>
</template>
<script>
data() {
return {
headers: [
{ text: 'فعال', value: 'isActive', sortable: false, width: '110px', align: 'right' },
{ text: 'نوع', value: 'location', sortable: false, width: '13%', align: 'start' },
{ text: 'نام', value: 'name', sortable: false, width: '200px' }
],
}
}
</script>
Related
I have a problem with an array that is undefined while in Vuejs devTool I see it full. Here is what I did with quasar:
When i click on my update button i want to display a q-card with input of my row. So i have make a request with axios and put response in array. But i have 'undefined' when i do a console.log() of my array.
<template>
<div>
<div class="q-pa-sm q-gutter-sm">
<q-dialog v-model="show_dialog" v-bind:programmeEdit="programmeEdit">
<q-card>
<q-card-section>
<div class="text-h6">Add new item!</div>
</q-card-section>
<q-card-section>
<div class="row">
<q-input v-model="programmeEdit.prg_libelle" label="prg_libelle"></q-input>
<q-input label="id"></q-input>
<q-input label="nom promotteur"></q-input>
<q-input label="date commercialistion"></q-input>
<q-input label="stock initial"></q-input>
<q-input label="nombre tranche"></q-input>
</div>
</q-card-section>
<q-card-actions align="right">
<q-btn flat label="OK" color="primary" v-close-popup #click="" ></q-btn>
</q-card-actions>
</q-card>
</q-dialog>
</div>
<q-table title="Programme" :filter="filter" :data="programme.data" :columns="columns" row-key="name">
<template v-slot:top-right>
<q-input borderless dense debounce="300" v-model="filter" placeholder="Search">
<template v-slot:append>
<q-icon name="search" />
</template>
</q-input>
</template>
<template v-slot:body="props">
<q-tr :props="props">
<q-td key="prg_libelle" :props="props">{{ props.row.prg_libelle }}</q-td>
<q-td key="id" :props="props">{{ props.row.id }}</q-td>
<q-td key="nom_promotteur" :props="props">{{ props.row.act_libelle }}</q-td>
<q-td key="id_promotteur" :props="props">{{ props.row.id_promotteur }}</q-td>
<q-td key="date_commercialisation" :props="props">{{ props.row.tra_date_commercialisation }}</q-td>
<q-td key="stock_initial" :props="props">{{ props.row.tra_stock_initial }}</q-td>
<q-td key="nombre_tranche" :props="props">{{ props.row.nombre_tranche }}</q-td>
<q-td key="actions" :props="props">
<q-btn color="blue" label="Update" #click="getProgramme(props.row.id)" size=sm no-caps></q-btn>
<q-btn color="red" label="Delete" #click="deleteItem(props.row)" size=sm no-caps></q-btn>
</q-td>
</q-tr>
</template>
</q-table>
</div>
</template>
Vue.use(VueAxios, axios)
export default {
methods: {
},
data () {
return {
programmetoEdit:'',
show_dialog:false,
filter: '',
programme:{},
programmeEdit:{},
columns: [
{
name: 'prg_libelle',required: true, label: 'prg_libelle',align: 'left', field: 'prg_libelle' ,format: val => `${val}`, sortable: true },
{ name: 'id', align: 'center', label: 'id', field: 'id', sortable: true },
{ name: 'nom_promotteur', align: 'center',label: 'nom_promotteur', field: 'act_libelle', },
{ name: 'id_promotteur', align: 'center',label: 'id_promotteur', field: 'id_promotteur', },
{ name: 'date_commercialisation', align: 'center',label: 'date_commercialisation', field: 'tra_date_commercialisation', },
{ name: 'stock_initial', align: 'center',label: 'stock_initial', field: 'tra_stock_initial', },
{ name: 'nombre_tranche', align: 'center',label: 'nombre_tranche', field: 'nombre_tranche', },
{ name: "actions", label: "Actions", field: "actions"},
]
}
},
created() {
axios.get("http://localhost:80/api/programme")
.then(response =>this.programme=response)
.catch(error=>console.log(error))
},
methods: {
getProgramme($id){
axios.get("http://localhost:80/api/programme/"+$id)
.then(response => this.programmeEdit=response.data);
this.show_dialog= !this.show_dialog;
this.programmeEdit.id=this.programmetoEdit;
}
},
}
I get an undefined when I want to retrieve the query according to the id. I'm blocking and I don't know why.
thanks a lot :)
If you want to log it from your code (like in the .then promise, for example) you should do:
console.log(this.programmetoEdit);
Moreover, you are doing assignment in parallel of the job Axios is doing. Not after, as I guess you are expecting it to do.
You should drop all your stuff in the .then promise if you want it to happen after the this.programmeEdit=response.data part.
Like so (this will show the dialog WHILE loading the data/waiting for the API to respond):
getProgramme ($id) {
axios.get("http://localhost:80/api/programme/" + $id)
.then(response => {
this.programmeEdit=response.data;
this.programmeEdit.id=this.programmetoEdit;
});
this.show_dialog= !this.show_dialog;
}
Or like so (this will show the dialog AFTER loading the data/waiting for the API to respond):
getProgramme ($id) {
axios.get("http://localhost:80/api/programme/" + $id)
.then(response => {
this.programmeEdit=response.data;
this.programmeEdit.id=this.programmetoEdit;
this.show_dialog= !this.show_dialog;
});
}
i want to show a image in vuetify data table row. i tried this with below code.
<v-data-table :headers="headers" :items="desserts" :search="search" class="elevation-1">
<template slot="items" slot-scope="props">
<td>
<img :src="'/assets/img/' + props.item.name" style="width: 50px; height: 50px" />
</td>
<td class="text-xs-right">{{ props.item.calories }}</td>
<td class="text-xs-right">{{ props.item.fat }}</td>
<td class="text-xs-right">{{ props.item.carbs }}</td>
<td class="text-xs-right">{{ props.item.protein }}</td>
<td class="text-xs-right">{{ props.item.iron }}</td>
</template>
<template v-slot:item.action="{ item }">
<v-icon small class="mr-2" #click="editItem(item)">edit</v-icon>
<v-icon small #click="deleteItem(item)">delete</v-icon>
</template>
</v-data-table>
but this code not works properly. only shows data with v-data-table loop and template slot not working. my script like this.
search: "",
headers: [
{
text: "Images",
align: "left",
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" },
{ text: "Actions", value: "action", sortable: false }
],
desserts: [
{
value: false,
name: "notfound.png",
calories: 159,
fat: 6.0,
carbs: 24,
protein: 4.0,
iron: "1%"
}],
how can i show my image. this method only shows image text name only.
Presuming you use the last version of vuetify, the slots are working a little bit different, and you can define a slot only for the column you want to customize. (order is defined by the headers)
<div id="app">
<v-data-table :headers="headers" :items="desserts" class="elevation-1">
<template v-slot:item.name="{ item }">
<img :src="'/assets/img/' + item.name" style="width: 50px; height: 50px" />
</template>
<template v-slot:item.action="{ item }">
<v-icon small class="mr-2" #click="editItem(item)">edit</v-icon>
<v-icon small #click="deleteItem(item)">delete</v-icon>
</template>
</v-data-table>
</div>
I have an assignment that uses Vuetify and I want to render a table of "customer" data. My code worked fine with Vuetify 1.5, but now I am supposed to update to the newest version, which is 2.0.
The problem I'm running into is that my data is recognized by the program, but none of it actually shows up in the table. The exact number of rows are rendered to match my number of records, and Vue DevTools shows that my data is there, but The rendered html is just empty elements. I attached screenshots below to illustrate my point a little better:
The project can be found at: https://github.com/apalmesano2/assign3_frontend.git
Here is a snippet of what my Vue template for the list of customers:
CustomerList.vue
<template>
<main>
<br />
<v-container fluid grid-list-md>
<v-layout column align-left>
<blockquote>
Welcome {{validUserName}}!
<footer>
<small>
<em>—Eagle Financial Services, your Midwest Financial Services Partner.</em>
</small>
</footer>
</blockquote>
</v-layout>
<v-layout column align-center>
<v-flex xs6 sm8 md7>
<v-alert
v-if="showMsg === 'new'"
dismissible
:value="true"
type="success"
>New customer has been added.</v-alert>
<v-alert
v-if="showMsg === 'update'"
dismissible
:value="true"
type="success"
>Customer information has been updated.</v-alert>
<v-alert
v-if="showMsg === 'deleted'"
dismissible
:value="true"
type="success"
>Selected Customer has been deleted.</v-alert>
</v-flex>
</v-layout>
<br />
<v-container fluid grid-list-md fill-height>
<v-layout column>
<v-flex md6>
<v-data-table
:headers="headers"
:items="customers"
hide-default-footer
class="elevation-1"
fixed
style="max-height: 300px; overflow-y: auto"
>
<template slot="items" slot-scope="props">
<td>{{ props.item.pk }}</td>
<td>{{ props.item.cust_number }}</td>
<td>{{ props.item.name }}</td>
<td nowrap="true">{{ props.item.address }}</td>
<td nowrap="true">{{ props.item.city }}</td>
<td nowrap="true">{{ props.item.state }}</td>
<td nowrap="true">{{ props.item.zipcode }}</td>
<td nowrap="true">{{ props.item.email }}</td>
<td nowrap="true">{{ props.item.cell_phone }}</td>
<td nowrap="true">
<v-icon #click="updateCustomer(props.item)">edit</v-icon>
</td>
<td nowrap="true">
<v-icon #click="deleteCustomer(props.item)">delete</v-icon>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
</v-container>
<v-btn class="blue white--text" #click="addNewCustomer">Add Customer</v-btn>
</v-container>
</main>
</template>
And the script, although I don't think there is an issue here because the data is being fetched just fine according to the Vue DevTools:
<script>
import router from "../router";
import { APIService } from "../http/APIService";
const apiService = new APIService();
export default {
name: "CustomerList",
data: () => ({
customers: [],
validUserName: "Guest",
customerSize: 0,
showMsg: "",
headers: [
{ text: "Record Number", sortable: false, align: "left" },
{ text: "Customer Number", align: "left", sortable: false },
{ text: "Name", sortable: false, align: "left" },
{ text: "Address", sortable: false, align: "left" },
{ text: "City", sortable: false, align: "left" },
{ text: "State", sortable: false, align: "left" },
{ text: "ZipCode", sortable: false, align: "left" },
{ text: "Email", sortable: false, align: "left" },
{ text: "Phone", sortable: false, align: "left" },
{ text: "Update", sortable: false, align: "left" },
{ text: "Delete", sortable: false, align: "left" }
]
}),
mounted() {
this.getCustomers();
this.showMessages();
},
methods: {
showMessages() {
console.log(this.$route.params.msg);
if (this.$route.params.msg) {
this.showMsg = this.$route.params.msg;
}
},
getCustomers() {
apiService
.getCustomerList()
.then(response => {
this.customers = response.data.data;
this.customerSize = this.customers.length;
if (
localStorage.getItem("isAuthenticates") &&
JSON.parse(localStorage.getItem("isAuthenticates")) === true
) {
this.validUserName = JSON.parse(localStorage.getItem("log_user"));
}
})
.catch(error => {
if (error.response.status === 401) {
localStorage.removeItem("isAuthenticates");
localStorage.removeItem("log_user");
localStorage.removeItem("token");
router.push("/auth");
}
});
},
addNewCustomer() {
if (
localStorage.getItem("isAuthenticates") &&
JSON.parse(localStorage.getItem("isAuthenticates")) === true
) {
router.push("/customer-create");
} else {
router.push("/auth");
}
},
updateCustomer(customer) {
router.push("/customer-create/" + customer.pk);
},
deleteCustomer(customer) {
apiService
.deleteCustomer(customer.pk)
.then(response => {
if (response.status === 204) {
alert("Customer deleted");
this.showMsg = "deleted";
this.$router.go();
}
})
.catch(error => {
if (error.response.status === 401) {
localStorage.removeItem("isAuthenticates");
localStorage.removeItem("log_user");
localStorage.removeItem("token");
router.push("/auth");
}
});
}
}
};
</script>
I have a hunch I'm doing something wrong with my v-data-table and the template where I'm passing the props in but I can't figure out what's going wrong or how to fix it because even just hardcoded text in the tags won't render in the table.
To access the page where the screenshots are after cloning the project, you would need to log in with the following credentials:
Username: instructor
Password: instructor1a
Thanks to anyone who can help!
I figured out the new syntax after moving to vuetify v2:
<v-data-table
:headers="headers"
:items="stocks"
hide-default-footer
class="elevation-1"
fixed
style="max-height: 300px; overflow-y: auto"
>
<template v-slot:item="props">
<tr>
<td>{{ props.item.customer }}</td>
<td nowrap="true">{{ props.item.symbol }}</td>
<td nowrap="true">{{ props.item.name }}</td>
<td nowrap="true">{{ props.item.shares }}</td>
<td nowrap="true">{{ props.item.purchase_price }}</td>
<td nowrap="true">{{ props.item.purchase_date }}</td>
<td nowrap="true">
<v-icon #click="updateStock(props.item)">edit</v-icon>
</td>
<td nowrap="true">
<v-icon #click="deleteStock(props.item)">delete</v-icon>
</td>
</tr>
</template>
</v-data-table>
I encountered some troubles creating an accordion table. I created an Accordion component and a Table component. While independant from each other it works perfectly fine but I can't get any table appear into accordion.
//js part of accordion component
import Table from "../Table/index.vue"
export default {
name: 'accordion',
components: { Table },
mounted () {
},
data(){
return {
items: [
{ id: "mc", title: "Medical Checkup", text: this.components.Table },
{ id: "ac", title: "Application connected", text:
this.components.Table },
{ id: "p", title: "Programs", text: this.components.Table },
{ id: "pl", title: "Pain list", text: this.components.Table }
]
}
}
}
//html part of accordion component
<div>
<div ref="list" class="list">
<transition-group class="flip-list" name="flip-list" ref="tg1"
tag="div">
<div v-for="(item,index) in items" :key="item.id" class="item">
<slot name="item" :class="{active:item.isOpen}" :item="item"
:index="index">
<v-expansion-panel id="exp1">
<v-expansion-panel-content>
<div slot="header" class="drop-target handle2">
<span>{{item.title}}</span>
</div>
<v-card>
<v-card-text>
<div slot="item">{{Table}}</div>
</v-card-text>
</v-card>
</v-expansion-panel-content>
</v-expansion-panel>
</slot>
</div>
</transition-group>
</div>
</div>
So, the point is : how can I make it so that a datatable appears into accordion ? Like when you click aon one of the titles and it appears instead of some text ?
Thanks a lot
Resolved!
In case of (if people encounter the same problem as I had), here is the code (html / js).
//html goes here
<div id="app">
<v-app id="inspire">
<v-data-table :headers="mainHeaders"
:items="mainItems"
item-key="title"
hide-actions
expand
class="elevation-1">
<template slot="items" scope="props">
<tr #click="props.expanded = !props.expanded">
<td class="text-xs">{{ props.item.title }}</td>
</tr>
</template>
<template slot="expand" scope="props">
<v-data-table :headers="subHeaders"
:items="subItems"
item-key="pain"
hide-actions
class="elevation-10">
<template slot="items" scope="props">
<td class="text-xs">{{ props.item.pain }}</td>
<td class="text-xs">{{ props.item.type }}</td>
</template>
</v-data-table>
</template>
</v-data-table> </v-app>
</div>
//js goes here
export default {
name: 'accordion-table',
mounted () {
},
data () {
return {
mainHeaders: [
{ text: 'Medical informations', value: 'title' }
],
mainItems: [
{ title: 'Medical Checkup' },
{ title: 'Application connected' },
{ title: 'Programs' },
{ title: 'Pain List' }
],
subHeaders: [
{ text: 'Pain', value: 'pain' },
{ text: 'Type', value: 'type' }
],
subItems: [
{ pain: 'Knee', type: '1' },
{ pain: 'Ankle', type: '2' },
{ pain: 'Back', type: '3' },
{ pain: 'Neck', type: '4' }
]
}
}
}
(I used random values)
Hope it helps some of you
I am working with Bootstrap Vue JS table component to create a datatable:
https://bootstrap-vue.js.org/docs/components/table
I am new to VueJS and am uncertain on how to approach this problem which makes searching for a solution even more complicated.
I use an API endpoint to return JSON data:
{
"options":{
"filter":false
},
"fields":[
{
"key":"id",
"label":"Id",
"editLink":false,
"display":true,
"sortable":true,
"class":"shrink"
},
{
"key":"name",
"label":"Name",
"editLink":true,
"display":true,
"sortable":true
}
],
"data":[ ]
}
Here is my table template:
<b-table striped hover bordered foot-clone class="table-sm"
:items="users" :fields="displayedFields" :per-page="perPage" :current-page="currentPage" :filter="filter"
#filtered="onFiltered"
>
<template v-for="(field, index) in fields">
<template slot="{{field.key}}" slot-scope="row" v-if="field.editLink">
<router-link :to="'/user/' + row.item.id" v-bind:key="index"></router-link>
</template>
</template>
<template slot="status" slot-scope="row">
<toggle-button :width="36" :height="18" v-model="row.status" :labels="false" :colors="{checked: '#00FF00', unchecked: '#FF0000', disabled: '#CCCCCC'}"/>
</template>
</b-table>
The first template tag is an attempt from a wild guess. I want to be able to conditionally select a table for a column from the fields config. You can see in my attempt that I want to put a RouterLink when the field's config editLink is true.
How can I get this done?
If you're using version 2.0.0 or newer of bootstrap-vue you need to change the slot names as
they've changed, and the old vue slot has also been deprecated in favor for v-slot.
I changed the accepted answers fiddle to work with the new naming and v-slot
new Vue({
el: "#app",
data: {
fields: [{
key: "id",
label: "Id",
colType: "span"
}, {
key: "name",
label: "Name",
colType: "button"
}, {
key: "uhh",
label: "uhh..",
colType: "idk"
}],
items: [{
id: 0,
name: "Test 0"
}, {
id: 1,
name: "Test 1"
}, {
id: 2,
name: "Test 2"
}]
}
});
<link href="https://unpkg.com/bootstrap#4.3.1/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/bootstrap-vue#2.0.0/dist/bootstrap-vue.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue#2.0.0/dist/bootstrap-vue.js"></script>
<div id="app">
<b-table :items="items" :fields="fields">
<template v-for="(field, index) in fields" v-slot:[`cell(${field.key})`]="data">
<div v-if="field.colType === 'button'">
<h5>{{data.item.name}}</h5>
<b-button>Am Button</b-button>
</div>
<div v-else-if="field.colType === 'span'">
<h5>{{data.item.name}}</h5>
<span>Am Span</span>
</div>
<div v-else>
<h5>{{data.item.name}}</h5>
Am Confused
</div>
</template>
</b-table>
</div>
Here's a jsfiddle showing dynamic columns with a b-table:
https://jsfiddle.net/nardnob/wvk6fxgt/
new Vue({
el: "#app",
data: {
fields: [{
key: "id",
label: "Id",
colType: "span"
}, {
key: "name",
label: "Name",
colType: "button"
}, {
key: "uhh",
label: "uhh..",
colType: "idk"
}],
items: [{
id: 0,
name: "Test 0"
}, {
id: 1,
name: "Test 1"
}, {
id: 2,
name: "Test 2"
}]
}
});
<div id="app">
<b-table :items="items" :fields="fields">
<template v-for="(field, index) in fields" :slot="field.key" slot-scope="data">
<div v-if="field.colType === 'button'">
<h5>{{data.item.name}}</h5>
<b-button>Am Button</b-button>
</div>
<div v-else-if="field.colType === 'span'">
<h5>{{data.item.name}}</h5>
<span>Am Span</span>
</div>
<div v-else>
<h5>{{data.item.name}}</h5>
Am Confused
</div>
</template>
</b-table>
</div>