Usng Vuetify v-data-table how to set chip color based and value and item - vuetify.js

I would like to set the chip color for the value of an item in a v-data-table using both the items value and the items id. So i want to set values under 0.5 to red only if the id is "Cl2". ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
[enter image description here][1]
Here's my table and code:
[1]: https://i.stack.imgur.com/Sp8DQ.jpg
<template>
<v-data-table
:headers="headers"
:items="parameters"
class="elevation-1"
hide-default-footer
calculate-widths
dense
>
<template v-slot:top>
<v-toolbar flat color="white">
<v-toolbar-title>Parameter Input {{ scanSite }} </v-toolbar-title>
<v-divider class="mx-4" inset vertical></v-divider>
<v-spacer></v-spacer>
<v-dialog v-model="dialog" persistent>
<v-card
max-width="315px"
max-height="240px"
style="position: absolute; top: 90px; left: 30px; right: 30px;"
>
<v-card-title>
<span class="">{{ editedItem.name }} - Enter/Edit Values </span>
</v-card-title>
<v-card-text class="card-text py-0 my-0">
<v-container>
<v-row class="row py-0">
<v-col cols="5">
<v-text-field
v-model="editedItem.value"
label="Value"
></v-text-field>
</v-col>
<v-col cols="5">
<v-text-field
v-model="editedItem.sid"
label="Save ID"
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text #click="close">Cancel</v-btn>
<v-btn color="blue darken-1" text #click="save">Save</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-toolbar>
</template>
<template v-slot:[`item.actions`]="{ item }">
<v-icon small class="mr-2" #click="editItem(item)">
mdi-pencil
</v-icon>
<v-icon small class="mr-2" #click="addItem(item)">
mdi-plus
</v-icon>
</template>
<template v-slot:[`item.analyse`]="{ item }">
<v-simple-checkbox
color="green"
v-model="item.analyse"
></v-simple-checkbox>
</template>
<template v-slot:[`item.value`]="{ item }">
<v-chip :color="getColor(item.value)" small dark>{{ item.value }}</v-chip>
</template>
</v-data-table>
</template>
<script>
import { mapState } from "vuex";
export default {
data() {
return {
scanSite: "",
dialog: false,
selected: [],
editedItem: {
name: "",
value: 0,
sid: 0
}
};
},
computed: {
...mapState(["scanSite", "headers", "parameters", "sites"])
},
methods: {
editItem(item) {
this.editedIndex = this.parameters.indexOf(item);
this.editedItem = Object.assign({}, item);
this.dialog = true;
},
save() {
Object.assign(this.parameters[this.editedIndex], this.editedItem);
this.dialog = false;
},
close() {
this.dialog = false;
},
getColor(value, id) {
console.log(value, id);
if (value > 0.5 && id == "Cl2") return "red";
else if (value > 10) return "orange";
else return "green";
},
addItem(item) {
this.editedIndex = this.parameters.indexOf(item);
this.editedItem = Object.assign({}, item);
this.parameters.push(this.editedItem);
this.dialog = true;
}
}
};
</script>

I think you need to set both paramareters when you call your getColor() function, like so
<v-chip :color="getColor(item.value, item.id)" small dark>{{ item.value }}</v-chip>
or pass the whole item object and manage it in the getColor() function
<v-chip :color="getColor(item)" small dark>{{ item.value }}</v-chip>
...
getColor(item) {
if (item.value > 0.5 && item.id == "Cl2") return "red";
else if (item.value > 10) return "orange";
else return "green";
},

Related

Draggable table with bootstrap

i would like to make the rows in the table draggable but everything i tried didnt work.
i am realy new to programming and must do the task as soon as possible:)
i am realy thankful for your help`
i read all about b-table documentation in bootstrap but it doesnt say anything about the draggable rows in a table.
<script>
import BaseSafetyModal from '#/components/Base/BaseSafetyModal';
import draggable from "vuedraggable";
export default {
components: {
'safety-modal': BaseSafetyModal,
draggable
},
props: {
fields: {
type: Array,
required: true
},
items: {
type: Array,
required: true
},
approved: {
type: Boolean,
default: false
}
},
methods: {
getModalId (item) {
let name = Object.keys(item).find(
itemKeys =>
itemKeys.indexOf('id') > -1 &&
itemKeys !== 'headline_id' &&
itemKeys !== 'revision_id' &&
itemKeys !== 'building_id'
);
if (
Object.keys(item).indexOf('geometry_id') > -1 &&
Object.keys(item).indexOf('level_id') > -1
)
name = 'level_id';
return `${name}-${item[name]}`;
},
showModal (item) {
this.$root.$emit('bv::show::modal', `safety-modal-${this.getModalId(item)}`);
},
removeItem (item) {
this.$emit('removeItem', item);
this.$root.$emit('bv::hide::modal', `safety-modal-${this.getModalId(item)}`);
}
}
};
</script>
<template>
<div>
<b-row>
<b-col>
<slot name="button1"></slot>
<b-button
v-if="$store.state.permissions.location_permission > 10 && !approved && items.length > 2"
v-b-tooltip.hover
title="Eintrag hinzufügen"
class="float-right"
variant="primary"
#click="$emit('changeMode')"
>
<font-awesome-icon icon="plus"/>
</b-button>
</b-col>
</b-row>
<b-row>
<b-col class="pt-3">
<b-table fixed outlined striped hover stacked="md" :items="items" :fields="fields">
<template v-slot:cell(actions)="row">
<div class="text-md-right float-right">
<b-button-group size="sm">
<slot :item="row.item"></slot>
<b-button
v-b-tooltip.hover
title="Bearbeiten"
v-if="$store.state.permissions.location_permission > 10 && !approved"
type="button"
variant="primary"
#click="$emit('changeMode',row.item)"
>
<font-awesome-icon icon="edit"/>
</b-button>
<b-button
#click="showModal(row.item)"
v-b-tooltip.hover
title="Löschen"
v-if="$store.state.permissions.location_permission > 10 && !approved"
type="button"
variant="danger"
>
<font-awesome-icon icon="trash"/>
</b-button>
<safety-modal
:modal-id="`safety-modal-${getModalId(row.item)}`"
#removeItem="removeItem(row.item)"
></safety-modal>
</b-button-group>
</div>
</template>
</b-table>
</b-col>
</b-row>
<b-row>
<b-col>
<slot name="button2"></slot>
<b-button
v-if="$store.state.permissions.location_permission > 10 && !approved"
v-b-tooltip.hover
title="Eintrag hinzufügen"
class="float-right"
variant="primary"
#click="$emit('changeMode')"
>
<font-awesome-icon icon="plus"/>
</b-button>
</b-col>
</b-row>
</div>
</template>
`
You probably gonna need some drag and drop package, such as SortableJS or vue-smooth-dnd.
Let us now!

vuetify.js how to add type="submit" to Loaders Button

