Skip to content

Instantly share code, notes, and snippets.

@Teguh010
Created November 1, 2019 06:10
Show Gist options
  • Save Teguh010/f62c479fed2b4d11a2e5beab4e6a9709 to your computer and use it in GitHub Desktop.
Save Teguh010/f62c479fed2b4d11a2e5beab4e6a9709 to your computer and use it in GitHub Desktop.
Crud Table Editing Quasar
<!--
Forked from:
https://quasar.dev/vue-components/table#Example--Popup-editing
-->
<div id="q-app">
<div class="q-pa-sm q-gutter-sm">
<q-table title="Treats" :data="data" :columns="columns" row-key="name" binary-state-sort>
<template v-slot:top>
<q-btn flat outline dense color="primary" label="Add row" @click="show_dialog = true" ></q-btn>
<div class="q-pa-sm q-gutter-sm">
<q-dialog v-model="show_dialog">
<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="editedItem.name" label="Dessert Name"></q-input>
<q-input v-model="editedItem.calories" label="Calories"></q-input>
<q-input v-model="editedItem.fat" label="Fat"></q-input>
<q-input v-model="editedItem.carbs" label="Carbs"></q-input>
<q-input v-model="editedItem.protein" label="Protein"></q-input>
<q-input v-model="editedItem.sodium" label="Sodium"></q-input>
<q-input v-model="editedItem.calcium" label="Calcium"></q-input>
<q-input v-model="editedItem.iron" label="Iron"></q-input>
</div>
</q-card-section>
<q-card-actions align="right">
<q-btn flat label="OK" color="primary" v-close-popup @click="addRow" ></q-btn>
</q-card-actions>
</q-dialog>
</div>
</template>
<template v-slot:body="props">
<q-tr :props="props">
<q-td key="desc" :props="props">
{{ props.row.name }}
<q-popup-edit v-model="props.row.name">
<q-input v-model="props.row.name" dense autofocus counter ></q-input>
</q-popup-edit>
</q-td>
<q-td key="calories" :props="props">
{{ props.row.calories }}
<q-popup-edit v-model="props.row.calories" title="Update calories" buttons>
<q-input type="number" v-model="props.row.calories" dense autofocus ></q-input>
</q-popup-edit>
</q-td>
<q-td key="fat" :props="props">
<div class="text-pre-wrap">{{ props.row.fat }}</div>
<q-popup-edit v-model="props.row.fat">
<q-input type="textarea" v-model="props.row.fat" dense autofocus ></q-input>
</q-popup-edit>
</q-td>
<q-td key="carbs" :props="props">
{{ props.row.carbs }}
<q-popup-edit v-model="props.row.carbs" title="Update carbs" buttons persistent>
<q-input type="number" v-model="props.row.carbs" dense autofocus hint="Use buttons to close" ></q-input>
</q-popup-edit>
</q-td>
<q-td key="protein" :props="props">{{ props.row.protein }}</q-td>
<q-td key="sodium" :props="props">{{ props.row.sodium }}</q-td>
<q-td key="calcium" :props="props">{{ props.row.calcium }}</q-td>
<q-td key="iron" :props="props">{{ props.row.iron }}</q-td>
<q-td key="actions" :props="props">
<q-btn color="blue" label="update" @click="editItem(props.row)" size=sm></q-btn>
<q-btn color="red" label="delete" @click="deleteItem(props.row)" size=sm></q-btn>
</q-td>
</q-tr>
</template>
</q-table>
</div>
</div>
new Vue({
el: "#q-app",
methods: {
addRow() {
if (this.editedIndex > -1) {
Object.assign(this.data[this.editedIndex], this.editedItem);
} else {
this.data.push(this.editedItem);
}
this.close()
},
deleteItem(item) {
const index = this.data.indexOf(item);
confirm("Are you sure you want to delete this item?") &&
this.data.splice(index, 1);
},
editItem(item) {
this.editedIndex = this.data.indexOf(item);
this.editedItem = Object.assign({}, item);
this.show_dialog = true;
},
close () {
this.show_dialog = false
setTimeout(() => {
this.editedItem = Object.assign({}, this.defaultItem)
this.editedIndex = -1
}, 300)
}
},
data() {
return {
show_dialog: false,
editedIndex: -1,
editedItem: {
name: "",
calories: 0,
fat: 0,
carbs: 0,
protein: 0,
sodium: 0,
calcium: "0%",
iron: "0%"
},
defaultItem: {
name: "",
calories: 0,
fat: 0,
carbs: 0,
protein: 0,
sodium: 0,
calcium: "0%",
iron: "0%"
},
columns: [
{
name: "desc",
required: true,
label: "Dessert (100g serving)",
align: "left",
field: row => row.name,
format: val => `${val}`,
sortable: true
},
{
name: "calories",
align: "center",
label: "Calories",
field: "calories",
sortable: true
},
{
name: "fat",
label: "Fat (g)",
field: "fat",
sortable: true,
style: "width: 10px"
},
{ name: "carbs", label: "Carbs (g)", field: "carbs" },
{ name: "protein", label: "Protein (g)", field: "protein" },
{ name: "sodium", label: "Sodium (mg)", field: "sodium" },
{
name: "calcium",
label: "Calcium (%)",
field: "calcium",
sortable: true,
sort: (a, b) => parseInt(a, 10) - parseInt(b, 10)
},
{
name: "iron",
label: "Iron (%)",
field: "iron",
sortable: true,
sort: (a, b) => parseInt(a, 10) - parseInt(b, 10)
},
{
name: "actions",
label: "Actions",
field: "actions"
}
],
data: [
{
name: "Frozen Yogurt",
calories: 159,
fat: 6.0,
carbs: 24,
protein: 4.0,
sodium: 87,
calcium: "14%",
iron: "1%"
},
{
name: "Ice cream sandwich",
calories: 237,
fat: 9.0,
carbs: 37,
protein: 4.3,
sodium: 129,
calcium: "8%",
iron: "1%"
},
{
name: "Eclair",
calories: 262,
fat: 16.0,
carbs: 23,
protein: 6.0,
sodium: 337,
calcium: "6%",
iron: "7%"
},
{
name: "Cupcake",
calories: 305,
fat: 3.7,
carbs: 67,
protein: 4.3,
sodium: 413,
calcium: "3%",
iron: "8%"
},
{
name: "Gingerbread",
calories: 356,
fat: 16.0,
carbs: 49,
protein: 3.9,
sodium: 327,
calcium: "7%",
iron: "16%"
},
{
name: "Jelly bean",
calories: 375,
fat: 0.0,
carbs: 94,
protein: 0.0,
sodium: 50,
calcium: "0%",
iron: "0%"
},
{
name: "Lollipop",
calories: 392,
fat: 0.2,
carbs: 98,
protein: 0,
sodium: 38,
calcium: "0%",
iron: "2%"
},
{
name: "Honeycomb",
calories: 408,
fat: 3.2,
carbs: 87,
protein: 6.5,
sodium: 562,
calcium: "0%",
iron: "45%"
},
{
name: "Donut",
calories: 452,
fat: 25.0,
carbs: 51,
protein: 4.9,
sodium: 326,
calcium: "2%",
iron: "22%"
},
{
name: "KitKat",
calories: 518,
fat: 26.0,
carbs: 65,
protein: 7,
sodium: 54,
calcium: "12%",
iron: "6%"
}
]
};
}
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/quasar.umd.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/quasar.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment