Calculating price with checkboxes and radio button with Vuejs
I am new to vue trying to make this small pizza ordering app where u can select the pizza size like medium, large, and extralarge each with different price, with toppings like pepperoni, extra cheese, mushrooms as checkboxes with different prices, when u select the pizza size it will display the price of that size like medium is 3000 and when you add topping by selecting a checkbox like pepperoni, the price will be added to the pizza size medium, if you wish to check all checkboxes the prices of each topping should add to the selected pizza size and if u unchecked the price should reduce accordingly. Everything I want is working perfectly so far except for when I checked two or more checkboxes on a pizza size it gets added but when I change the pizza size to say from medium to large only the last checked checkbox price gets added the remaining checked checkboxes price gets ignored, any idea how to solve this will be appreciated or even better way of writing this code
this is the template
<div class="mb-4 md:mr-2 md:mb-0">
<label class="block mb-2 text-sm font-bold text-gray-700" for="address">
Size
</label>
<div>
<input class="cursor-pointer " @change="setSizePrice($event)" type="radio" v-
bind:value="m" v-model="form.size">
<span class="text-sm px-1">Medium</span>
</div>
<div>
<input class="cursor-pointer" @change="setSizePrice($event)" type="radio" v-
bind:value="l" v-model="form.size">
<span class="text-sm px-1">Large</span>
</div>
<div>
<input class="cursor-pointer" @change="setSizePrice($event)" type="radio" v-
bind:value="xl" v-model="form.size">
<span class="text-sm px-1">Extra Large</span>
</div>
</div>
</div>
<div class="mb-4">
<label class="block mb-2 text-sm font-bold text-gray-700" for="address">
Toppings
</label>
<div id="checkboxes" class="flex">
<div class="md:ml-2">
<input type="checkbox" @change="addToppings($event)" :value="200"
id="pepperoni" v-model="form.toppings"
class="rounded border-gray-300 text-indigo-600 shadow-sm focus:border-
indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"/>
<span class="text-sm pl-1 pr-2">Pepperoni</span>
</div>
<div class="md:ml-2">
<input type="checkbox" @change="addToppings($event)" :value="300"
id="extracheese" v-model="form.toppings"
class="rounded border-gray-300 text-indigo-600 shadow-sm focus:border-
indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"/>
<span class="text-sm pl-1 pr-2">Extra Cheese</span>
</div>
<div class="md:ml-2">
<input type="checkbox" @change="addToppings($event)" :value="400"
id="mushrooms" v-model="form.toppings"
class="rounded border-gray-300 text-indigo-600 shadow-sm focus:border-
indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"/>
<span class="text-sm pl-1 pr-2">Mushrooms</span>
</div>
<div class="md:ml-2">
<input type="checkbox" @change="addToppings($event)" :value="500"
id="groundbeef" v-model="form.toppings"
class="rounded border-gray-300 text-indigo-600 shadow-sm focus:border-
indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"/>
<span class="text-sm pl-1 pr-2">Ground Beef</span>
</div>
<div class="md:ml-2">
<input type="checkbox" @change="addToppings($event)" :value="600"
id="pineapple" v-model="form.toppings"
class="rounded border-gray-300 text-indigo-600 shadow-sm focus:border-
indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"/>
<span class="text-sm pl-1 pr-2">Pineapple</span>
</div>
</div>
</div>
<div class="mb-4">
<label class="block mb-2 text-sm font-bold text-gray-700" for="instruction">
Instruction
</label>
<input
class="w-full px-3 py-2 mb-3 text-sm leading-tight text-gray-700 border rounded
shadow appearance-none focus:outline-none focus:shadow-outline"
id="instructions"
type="instructions"
name="instructions"
placeholder="Instructions"
v-model="form.instructions"
/>
</div>
<div class="mb-6 text-center">
<button
class="w-full px-4 py-2 font-bold text-white bg-blue-500 rounded-full hover:bg-blue-
700 focus:outline-none focus:shadow-outline"
>
Place Order
</button>
</div>
<hr class="mb-6 border-t" />
<span >Price: N{{totalPrice ? totalPrice : sizePrice}} </span>
</form>
this is the script
<script>
import Checkbox from '../../Jetstream/Checkbox.vue';
import Input from '../../Jetstream/Input.vue';
import AppLayout from '@/Layouts/AppLayout.vue';
export default {
components: { Input, Checkbox, AppLayout },
data: function() {
return {
form: this.$inertia.form({
address: null,
size: null,
toppings: [],
instructions: null
}),
m: 'medium',
l: 'large',
xl: 'extralarge',
sizeStatus: null,
sizePrice: null,
toppingsPrice: null,
totalPrice: null,
medium: 2000,
large: 3000,
extralarge: 4500,
pizzaSize: null,
pepperoni: 'pepperoni',
extraCheese: 'extracheese',
mushrooms: 'mushrooms',
groundBeef: 'groundbeef',
pineapple: 'pineapple',
toppings: null,
toppingsSum: null,
toppingsStatus: null,
}
},
methods: {
store() {
this.form.post(this.route('order.store'))
},
setSizePrice(event) {
this.pizzaSize = event.target.value;
this.sizeStatus = event.target.checked;
if (this.pizzaSize == this.m ) {
this.sizePrice = this.medium;
if (this.toppingsStatus == true && this.sizeStatus == true) {
this.sizePrice += parseInt(this.toppings);
}
} else if(this.pizzaSize == this.l){
this.sizePrice = this.large;
if (this.toppingsStatus == true && this.sizeStatus == true) {
this.sizePrice += parseInt(this.toppings);
}
} else {
this.sizePrice = this.extralarge
if (this.toppingsStatus == true && this.sizeStatus == true) {
this.sizePrice += parseInt(this.toppings)
}
}
console.log(this.sizePrice);
},
addToppings(event) {
this.toppings = event.target.value;
this.toppingsStatus = event.target.checked;
if (this.toppingsStatus) {
this.sizePrice += parseInt(this.toppings)
console.log(this.sizePrice);
} else if(this.toppingsStatus == false) {
this.sizePrice -= this.toppings;
console.log(this.sizePrice);
}
}
},
}
</script>
Please or to participate in this conversation.