vuetify show-select in data-table not selecting items - vuetify.js

So, I upgraded from vuetify 1.5 to latest (2.1xx) and get stuck on a few places.
I have a data-table where I want a "select all" checkbox in the header.
I added it with the "show-select" property and what I can see is that as the checkbox, when checked, actually puts all the items in the "selected" v-model.
My problem is that I want to have a template for item-props to customize the appearance of the rows and the checkbox that I bind to "props.selected" does not seem to work. If I check any checkbox on any row the item is not added to my "selected" v-model.
It is only if I use no template at all that I get it to work with the auto-generated checkboxes but this does not suffice for my current demands. In vuetify 1.5 I got it to work but I don't understand how to make it work in the new version.
<template>
<div>
<v-data-table
hide-default-footer
v-model="selected"
:sort-desc.sync="sortDescending"
:sort-by.sync="sortBy"
:headers="headers"
:items="cases"
item-key="id"
show-select
:items-per-page="itemsPerPage"
class="elevation-0">
<template v-slot:item="props">
<tr>
<td>
<v-checkbox v-model="props.selected" color="nordnetBlue" hide-details ></v-checkbox>
</td>
<td class="navigation-link" #click="goToCase(props.item)">{{ concatText( props.item.subject, 20) }}</td>
<td>{{ props.item.createdOn }}</td>
<td>{{ props.item.source }}</td>
<td>{{ !props.item.isSameQueue ? props.item.queueName : '' }}</td>
</tr>
</template>
</v-data-table>
<pre class="green--text">{{selected}}</pre>
</div>
</template>

I could not solve this so I followed a vuetify documentation example of how to customize the slot for each particular column.
So in my case, as you can see. three of the columns I just display the text as is and for two of them I do some modifying. So, I used a template for the two ones I wanted to edit.
Example:
template v-slot:item.Name="{ item }">
{{ item.Name }}
<v-tooltip bottom>
<template v-slot:activator="{on}">
<v-icon #click="openCustomer(item.Id)" class="clickable" small color="nordnetBlue" v-on="on">launch</v-icon>
</template>
Open in new window
</v-tooltip>
</template>

Related

How to control expandable v-data-table expand icon's position?

From vuetify'e example, the icon shows up at right side of each row.
But when I making my own, the arrow showed up at the left side, I havent figured out how to control its position.
My code is like following
<v-data-table
:headers="headers"
:items="inputs"
item-key="id"
disable-pagination
dense
show-expand
single-expand
hide-default-footer
>
<template v-slot:[`item.value`]="{ item }">
<v-progress-linear
height="22"
></v-progress-linear
>
</template>
<template v-slot:expanded-item="{headers, item}">
<td :colspan="headers.length">
<InputDetails
:input="item"
/>
</td>
</template>
</v-data-table>
Added one more header into header list did the magic. { text: '', value: 'data-table-expand' },

How to edit the group-by headers of Vuetify <v-data-table>?

How to edit the group-by headers of Vuetify <v-data-table> ?
I need to hide the cross and set a custom title.
<v-data-table
:headers="headers"
:items="items"
group-by="category"
></v-data-table>
You just need to override default group.header slot.
<v-data-table
:headers="headers"
:items="items"
group-by="category"
>
<template v-slot:group.header="{items, isOpen, toggle}">
<td :colspan="headers.length">
<v-icon #click="toggle">
{{ isOpen ? 'mdi-minus' : 'mdi-plus' }}
</v-icon>
<span>Your custom header w/o cross</span>
</td>
</template>
</v-data-table>
Check vuetify docs in Slots category to get full list of available props in this slot.

How can I get the cell selected in a Vuetify Datatable?

I know that I can get the row selected using the event "click:row" in my Datatable component, but I need to get the specific cell that I had clicked
You can use slots for that. Add it inside of your table component like given below:
<template v-slot:item.name="{ item }">
<div #click="rowClicked(item)">
<v-icon
class="mr-2"
color="#54a1e0"
large
>{{ "mdi-folder" }}
</v-icon>
{{ item.name }}
</div>
</template>
Here, you call a "rowClicked" method and you pass the clicked item when there is a click on "name" field that you also customise within the template.

Vuetify v-data-table showing error in props.item with nested JSON