i am new in Vuetify.js im trying to make submit Form using Loaders Button
i tryid but it not worked.
my tryid code
<v-btn
rounded
class="ma-2"
type="submit"
:loading="loading2"
:disabled="loading2"
color="primary"
#click="loader = 'loading2'"
>
Login
<template v-slot:loader>
<span>Loading...</span>
</template>
</v-btn>
my main code
<template>
<v-row justify="center">
<v-col cols="12" sm="6">
<form #submit.prevent="submit">
<v-card ref="form">
<v-card-text>
<h3 class="text-center">Login</h3>
<v-divider class="mt-3"></v-divider>
<v-col cols="12">
<v-img
:src="require('#/assets/1.png')"
class="my-3"
contain
height="80"
/>
</v-col>
<v-col cols="12" sm="12">
<v-text-field
v-model.trim="form.mobile_number"
type="number"
label="Mobile No"
solo
autocomplete="off"
></v-text-field>
<small class="form-text red--text" v-if="errors.mobile_number">{{
errors.mobile_number[0]
}}</small>
</v-col>
<v-col cols="12">
<v-text-field
v-model.trim="form.password"
type="password"
label="Password"
solo
autocomplete="off"
append-icon="mdi-eye"
></v-text-field>
<small class="form-text red--text" v-if="errors.password">{{
errors.password[0]
}}</small>
</v-col>
</v-card-text>
<v-divider class="mt-12"></v-divider>
<v-card-actions>
<div class="text-center">
<v-btn
rounded
color="primary"
dark
to="/AppMain/UserRegisterPage"
nuxt
>Register</v-btn
>
</div>
<v-spacer></v-spacer>
<div class="text-center">
<v-btn
rounded
class="ma-2"
type="submit"
:loading="loading2"
:disabled="loading2"
color="primary"
#click="loader = 'loading2'"
>
Login
<template v-slot:loader>
<span>Loading...</span>
</template>
</v-btn>
<!-- <v-btn rounded type="submit" color="primary" dark>Login</v-btn> -->
</div>
</v-card-actions>
</v-card>
</form>
</v-col>
</v-row>
</template>
<script>
export default {
middleware: ["guest"],
data() {
return {
loader: null,
loading: false,
loading2: false,
loading3: false,
loading4: false,
loading5: false,
form: {
mobile_number: "",
password: "",
},
};
},
watch: {
loader() {
const l = this.loader;
this[l] = !this[l];
setTimeout(() => (this[l] = false), 3000);
this.loader = null;
},
},
methods: {
async submit() {
await this.$auth.loginWith("local", {
data: this.form,
});
this.$router.push("/");
},
},
};
</script>
<style>
.custom-loader {
animation: loader 1s infinite;
display: flex;
}
#-moz-keyframes loader {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
#-webkit-keyframes loader {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
#-o-keyframes loader {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
#keyframes loader {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
</style>
You create and use the variable "loading" but never set it.
For resolve your problem, please, add in your #click method something like
loading = true
....
and then make loading same to false, for stop the loading style of your button.
Good luck!

Vuetify autocomplete with solo selection and toggle "Select All"

