Change attribute of this button inside v-for loop in Vue.js











up vote
-1
down vote

favorite
1












I'm using a Vue.js v-for loop to output a table of information, each with their own action buttons like so using Element UI library.



    <template>
<div class="card">
<div class="card-header">
<tool-bar></tool-bar>
</div>

<div class="card-body">
<el-table :data="orders" v-loading="loading" current-row-key="index" empty-text="No products found">
<el-table-column type="expand">
<template slot-scope="props">

<el-tabs>
<el-tab-pane label="Order Items">
<ul>
<li v-for="(product, index) in orders[props.$index].products" :key="index">{{ product.name }}</li>
</ul>
</el-tab-pane>
<el-tab-pane label="Customer Details">Customer Details
<!-- <p v-for="(customer, index) in orders[props.$index].order.billing_address" :key="index">{{ customer.index }}</p> -->
</el-tab-pane>
</el-tabs>


</template>
</el-table-column>

<el-table-column label="Order ID" prop="order.id"></el-table-column>
<el-table-column label="Customer" prop="order.billing_address.first_name"></el-table-column>
<el-table-column label="Due Time" prop="order.due_time"></el-table-column>

<el-table-column
align="right">
<template slot="header" slot-scope="scope">
<el-input
v-model="search"
placeholder="Type to search"/>
</template>
<template slot-scope="scope">
<el-button size="mini" type="success" :disabled="orders[scope.$index].checked_in" :loading="false" :ref="'btn-' + scope.$index" @click="checkInOrder(scope.$index, scope.row)">{{ (orders[scope.$index].checked_in) ? 'Checked in' : 'Check in' }}</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>

<script>
import Toolbar from '../components/Toolbar.vue';
export default {
components: {
'tool-bar': Toolbar
},
mounted() {
this.fetchOrders();
},
data () {
return {
search: '',
}
},
computed: {
loading() {
return this.$store.getters.loading;
},
orders() {
return this.$store.getters.orders;
}
},
methods: {
fetchOrders() {
this.$store.dispatch('fetchOrders')
.then(res => {
})
.catch(err => {
})
},
checkInOrder(index, row) {
this.$refs['btn-' + index].loading = true;

axios.post('/order/update', {
id: row.order.id,
status: 'bakery',
products: row.products
})
.then(res => {
this.$refs['btn-' + index].loading = false;
})
.catch(err => {
this.$refs['btn-' + index].loading = false;
})
}
}
}
</script>


When I click one of the buttons, I want to be able to set the :loading attribute of the clicked button to true as well as change the button label to Loading... until a given Ajax request is completed.



I used the :ref attribute on the button and, when the button is clicked, I alter the attribute as follows:



checkInOrder(index, row) {
this.$refs['btn-' + index].loading = true;
}


This seems to work fine, but the console is throwing a warning, so I want to find out the way to achieve this.



The warning I get is this:
enter image description here










share|improve this question
























  • please check my new answer
    – Boussadjra Brahim
    Nov 22 at 17:10

















up vote
-1
down vote

favorite
1












I'm using a Vue.js v-for loop to output a table of information, each with their own action buttons like so using Element UI library.



    <template>
<div class="card">
<div class="card-header">
<tool-bar></tool-bar>
</div>

<div class="card-body">
<el-table :data="orders" v-loading="loading" current-row-key="index" empty-text="No products found">
<el-table-column type="expand">
<template slot-scope="props">

<el-tabs>
<el-tab-pane label="Order Items">
<ul>
<li v-for="(product, index) in orders[props.$index].products" :key="index">{{ product.name }}</li>
</ul>
</el-tab-pane>
<el-tab-pane label="Customer Details">Customer Details
<!-- <p v-for="(customer, index) in orders[props.$index].order.billing_address" :key="index">{{ customer.index }}</p> -->
</el-tab-pane>
</el-tabs>


</template>
</el-table-column>

<el-table-column label="Order ID" prop="order.id"></el-table-column>
<el-table-column label="Customer" prop="order.billing_address.first_name"></el-table-column>
<el-table-column label="Due Time" prop="order.due_time"></el-table-column>

<el-table-column
align="right">
<template slot="header" slot-scope="scope">
<el-input
v-model="search"
placeholder="Type to search"/>
</template>
<template slot-scope="scope">
<el-button size="mini" type="success" :disabled="orders[scope.$index].checked_in" :loading="false" :ref="'btn-' + scope.$index" @click="checkInOrder(scope.$index, scope.row)">{{ (orders[scope.$index].checked_in) ? 'Checked in' : 'Check in' }}</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>

