0
votes

Vue version: 2.6.10

Vuetify version: 1.5

I am using example data of Vuetify 1.5.16 documentation: https://v15.vuetifyjs.com/en/components/data-tables

The problem is that in editing mode array is edited (I can see that in console) but it is not shown in vuetify data table (except if I change pages back thought or I am using input fields in expanded rows).

The problem is probably somehow related with axios, because when I used just regular data array there was no problem.

I am using Vue.js and Vuetify with Django framework but probably it has no effect for this problem.

{% extends 'base.html' %}
{% block title %}Page Name{% endblock %}

{% block custom_style %}
<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/vuetify.min.css" rel="stylesheet">
{% endblock %}


{% block content %}
<v-app id="app-employees">
    <div v-if="isLoading">
        <v-dialog v-model="isLoading" hide-overlay persistent width="300">
            <v-card dark>
                <v-card-text>
                    <h1>
                        <center>Loading...</center>
                    </h1>
                    <v-progress-linear indeterminate color="white" class="mb-0"></v-progress-linear>
                </v-card-text>
            </v-card>
        </v-dialog>
    </div>
    <div v-else>

        <template>
            <v-text-field class="search_field ma-0" v-model="search" append-icon="search" label="Paieška..." single-line
                hide-details>
            </v-text-field>

            <v-data-table disable-initial-sort no-data="Duomenys nerasti" dark :loading="isLoading" no-data-text
                :headers="headers" :items="tabledata" :search="search" :expand="expand" item-key="email"
                class="elevation-1" :pagination.sync="pagination" :rows-per-page-items="rowsPerPageItems">
                <template v-slot:items="props">
                    <td>
                        <v-edit-dialog :return-value.sync="props.item.first_name" lazy @save="save" @cancel="cancel"
                            @open="open" @close="close"> <% props.item.first_name %>
                            <template v-slot:input>
                                <v-text-field v-model="props.item.first_name" label="Edit" single-line counter>
                                </v-text-field>
                            </template>
                        </v-edit-dialog>
                    </td>

                    <!-- <td class="text-xs-left"> <% props.item.first_name %> </td> -->
                    <td class="text-xs-left"><% props.item.last_name %></td>
                    <td class="text-xs-left"><% props.item.email %></td>
                    <td class="text-xs-left"><% props.item.sex %></td>
                    <td @click="props.expanded = !props.expanded" class="text-xs-center">
                        <v-icon small v-if="props.expanded==undefined">arrow_downward</v-icon>
                        <v-icon small v-if="props.expanded==false">arrow_downward</v-icon>
                        <v-icon small v-if="props.expanded==true">arrow_upward</v-icon>
                    </td>
                    <!-- <td @click="props.expanded = !props.expanded"></td> -->
                    <td @click="props.expanded = !props.expanded" class="text-xs-center">
                        <v-icon small v-if="props.expanded==undefined">arrow_downward</v-icon>
                        <v-icon small v-if="props.expanded==false">arrow_downward</v-icon>
                        <v-icon small v-if="props.expanded==true">arrow_upward</v-icon>
                    </td>
                    <!-- <td class="text-xs-left"><% props.item.workload %></td> -->
                    <td class="text-xs-left"><% props.item.workload_units %></td>
                    <td @click="props.expanded = !props.expanded" class="text-xs-center">
                        <v-icon small v-if="props.expanded==undefined">arrow_downward</v-icon>
                        <v-icon small v-if="props.expanded==false">arrow_downward</v-icon>
                        <v-icon small v-if="props.expanded==true">arrow_upward</v-icon>
                    </td>
                    <td class="right">
                        <v-checkbox primary hide-details @click.native="props.item.active=!props.item.active"
                            :input-value="props.item.active"></v-checkbox>
                    </td>
                </template>

                <template v-slot:expand="props">
                    <v-card flat>
                        <v-card flat="flat" color="dark">
                            <v-container fluid="fluid" grid-list-xl="grid-list-xl">

                                <v-layout row wrap>
                                    <v-flex xs8>Position: </v-flex>
                                    <v-flex xs4>Categories: </v-flex>
                                </v-layout>

                                <v-layout row wrap>
                                    <v-flex xs2>
                                        <input class="expandable" type="text" style="float:right"
                                            v-model="props.item.position" />
                                    </v-flex>
                                    <v-flex xs2>
                                        <input class="expandable" type="text" style="float:left"
                                            v-model="props.item.workload" />

                                    </v-flex>
                                    <v-spacer></v-spacer>
                                    <v-flex xs4>
                                        <div>
                                            <input class="expandable" type="text" v-model="props.item.categories" />
                                        </div>
                                    </v-flex>
                                </v-layout>
                            </v-container>
                        </v-card>
                    </v-card>

                </template>
            </v-data-table>
            <v-snackbar v-model=" snack" :timeout="3000" :color="snackColor">
                <% snackText %>
                <v-btn flat @click="snack = false">Close</v-btn>
            </v-snackbar>
        </template>
    </div>