Vuetify newbie here.
My goal is to have a v-autocomplete with solo selection of elements, and a toggle for "Select All".
My approach was by modifying 'v-select__slot' and to change its contents, is this the best approach?
Question: I was not succesfull cleaning previous selections, what is the best way to clean previous selected elements?
Question: After the "Select All" change event, how to close the drop-down?
<div id="app">
<v-app id="inspire">
<v-container fluid>
<v-autocomplete v-model="selectedFruits" :items="fruits" solo ref="selector" :readonly="readonly" #change="changed">
<template v-slot:prepend-item>
<v-list-item ripple #click="toggle">
<v-list-item-action>
<v-icon :color="selectedFruits.length > 0 ? 'indigo darken-4' : ''">{{ icon }}</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>Select All</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-divider />
</template>
</v-autocomplete>
</v-container>
<br/>
{{selectedFruits}}
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
fruits: [
'Apples',
'...',
'Zucchini',
],
selectedFruits: [],
readonly: false,
}),
computed: {
likesAllFruit () {
return this.selectedFruits.length === this.fruits.length
},
likesSomeFruit () {
return this.selectedFruits.length > 0 && !this.likesAllFruit
},
icon () {
if (this.likesAllFruit) return 'mdi-close-box'
if (this.likesSomeFruit) return 'mdi-checkbox-blank-outline'
return 'mdi-checkbox-blank-outline'
},
},
methods: {
changed () {
var el = this.$refs.selector.$el.getElementsByClassName('v-select__slot')[0]
// var add_me = document.createTextNode(this.selectedFruits);
// el.appendChild(add_me, null);
},
toggle () {
this.$nextTick(() => {
var backup = this.$refs.selector.$el.getElementsByTagName('input')[0]
var text = ""
if (this.likesAllFruit) {
this.selectedFruits = []
text = "No fruits"
} else {
this.selectedFruits = this.fruits.slice()
text = "All fruits"
}
var el = this.$refs.selector.$el.getElementsByClassName('v-select__slot')[0]
el.textContent = ''
var add_me = document.createTextNode(text);
el.appendChild(add_me, null);
el.appendChild(backup, null);
})
},
},
created() {
}
})
Example:
https://codepen.io/dotmindlabs/pen/JjXbQyo?editors=1010
TIA
For displaying the toggle selection used a v-slot:label.
Regarding the closing of the drop-down after clicking toggle, it can be achieved with :menu-props="{closeOnClick: true,closeOnContentClick:true}"
Example HTML:
<div id="app">
<v-app id="inspire">
<v-container fluid>
<v-autocomplete
v-model="selectedFruits"
:items="fruits"
:menu-props="{ closeOnClick: true, closeOnContentClick: true }"
>
<template v-slot:label>
<div class="indigo--text">{{ label }}</div>
</template>
<template v-slot:selection="{ item, index }">
<span>{{ item }} </span>
</template>
<template v-slot:prepend-item>
<v-list-item
ripple
#click="toggle"
>
<v-list-item-action>
<v-icon :color="selectedFruits.length > 0 ? 'indigo darken-4' : ''">{{ icon }}</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>Select All</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-divider class="mt-2"></v-divider>
</template>
</v-autocomplete>
</v-container>
{{selectedFruits}}
</v-app>
</div>
Javascript
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
fruits: [
'Apples',
'....',
'Zucchini',
],
selectedFruits: [],
}),
computed: {
likesAllFruit () {
return this.selectedFruits.length === this.fruits.length
},
icon () {
if (this.likesAllFruit) return 'mdi-close-box'
if (this.likesSomeFruit) return 'mdi-minus-box'
return 'mdi-checkbox-blank-outline'
},
label (){
if (typeof this.selectedFruits === "string") { return ""}
return this.selectedFruits.length > 0 ? "All Fruit" : ""
}
},
methods: {
toggle () {
if (this.likesAllFruit) {
this.selectedFruits = []
} else {
this.selectedFruits = this.fruits.slice()
}
},
},
created(){
this.selectedFruits = this.fruits.slice()
}
})
Codepen:
https://codepen.io/dotmindlabs/pen/RwapobY?editors=1011

Vee Validate - Sever side validation and front end validation