<script>
import Toolbar from '../components/Toolbar.vue';
export default {
components: {
'tool-bar': Toolbar
},
mounted() {
this.fetchOrders();
},
data () {
return {
search: '',
}
},
computed: {
loading() {
return this.$store.getters.loading;
},
orders() {
return this.$store.getters.orders;
}
},
methods: {
fetchOrders() {
this.$store.dispatch('fetchOrders')
.then(res => {
})
.catch(err => {
})
},
checkInOrder(index, row) {
this.$refs['btn-' + index].loading = true;

axios.post('/order/update', {
id: row.order.id,
status: 'bakery',
products: row.products
})
.then(res => {
this.$refs['btn-' + index].loading = false;
})
.catch(err => {
this.$refs['btn-' + index].loading = false;
})
}
}
}
</script>


When I click one of the buttons, I want to be able to set the :loading attribute of the clicked button to true as well as change the button label to Loading... until a given Ajax request is completed.



I used the :ref attribute on the button and, when the button is clicked, I alter the attribute as follows:



checkInOrder(index, row) {
this.$refs['btn-' + index].loading = true;
}


This seems to work fine, but the console is throwing a warning, so I want to find out the way to achieve this.



The warning I get is this:
enter image description here










share|improve this question
























  • please check my new answer
    – Boussadjra Brahim
    Nov 22 at 17:10















up vote
-1
down vote

favorite
1









up vote
-1
down vote

favorite
1






1





I'm using a Vue.js v-for loop to output a table of information, each with their own action buttons like so using Element UI library.



    <template>
<div class="card">
<div class="card-header">
<tool-bar></tool-bar>
</div>

<div class="card-body">
<el-table :data="orders" v-loading="loading" current-row-key="index" empty-text="No products found">
<el-table-column type="expand">
<template slot-scope="props">

<el-tabs>
<el-tab-pane label="Order Items">
<ul>
<li v-for="(product, index) in orders[props.$index].products" :key="index">{{ product.name }}</li>
</ul>
</el-tab-pane>
<el-tab-pane label="Customer Details">Customer Details
<!-- <p v-for="(customer, index) in orders[props.$index].order.billing_address" :key="index">{{ customer.index }}</p> -->
</el-tab-pane>
</el-tabs>


</template>
</el-table-column>

<el-table-column label="Order ID" prop="order.id"></el-table-column>
<el-table-column label="Customer" prop="order.billing_address.first_name"></el-table-column>
<el-table-column label="Due Time" prop="order.due_time"></el-table-column>

<el-table-column
align="right">
<template slot="header" slot-scope="scope">
<el-input
v-model="search"
placeholder="Type to search"/>
</template>
<template slot-scope="scope">
<el-button size="mini" type="success" :disabled="orders[scope.$index].checked_in" :loading="false" :ref="'btn-' + scope.$index" @click="checkInOrder(scope.$index, scope.row)">{{ (orders[scope.$index].checked_in) ? 'Checked in' : 'Check in' }}</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>

<script>
import Toolbar from '../components/Toolbar.vue';
export default {
components: {
'tool-bar': Toolbar
},
mounted() {
this.fetchOrders();
},
data () {
return {
search: '',
}
},
computed: {
loading() {
return this.$store.getters.loading;
},
orders() {
return this.$store.getters.orders;
}
},
methods: {
fetchOrders() {
this.$store.dispatch('fetchOrders')
.then(res => {
})
.catch(err => {
})
},
checkInOrder(index, row) {
this.$refs['btn-' + index].loading = true;

axios.post('/order/update', {
id: row.order.id,
status: 'bakery',
products: row.products
})
.then(res => {
this.$refs['btn-' + index].loading = false;
})
.catch(err => {
this.$refs['btn-' + index].loading = false;
})
}
}
}
</script>


When I click one of the buttons, I want to be able to set the :loading attribute of the clicked button to true as well as change the button label to Loading... until a given Ajax request is completed.



I used the :ref attribute on the button and, when the button is clicked, I alter the attribute as follows:



checkInOrder(index, row) {
this.$refs['btn-' + index].loading = true;
}


This seems to work fine, but the console is throwing a warning, so I want to find out the way to achieve this.



The warning I get is this:
enter image description here










share|improve this question















I'm using a Vue.js v-for loop to output a table of information, each with their own action buttons like so using Element UI library.



    <template>
<div class="card">
<div class="card-header">
<tool-bar></tool-bar>
</div>

<div class="card-body">
<el-table :data="orders" v-loading="loading" current-row-key="index" empty-text="No products found">
<el-table-column type="expand">
<template slot-scope="props">

<el-tabs>
<el-tab-pane label="Order Items">
<ul>
<li v-for="(product, index) in orders[props.$index].products" :key="index">{{ product.name }}</li>
</ul>
</el-tab-pane>
<el-tab-pane label="Customer Details">Customer Details
<!-- <p v-for="(customer, index) in orders[props.$index].order.billing_address" :key="index">{{ customer.index }}</p> -->
</el-tab-pane>
</el-tabs>