Here's the error
TypeError: Cannot read property 'name' of undefined
at Object.fn [as items] (app.js:74266)...
Hi guys I'm working on a UsersVue component and recently updated to Vuetify and I'm getting the Users API from a Laravel backend from this controller. Any help or suggestions are appreciated, thanks.
UsersController.php
public function index()
{
//With data from ROLES table
$users = User::with('role:role_id,name')->orderBy('id','asc')->get();
return response()->json($users);
}
The props.item.role.name is showing properly and the add/update functionality are also working except the errors showing after I updated a user
Users.vue
<template>
<v-data-table
:headers="headers"
:items="myUsers"
:search="search"
:loading="isLoading"
class="elevation-1"
>
<v-progress-linear slot="progress" color="blue" indeterminate></v-progress-linear>
<template slot="items" slot-scope="props">
<td class="text-md-left pt-3">{{ props.item.name }}</td>
<td class="text-md-left pt-3">{{ props.item.email }}</td>
-----------------------------------------------------------------------
**<td class="text-md-left pt-3">{{ props.item.role.name }}</td>**
-----------------------------------------------------------------------
<td class="justify-content-left layout">
<v-btn icon #click.prevent="editUser(props.item)">
<v-icon color="blue">edit</v-icon>
</v-btn>
<v-btn icon #click.prevent="deleteUser(props.item)" :disabled="props.item.name === 'admin'">
<v-icon color="pink">delete</v-icon>
</v-btn>
</td>
</template>
<v-alert slot="no-results" :value="true" color="error" icon="warning">
Your search for "{{ search }}" found no results.
</v-alert>
<template slot="no-data">
<v-btn color="primary" href="/dashboard/users" >Reset</v-btn>
</template>
</v-data-table>
</template>
[Edited] VueDevTools view
myUsers.role.name has value showing ''student'' string in the v-data-table. The props.item.role.name is really the source of the errors which doesn't occur when I omitted it or changed it to a non-nested JSON like props.item.role_id.
[VueDevTools View - JSON]1
[VueDevTools View - Error]2
It's telling that in your :items="myUsers" there is no role.name.
So when when you try to do {{ props.item.role.name }} it's poping you an error.
Look in myUsers, when you're having the error, with VueDevTool for example, it should miss role.name.
Find a way to add it, or remove that line, and datatable will be ok.
I finally fixed my problem here. There are 2 reasons why I got the error. One in the backend (Laravel) and one in the Frontend (Vue.js).
Backend
My User and Role has One to many relationship so by using this fixed my update/edit of roles (this alone solved my problem)
$user->roles()->sync(values);
Frontend
Additionally for the minor problem, the Errors exist in updating/editing the v-data-table because I'm using
Object.assign({},obj);
which I discovered is only suited for shallow copying of objects and fail when data are updated for the deep properties inside the object. Which obviously didn't reach props.item.role.name. By using this I coped with errors
JSON.parse(JSON.stringify(obj));

How to populate the v-data-table after an AJAX request to fetch the data using Vuetify in Laravel?

Using VueJS with Vuetify and in Laravel framework. Many different methods of AJAX and defining components were tried but nothing worked. It seems that when the ajax call is made, the variable is updated, which I checked in the console.log, but it is not reflected in the DOM.
My current code is as follows
Method 1
In the home.blade.php
<div id="items-display-table">
#{{itemslist}}
<v-data-table
:items="itemslist"
class="elevation-1"
hide-actions
hide-headers
>
<template slot="items" slot-scope="props">
<td>#{{ props.item.name }}</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>
</v-data-table>
</div>
And in the app.js
var itemsDisplayTable = new Vue({
el: '#items-display-table',
data: {
itemslist: []
},
created: function () {
this.fetchData();
},
methods: {
fetchData: function () {
var self = this;
var apiURL = '/api/cards';
axios.get( apiURL )
.then ( function( response ) {
data = response['data'];
// console.log(data);
self.itemslist = data;
console.log(self._data);
});
}
}
});
Method 2
Alternatively, I have also tried building a component with the data passed as a prop to solve the reactive issue but still it doesn't work.
The code for that is as follows in home.blade.php
<div id="cards-display-table">
<grid
:itemslist="itemslist">
</grid>
</div>
In app.js
Vue.component('grid', require('./components/DataTable.vue'));
And the instance creation is same as above.
The code in the DataTable.vue file is as follows
<template>
<div>{{itemslist}}</div>
<v-data-table
:items="itemslist"
class="elevation-1"
hide-actions
hide-headers
>
<template slot="items" slot-scope="props">
<td>#{{ props.item.name }}</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>
</v-data-table>
</template>
<script>
export default {
props: {
itemslist: Array
}
}
</script>
How should i proceed?
I found a solution to my question. It was a pretty silly mistake. So just in case, anyone faces it again, I have decided to answer it.
The problem was that I was registering a new root component to display the items in the app.js file. And it is clearly mentioned that for the Vuetify components to work, they must be wrapped in the <v-app>. So I put the components in a single file and now it is working perfectly.

Resources