</v-app>

{% endblock %}


{% block custom_js_back %}


<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>


<script>
    axios.defaults.xsrfCookieName = 'csrftoken';
    axios.defaults.xsrfHeaderName = 'X-CSRFToken';
    axios.defaults.baseURL = "http://{{ request.get_host }}/api";

    var vueData = new Vue({
        delimiters: ["<%", "%>"],
        el: '#app-employees',
        data() {
            return {
                isLoading: true,
                ids: null,
                tabledata: [
                    { first_name: null, last_name: null, email: null, sex: null, position: null, workload: null, workload_units: null, categories: null, active: null },
                ],
                expand: false,
                search: '',
                snack: false,
                snackColor: '',
                snackText: '',
                max25chars: v => v.length <= 25 || 'Input too long!',
                rowsPerPageItems: [30, 40, 50,
                    {
                        value: -1,
                        text: "All"
                    }],
                pagination: {
                    rowsPerPage: 30
                },
                headers: [
                    {
                        text: 'Name',
                        sortable: true,
                        value: 'first_name',
                    },
                    { text: 'Surname', value: 'last_name' },
                    { text: 'email', value: 'email' },
                    { text: 'gender', value: 'sex' },
                    { text: 'position', value: 'position', align: 'center' },
                    { text: 'workload', value: 'workload', align: 'center' },
                    { text: 'units', value: 'workload_units' },
                    { text: 'categories', value: 'categories', align: 'center' },
                    { text: 'Activity', value: 'active', align: 'right' },
                ],
            }
        },
        beforeCreate() {
            const initialData = async () => {
                try {

                    let shiftData = null;
                    let categorydata = null;
                    let employeedata = null;
                    let positiondata = null;
                    let data = [
                        { first_name: null, last_name: null, email: null, sex: null, position: null, workload: null, workload_units: null, categories: null, active: null },
                    ];

                    categorydata = await axios.get('/categories/' + '{{schedule.pk}}').then(response => { return response.data })
                    employeedata = await axios.get('/profiles/' + '{{schedule.pk}}').then(response => { return response.data })
                    shiftData = await axios.get('/shifts/' + '{{schedule.pk}}').then(response => { return response.data })
                    positiondata = await axios.get('/positions/' + '{{schedule.pk}}').then(response => { return response.data })


                    data = [
                        { first_name: "name", last_name: "last name", email: "email", sex: "gender", position: "position", workload: "number", workload_units: "units", categories: "category", active: "active" },
                        { first_name: "name", last_name: "last name", email: "email", sex: "gender", position: "position", workload: "number", workload_units: "units", categories: "category", active: "active" },
                        { first_name: "name", last_name: "last name", email: "email", sex: "gender", position: "position", workload: "number", workload_units: "units", categories: "category", active: "active" },
                        { first_name: "name", last_name: "last name", email: "email", sex: "gender", position: "position", workload: "number", workload_units: "units", categories: "category", active: "active" },
                        { first_name: "name", last_name: "last name", email: "email", sex: "gender", position: "position", workload: "number", workload_units: "units", categories: "category", active: "active" },
                    ];


                    for (let i = 0; i < data.length; i++) {
                        this.tabledata[i] = data[i];
                    }
                    console.log("table data: ", this.tabledata);
                    this.isLoading = false;
                }
                catch (error) {
                    console.log(`Loading error: ${error}`)
                }
            }
            initialData()
        },
        methods: {
            save() {
                this.snack = true
                this.snackColor = 'success'
                this.snackText = 'Saved'
                console.log("Išsaugota: ", this.tabledata);
            },
            cancel() {
                this.snack = true
                this.snackColor = 'error'
                this.snackText = 'Cancel'
            },
            open() {
                this.snack = true
                this.snackColor = 'info'
                this.snackText = 'Edit'
            },
            close() {

            }
        }
    });

</script>
{% endblock custom_js_back %}
1

1 Answers

0
votes

The beforeCreate() method is the very first method in the vue life cycle. The data is not reactive at this point, so any changes you make to the data in the beforeCreate() method will not be reflected. Instead make the changes to the created() or mounted() methods.

For more info:

https://vuejs.org/v2/guide/instance.html

https://alligator.io/vuejs/component-lifecycle/