</template>
</el-table-column>

<el-table-column label="Order ID" prop="order.id"></el-table-column>
<el-table-column label="Customer" prop="order.billing_address.first_name"></el-table-column>
<el-table-column label="Due Time" prop="order.due_time"></el-table-column>

<el-table-column
align="right">
<template slot="header" slot-scope="scope">
<el-input
v-model="search"
placeholder="Type to search"/>
</template>
<template slot-scope="scope">
<el-button size="mini" type="success" :disabled="orders[scope.$index].checked_in" :loading="false" :ref="'btn-' + scope.$index" @click="checkInOrder(scope.$index, scope.row)">{{ (orders[scope.$index].checked_in) ? 'Checked in' : 'Check in' }}</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>

<script>
import Toolbar from '../components/Toolbar.vue';
export default {
components: {
'tool-bar': Toolbar
},
mounted() {
this.fetchOrders();
},
data () {
return {
search: '',
}
},
computed: {
loading() {
return this.$store.getters.loading;
},
orders() {
return this.$store.getters.orders;
}
},
methods: {
fetchOrders() {
this.$store.dispatch('fetchOrders')
.then(res => {
})
.catch(err => {
})
},
checkInOrder(index, row) {
this.$refs['btn-' + index].loading = true;

axios.post('/order/update', {
id: row.order.id,
status: 'bakery',
products: row.products
})
.then(res => {
this.$refs['btn-' + index].loading = false;
})
.catch(err => {
this.$refs['btn-' + index].loading = false;
})
}
}
}
</script>


When I click one of the buttons, I want to be able to set the :loading attribute of the clicked button to true as well as change the button label to Loading... until a given Ajax request is completed.



I used the :ref attribute on the button and, when the button is clicked, I alter the attribute as follows:



checkInOrder(index, row) {
this.$refs['btn-' + index].loading = true;
}


This seems to work fine, but the console is throwing a warning, so I want to find out the way to achieve this.



The warning I get is this:
enter image description here







javascript vue.js






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 at 16:19

























asked Nov 22 at 15:11









Marcus Christiansen

61511031




61511031












  • please check my new answer
    – Boussadjra Brahim
    Nov 22 at 17:10




















  • please check my new answer
    – Boussadjra Brahim
    Nov 22 at 17:10


















please check my new answer
– Boussadjra Brahim
Nov 22 at 17:10






please check my new answer
– Boussadjra Brahim
Nov 22 at 17:10














2 Answers
2






active

oldest

votes

















up vote
0
down vote













I believe it's prompting you to link :loading to a property, which you can set, rather than mutating the element prop directly. Thus, when you call checkInOrder() you could just update the boolean property that :loading is linked to.



I believe this question is relevant and will help you fix this issue.






share|improve this answer





















  • How do I achieve this inside a v-for?
    – Marcus Christiansen
    Nov 22 at 16:16


















up vote
0
down vote













add a property called btnsLoading which is an array in your data as follows:



  data () {
return {
search: '',
btnsLoading:null
}
}


in the mounted hook initialize that array with orders length and fill it with false values :



    mounted() {
this.fetchOrders();
this.btnsLoading=new Array( this.$store.getters.orders.length);
this.btnsLoading.fill(false);
}


and in your template do :



    <el-button ... :loading="btnsLoading[scope.$index]" ...></el-button>


