0
votes

Im very new to Vue.js. I’m trying to build a simple app that totals a list of items. But it also, should have the option to ‘disable’ the individual items so that their value would not contribute to the total. (UPDATE: the button should toggle the disabled state)

Visually, the disabled items would simply be greyed-out, (i dont want their amounts showing zero)

I was imagining perhaps, targeting the parent item with a disabled attribute (when the btn is clicked). And then….a check would be made for the existence of this attribute, when the totalling is done (and any item without the attribute (class?) would be skipped)

But I have no idea how this would work in Vue World. Anyone willing to help out please? Or even point me in the right direction?

HTML

<div id="app">
    <div id="item1">{{ item1.amt }} <button type="button">exclude me</button></div>
    <div id="item2">{{ item2.amt }} <button type="button">exclude me</button></div>
    <div id="item3">{{ item3.amt }} <button type="button">exclude me</button></div>

    <br>

    <div id="total">total: {{ item1.amt + item2.amt + item3.amt }}</div>

</div>

JS

var app = new Vue({
    el: "#app", 
    data: {
        item1: {
            amt: 10
        },
        item2: {
            amt: 20
        },
        item3: {
            amt: 30
        }
    }
});

https://codepen.io/dagford/pen/oyKXYP?editors=1010

thank you

2

2 Answers

2
votes

Welcome to the vuetiful world of Vue.

If you need the to see the working code, go here

But let me explain you what I actually did

JS

var app = new Vue({
    el: "#app", 
    data: {
        items:[
        {
            id:'item1',
            included:'true',
            amt: 10
        },
        {
            id:'item2',
            included:'true',
            amt: 20
        },
        {
            id:'item3',
            included:'true',
            amt: 30
        }
        ]
    },
    computed:{
        itemTotal(){
            return this.items.reduce(function(sum, item){
                if(item.included){
                    return  item.amt + sum;
                }

                return sum;
            },0)
        }
    }
});

It is very crucial to model your data in a correct way. As your items where having common properties, so it could come in an array. I have include the id and a flag know whether it is included or not.

I also have added a method to compute the total every time item changes.

Template:

<div id="app">    
    <div v-for="item in items"
         :id="item.id"
         :key="item.id">
        <span>{{item.amt}}</span>
        <button @click="item.included = false"> exclude me</button>

    </div>
    <br>
    <div id="total">total: {{ itemTotal }}</div>
    </div>

In template code I have added v-for to render the whole list, and at button click I am just changing the flag (included). Computation of the itemTotal is triggered automatically and smartly by vue. An at last I am rendering the itemTotal in separate div.

I hope this helps.

2
votes

if you want to button toggles the 'included' state and exclude the value

try it use v-on:click and a unclick boolean varible

simple demo looks like:


var app = new Vue({
    el: "#app", 
    data: {
        item1: {
            amt: 10,
            unclick:true
        },
        item2: {
            amt: 30,
            unclick:true
        }
    }
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<div id="app">
    <div id="item1">{{ item1.amt }} 
        <button v-on:click="item1.unclick = !item1.unclick" type="button">
         {{ (item1.unclick?'exclude me':'include me')  }}
        </button>  
    </div>
    <div id="item2">{{ item2.amt }} 
        <button v-on:click="item2.unclick = !item2.unclick" type="button">
         {{ (item2.unclick?'exclude me':'include me')  }}
        </button>  
    </div>
    <br>
    <div id="total">total: {{ 
            (item1.unclick?item1.amt:0) 
            + (item2.unclick?item2.amt:0)
        }}
    </div>
</div>