I have a laravel lumen endpoint which i return errors from. The issue i am facing is that vee validate is not setting the errors?
<template>
<v-container fluid class="ma-0 pa-0">
<v-card route>
<v-card-title class="primary white--text">Create New User</v-card-title>
<v-row align="center" :class="{'px-6': $vuetify.breakpoint.xs, 'pa-8': $vuetify.breakpoint.smAndUp}">
<v-row justify="space-between" v-if="!isCreating">
<v-col cols="12" md="4">
<v-row align="center" justify="center" class="mb-4">
<v-avatar color="primary" size="128">
<v-icon size="48" dark v-if="!userAvatarName()">mdi-account</v-icon>
<span
v-if="userAvatarName()"
class="white--text display-2"
>{{ userAvatarName() }}</span>
</v-avatar>
</v-row>
</v-col>
<v-col>
<ValidationObserver v-slot="{ invalid, validated, passes }" ref="provider">
<v-form #submit.prevent="passes(handleSubmit)">
<v-row >
<v-col class="py-0">
<VTextFieldWithValidation vid="username" rules="required" v-model="newUser['username']" label="Username" />
</v-col>
</v-row>
<v-row >
<v-col class="py-0">
<VTextFieldWithValidation vid="email" rules="required|email" v-model="newUser['email']" label="Email address" />
</v-col>
</v-row>
<v-row >
<v-col class="py-0">
<VTextFieldWithValidation rules="required" v-model="newUser['first_name']" label="First name" />
</v-col>
<v-col class="py-0">
<VTextFieldWithValidation rules="required" v-model="newUser['last_name']" label="Last name" />
</v-col>
</v-row>
<v-row >
<v-col class="py-0 mt-4">
<ValidationProvider name="role" rules="required" v-slot="{ errors, valid }">
<v-select
:error-messages="errors"
:success="valid"
:items="roles"
item-text="name" item-value="value"
label="Role"
outlined
v-model="newUser['role']"
></v-select>
</ValidationProvider>
</v-col>
</v-row>
<v-divider></v-divider>
<v-row >
<v-col class="py-0">
<v-switch
v-model="newUser['send_activation']"
label="Send Activation Email"
></v-switch>
</v-col>
</v-row>
<v-row v-if="!newUser['send_activation']">
<v-col class="py-0">
<ValidationProvider name="password" :rules="!newUser['send_activation'] ? 'required|min:8' : ''" v-slot="{ errors, valid }">
<v-text-field
outlined
counter
:error-messages="errors"
:success="valid"
label="Password"
:append-icon="userPasswordVisibility.password_current_show ? 'mdi-eye' : 'mdi-eye-off'"
:type="userPasswordVisibility.password_current_show ? 'text' : 'password'"
#click:append="userPasswordVisibility.password_current_show = !userPasswordVisibility.password_current_show"
v-model="newUser['password']"
></v-text-field>
</ValidationProvider>
</v-col>
<v-col class="py-0">
<ValidationProvider name="confirmation" :rules="!newUser['send_activation'] ? 'required|password:#password' : ''" v-slot="{ errors, valid }">
<v-text-field
outlined
counter
:error-messages="errors"
:success="valid"
label="Password Confirmation"
:append-icon="userPasswordVisibility.password_new_show ? 'mdi-eye' : 'mdi-eye-off'"
:type="userPasswordVisibility.password_new_show ? 'text' : 'password'"
#click:append="userPasswordVisibility.password_new_show = !userPasswordVisibility.password_new_show"
v-model="newUser['password_confirmation']"
></v-text-field>
</ValidationProvider>
</v-col>
</v-row>
<v-row class="mt-4">
<v-col class="py-0">
<v-btn text color="primary" :to="{ name: 'organisation/users', params: { org_id: organisation.id }}">Cancel</v-btn>
</v-col>
<v-col class="py-0 text-right">
<v-tooltip top>
<template v-slot:activator="{ on }">
<v-btn outlined color="primary" v-on="on" #click="passes(handleSubmit)" :disabled="invalid || !validated">Add New User</v-btn>
</template>
<span>Create new user and add them to <strong>{{organisation.name}}</strong>.</span>
</v-tooltip>
</v-col>
</v-row>
</v-form>
</ValidationObserver>
</v-col>
</v-row>
<v-row align="center" justify="center" v-if="isCreating">
<v-progress-circular
class="ma-5"
indeterminate
color="teal accent-1 darken-2" >
</v-progress-circular>
</v-row>
</v-row>
</v-card>
</v-container>
</template>
<script>
import { mapState } from 'vuex'
import { CREATE_USER } from '#/_apollo/GraphQL/userGraphQL'
import BreadcrumbsManager from '#/_util/breadcrumbManager'
import VTextFieldWithValidation from '#/components/inputs/VTextFieldWithValidation'
import { ValidationProvider, ValidationObserver } from "vee-validate"
export default {
name: 'CreateUser',
mixins: [BreadcrumbsManager],
props: [
'organisation'
],
components: {
ValidationObserver,
ValidationProvider,
VTextFieldWithValidation
},
data() {
return {
userPasswordVisibility: {
password_current_show: false,
password_new_show: false,
password_new_confirm_show: false
},
newUser: {
send_activation: 1
},
roles: [
{ name: 'Admin', value: 'organisation_admin' },
{ name: 'User', value: 'user' }
],
isCreating: false
}
},
computed: {
...mapState({
authUser: state => state.AUTH_STORE.authUser
}),
},
methods: {
userAvatarName() {
let name = '';
if (this.newUser['first_name']) {
name += `${this.newUser['first_name'].charAt(0).toUpperCase()}`
}
if (this.newUser['last_name']) {
name += `${this.newUser['last_name'].charAt(0).toUpperCase()}`
}
if (name !== '') {
return name
}
return false
},
async handleSubmit() {
this.isCreating = true
this.newUser['reseller_id'] = this.authUser.reseller_id
this.newUser['organisation_id'] = parseInt(this.$route.params.org_id)
this.newUser['send_activation'] = this.newUser['send_activation'] ? 1 : 0
var refs = this.$refs.provider
this.$apollo
.mutate({
mutation: CREATE_USER,
variables: this.newUser
})
.then(response => {
this.isCreating = false
const user = response.data.createUser
this.$store.commit('USER_STORE/CREATE_USER', response.data.createUser)
this.$toast.success('Successfully created new user.')
this.$router.push({ name: "organisation/users", params: { org_id: this.$route.params.org_id }}, () => {})
}).catch((error) => {
this.isCreating = false
this.$toast.error(error.graphQLErrors[0].extensions.code.message)
let errors = error.graphQLErrors[0].extensions.code.errors
console.log(errors)
refs.setErrors(errors)
console.log(refs)
})
refs.validate();
}
},
created() {
this.setBreadcrumbs([
{ text: 'Dashboard' , path: '/' },
{ text: 'Organisations' , path: '/organisation/all/' },
{ text: ':organisation' },
{ text: 'Users', path: `/organisation/${this.organisation.org_id}/users/` },
{ text: 'Create' }
])
this.replaceBreadcrumb({
find: ':organisation',
replace: { text: this.organisation.name, path: `/organisation/${this.organisation.org_id}` }
})
}
}
</script>
In the catch error on handle submit i can see the sever errors but my view wont show an error on the field?
I have took inspiration from the following from the docs:
https://codesandbox.io/s/veevalidate-backend-driven-validation-ynrp9?from-embed=&file=/src/App.vue
But to no avail.
Can anyone help?
It turns out apollo client is a promise which isnt resolved so the fix is:
const userResponse = await this.$apollo
.mutate({
mutation: CREATE_USER,
variables: this.newUser
})
.then(response => {
this.isCreating = false
const user = response.data.createUser
this.$store.commit('USER_STORE/CREATE_USER', response.data.createUser)
this.$toast.success('Successfully created new user.')
this.$router.push({ name: "organisation/users", params: { org_id: this.$route.params.org_id }}, () => {})
}).catch((error) => {
this.isCreating = false
this.$toast.error(error.graphQLErrors[0].extensions.code.message)
return error.graphQLErrors[0].extensions.code.errors.detail
})
this.$refs.provider.setErrors(userResponse);

How to wire up external data in Vuetify datatables

I have just started with Vue and found Vuetify ( and very impressed ) . I'm a bit of a newbie with node.js as well but some experience.
I am trying to find some examples on loading data from external API's into the vuetify datagrid - CRUD type stuff, reasonably large amounts of data paginated. The documentation in Vuetify is a little lacking in this regard. Should I be using Vuex?
If you want to call external API using REST, you'll need to use axios, which is a NPM package allowing you to make GET, POST and all that kind.
Let's use this online working API for our example. First, you need to get your data by calling this API. A good tutorial on Internet will show you more details, but let's use this code.
this.todos = axios.get('https://jsonplaceholder.typicode.com/todos/')
.then(response => { this.todos = response.data })
.catch(error => { console.log(error)});
Then you just have to use the datatable like in the documentation. Here is a CodePen to help you see, briefly, how I made the API call and then displayed it. It all comes from the official documentation, just modified to call a REST API. I'll put the code also here, in order to save it for future readers too.
<div id="app">
<v-app id="inspire">
<div>
<v-toolbar flat color="white">
<v-toolbar-title>Todos CRUD</v-toolbar-title>
<v-divider
class="mx-2"
inset
vertical
></v-divider>
<v-spacer></v-spacer>
<v-dialog v-model="dialog" max-width="500px">
<v-btn slot="activator" color="primary" dark class="mb-2">New Item</v-btn>
<v-card>
<v-card-title>
<span class="headline">{{ formTitle }}</span>
</v-card-title>
<v-card-text>
<v-container grid-list-md>
<v-layout wrap>
<v-flex xs12 sm6 md4>
<v-text-field v-model="editedItem.userId" label="User ID"></v-text-field>
</v-flex>
<v-flex xs12 sm6 md4>
<v-text-field v-model="editedItem.id" label="ID"></v-text-field>
</v-flex>
<v-flex xs12 sm6 md4>
<v-text-field v-model="editedItem.title" label="Title"></v-text-field>
</v-flex>
<v-flex xs12 sm6 md4>
<v-checkbox v-model="editedItem.completed" label="Completed?"></v-checkbox>
</v-flex>
</v-layout>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" flat #click="close">Cancel</v-btn>
<v-btn color="blue darken-1" flat #click="save">Save</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-toolbar>
<v-data-table
:headers="headers"
:items="todos"
class="elevation-1"
>
<template slot="items" slot-scope="props">
<td class="text-xs-right">{{ props.item.userId }}</td>
<td class="text-xs-right">{{ props.item.id }}</td>
<td class="text-xs-right">{{ props.item.title }}</td>
<td class="text-xs-right">{{ props.item.completed }}</td>
<td class="justify-center layout px-0">
<v-icon
small
class="mr-2"
#click="editItem(props.item)"
>
edit
</v-icon>
<v-icon
small
#click="deleteItem(props.item)"
>
delete
</v-icon>
</td>
</template>
<template slot="no-data">
<v-btn color="primary" #click="initialize">Reset</v-btn>
</template>
</v-data-table>
</div>
</v-app>
</div>
And then the associated JS.
new Vue({
el: '#app',
data: () => ({
dialog: false,
headers: [
{
text: 'User ID',
align: 'left',
sortable: false,
value: 'userId',
width: '10'
},
{ text: 'ID', value: 'id', width: '10' },
{ text: 'Title', value: 'title' },
{ text: 'Completed', value: 'completed' }
],
todos: [],
editedIndex: -1,
editedItem: {
userId: 0,
id: 0,
title: '',
completed: false
},
defaultItem: {
userId: 0,
id: 0,
title: '',
completed: false
}
}),
computed: {
formTitle () {
return this.editedIndex === -1 ? 'New Item' : 'Edit Item'
}
},
watch: {
dialog (val) {
val || this.close()
}
},
created () {
this.initialize()
},
methods: {
initialize () {
this.todos = axios.get('https://jsonplaceholder.typicode.com/todos/')
.then(response => { this.todos = response.data })
.catch(error => { console.log(error)});
},
editItem (item) {
this.editedIndex = this.todos.indexOf(item)
this.editedItem = Object.assign({}, item)
this.dialog = true
},
deleteItem (item) {
const index = this.todos.indexOf(item)
confirm('Are you sure you want to delete this item?') && this.todos.splice(index, 1)
},
close () {
this.dialog = false
setTimeout(() => {
this.editedItem = Object.assign({}, this.defaultItem)
this.editedIndex = -1
}, 300)
},
save () {
if (this.editedIndex > -1) {
Object.assign(this.todos[this.editedIndex], this.editedItem)
} else {
this.todos.push(this.editedItem)
}
this.close()
}
}
})

Resources