and in your method :



       checkInOrder(index, row) {
this.$set(this.btnLoading,index,true);

axios.post('/order/update', {
id: row.order.id,
status: 'bakery',
products: row.products
})
.then(res => {
this.$set(this.btnLoading,index,false);
})
.catch(err => {
this.$set(this.btnLoading,index,false);
})





share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53433836%2fchange-attribute-of-this-button-inside-v-for-loop-in-vue-js%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    I believe it's prompting you to link :loading to a property, which you can set, rather than mutating the element prop directly. Thus, when you call checkInOrder() you could just update the boolean property that :loading is linked to.



    I believe this question is relevant and will help you fix this issue.






    share|improve this answer





















    • How do I achieve this inside a v-for?
      – Marcus Christiansen
      Nov 22 at 16:16















    up vote
    0
    down vote













    I believe it's prompting you to link :loading to a property, which you can set, rather than mutating the element prop directly. Thus, when you call checkInOrder() you could just update the boolean property that :loading is linked to.



    I believe this question is relevant and will help you fix this issue.






    share|improve this answer





















    • How do I achieve this inside a v-for?
      – Marcus Christiansen
      Nov 22 at 16:16













    up vote
    0
    down vote










    up vote
    0
    down vote









    I believe it's prompting you to link :loading to a property, which you can set, rather than mutating the element prop directly. Thus, when you call checkInOrder() you could just update the boolean property that :loading is linked to.



    I believe this question is relevant and will help you fix this issue.






    share|improve this answer












    I believe it's prompting you to link :loading to a property, which you can set, rather than mutating the element prop directly. Thus, when you call checkInOrder() you could just update the boolean property that :loading is linked to.



    I believe this question is relevant and will help you fix this issue.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 22 at 15:31









    Barzev

    439




    439












    • How do I achieve this inside a v-for?
      – Marcus Christiansen
      Nov 22 at 16:16


















    • How do I achieve this inside a v-for?
      – Marcus Christiansen
      Nov 22 at 16:16
















    How do I achieve this inside a v-for?
    – Marcus Christiansen
    Nov 22 at 16:16




    How do I achieve this inside a v-for?
    – Marcus Christiansen
    Nov 22 at 16:16












    up vote
    0
    down vote













    add a property called btnsLoading which is an array in your data as follows:



      data () {
    return {
    search: '',
    btnsLoading:null
    }
    }


    in the mounted hook initialize that array with orders length and fill it with false values :



        mounted() {
    this.fetchOrders();
    this.btnsLoading=new Array( this.$store.getters.orders.length);
    this.btnsLoading.fill(false);
    }


    and in your template do :



        <el-button ... :loading="btnsLoading[scope.$index]" ...></el-button>


    and in your method :



           checkInOrder(index, row) {
    this.$set(this.btnLoading,index,true);

    axios.post('/order/update', {
    id: row.order.id,
    status: 'bakery',
    products: row.products
    })
    .then(res => {
    this.$set(this.btnLoading,index,false);
    })
    .catch(err => {
    this.$set(this.btnLoading,index,false);
    })





    share|improve this answer

























      up vote
      0
      down vote













      add a property called btnsLoading which is an array in your data as follows:



        data () {
      return {
      search: '',
      btnsLoading:null
      }
      }


      in the mounted hook initialize that array with orders length and fill it with false values :



          mounted() {
      this.fetchOrders();
      this.btnsLoading=new Array( this.$store.getters.orders.length);
      this.btnsLoading.fill(false);
      }


      and in your template do :



          <el-button ... :loading="btnsLoading[scope.$index]" ...></el-button>


      and in your method :



             checkInOrder(index, row) {
      this.$set(this.btnLoading,index,true);

      axios.post('/order/update', {
      id: row.order.id,
      status: 'bakery',
      products: row.products
      })
      .then(res => {
      this.$set(this.btnLoading,index,false);
      })
      .catch(err => {
      this.$set(this.btnLoading,index,false);
      })





      share|improve this answer























        up vote
        0
        down vote










        up vote
        0
        down vote









        add a property called btnsLoading which is an array in your data as follows:



          data () {
        return {
        search: '',
        btnsLoading:null
        }
        }


        in the mounted hook initialize that array with orders length and fill it with false values :



            mounted() {
        this.fetchOrders();
        this.btnsLoading=new Array( this.$store.getters.orders.length);
        this.btnsLoading.fill(false);
        }


        and in your template do :



            <el-button ... :loading="btnsLoading[scope.$index]" ...></el-button>


        and in your method :



               checkInOrder(index, row) {
        this.$set(this.btnLoading,index,true);

        axios.post('/order/update', {
        id: row.order.id,
        status: 'bakery',
        products: row.products
        })
        .then(res => {
        this.$set(this.btnLoading,index,false);
        })
        .catch(err => {
        this.$set(this.btnLoading,index,false);
        })





        share|improve this answer












        add a property called btnsLoading which is an array in your data as follows:



          data () {
        return {
        search: '',
        btnsLoading:null
        }
        }


        in the mounted hook initialize that array with orders length and fill it with false values :



            mounted() {
        this.fetchOrders();
        this.btnsLoading=new Array( this.$store.getters.orders.length);
        this.btnsLoading.fill(false);
        }


        and in your template do :



            <el-button ... :loading="btnsLoading[scope.$index]" ...></el-button>


        and in your method :



               checkInOrder(index, row) {
        this.$set(this.btnLoading,index,true);

        axios.post('/order/update', {
        id: row.order.id,
        status: 'bakery',
        products: row.products
        })
        .then(res => {
        this.$set(this.btnLoading,index,false);
        })
        .catch(err => {
        this.$set(this.btnLoading,index,false);
        })






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 22 at 17:10









        Boussadjra Brahim

        4,3103628




        4,3103628






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53433836%2fchange-attribute-of-this-button-inside-v-for-loop-in-vue-js%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Trompette piccolo

            Slow SSRS Report in dynamic grouping and multiple parameters

            Simon Yates (cyclisme)