简体   繁体   中英

How to change property of indivudal buttons in vuetify data-table?

I have a vuetify data-table which renders the data received from axios call.

On the last column I'm using template v-slot for bespoke column so I can add two buttons. v-btn accepts has two props for loading state as per the documentation https://vuetifyjs.com/en/components/buttons#loaders :

  • :loading
  • :disabled

The problem is that when I call a function that changes those values, all of the buttons in the data table are receiving the prop state so instead of 1 button displying loader, all of them are.

<v-row no-gutters>      
                <v-data-table
                :headers="tableHeaders"
                :items="requests"
                :items-per-page="10"
                class="elevation-1"
                :loading="loading" loading-text="Loading... Please wait"
                >

                <template v-slot:item.action="{ item }">
                    <v-btn color="success" @click="createPacks(item)" :loading="createloading" :disabled="createloading">Create</v-btn>
                    <v-btn color="error" @click="excludeRequest(item)" :loading="cancelloading" :disabled="cancelloading">Cancel</v-btn>     
                </template>
                </v-data-table>
            </v-row>

I'm aware this is because the buttons in the DOM are not unique and the framework is calling all of them but I have no idea how to change that default behaviour.


Data:

export default {
    data() {
        return {
            loading: null,
            error: null,
            tableHeaders: [
                {
                    text: 'ID',
                    value: 'req_id',
                    align: 'center',
                },
                { text: 'Template', value: 'templateConcatenated'},
                { text: 'No of batches', value: 'no_batches' },
                { text: 'Batch size', value: 'batch_size' },
                { text: 'Date requested', value: 'requested_at' },
                { text: 'Requested by', value: 'requester' },
                { text: 'Actions', value: 'action', sortable: false, align: 'center'},
            ],

            createloading: false,
            cancelloading: false,
            successmessage: '',
            errormessage: '',

        };
    },
    methods: {

        createPacks(item) {
            this.loading = true;
            this.createloading = true;
            let page_url = '/api/CreateProcedure?api_token='+this.$api_token;
            axios
                .post(page_url, item)
                .then((response) => {
                    this.loading = false;

                    this.error = null;
                    this.createloading = false;
                    this.successmessage = 'Packs created successfully!';
                    this.errormessage = null;
                })
                .catch(err => {
                    this.createloading = false;
                    this.successmessage = null;
                    this.errormessage = 'Error creating the packs: '+err;
                    console.log("error: "+err);
                })
        },

    }
}

Any idea how to call each individual button to change it's state?

Thank you

You've to set the loading properties on the item itself instead of defining them globally:

createPacks(item) {
        this.loading = true;
        item.createloading = true;
        let page_url = '/api/CreateProcedure?api_token='+this.$api_token;
        axios
            .post(page_url, item)
            .then((response) => {
                this.loading = false;

                this.error = null;
                item.createloading = false;
                this.successmessage = 'Packs created successfully!';
                this.errormessage = null;
            })
            .catch(err => {
                item.createloading = false;
                this.successmessage = null;
                this.errormessage = 'Error creating the packs: '+err;
                console.log("error: "+err);
            })
    },

== UPDATE ==

I added a code based on the codepen you added in the comments, you have to use item.createloasing also in the HTML else it is not working. https://codepen.io/reijnemans/pen/LYPerLg?editors=1010

Currently only one button is working at the same time but this is probably because of axios is not defined in the codepen.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM