Reputation: 1368
I am trying to create a user feedback form where users can rate the quality of the food item they ordered. I have an array foodItems
which render the food list and i have certain reactions set up for the food items. I am trying to add a method so that user can provide the feedback but user can set up only one reaction at a time. So for instance for Pizza they can be satisfied
or dissatisfied
and the selected reaction should be highlighted and so on but i am not sure how i can do it.
Check out this sample codepen.
Check out this working example:-
new Vue({
el: "#app",
data() {
return {
reaction: false,
selectedReaction: "",
foodItems: [{
name: "Pizza",
value: "pizza"
},
{
name: "Pasta",
value: "pasta"
}
]
};
},
methods: {
setReaction() {
this.reaction = !this.reaction;
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js"></script>
<link rel="stylesheet" href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons'>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet" />
<div id="app">
<v-app id="inspire">
<v-container>
<v-layout row wrap justify-center>
<v-flex xs6 v-for="(food,index) in foodItems" :key="index">
<h1>{{ food.name }}</h1>
<v-icon large left :color="reaction ? 'primary' : ''" @click="setReaction">sentiment_dissatisfied</v-icon>
<v-icon large :color="reaction ? 'primary' : ''" @click="setReaction">sentiment_very_satisfied</v-icon>
</v-flex>
</v-layout>
</v-container>
</v-app>
</div>
So basically i am trying to add the functionality for the users to rate the food. Any help will be appreciated. Thank you so much.
Upvotes: 1
Views: 478
Reputation: 190
The main concern is you need to have a reaction corresponding to each food item, so add a reaction/feedback property with each food item. Notice individual feedback change. There can be so many other approaches as well.
https://codepen.io/pjain-techracers/pen/abvXPwK
Upvotes: 1
Reputation: 823
The simplest thing to do is using a boolean value like isSatisfied
which is false if user dissatisfiedm true if it is satisfied and undefined if no information has been given.
the problem with this is that if you write if(isSatisfied)
and the flag is undefined, codeflow goes to else block. so you should write something like
if(isSatisfied)
//satisfied
if(isSatisfied === false)
//unsatisfied
Another option is to use a string, you can store a string feedback
that can be undefined
, 'satisfied'
or 'unsatisfied'
.
You can do the same using a number.
Those last options are more flexible as you can "upgrade" feedback system without changing the model (obviously within certain limits).
That flags/strings/numbers must be stored somewhere. You could create a new feedback array of objects, each of them containing:
food reference
user reference
user rating
Upvotes: 3
Reputation: 4330
There are many approaches for this, but in the end what you need to do is, store rating for every food item.
What I have done in my implementation is created an array for ratings selectedReaction
, which will store either 1, -1, undefined
. Whenever you add any rating, for any food, for the index of food in foodItems
I add 1 for positive feedback, -1 for negative feedback at the same index in selectedReaction
.
<div id="app">
<v-app id="inspire">
<v-container>
<v-layout row wrap justify-center>
<v-flex xs6 v-for="(food,index) in foodItems" :key="index">
<h1>{{ food.name }}</h1>
<v-icon large left :color="selectedReaction[index] === -1 ? 'primary' : ''" @click="setReaction(index, false)">sentiment_dissatisfied</v-icon>
<v-icon large :color="selectedReaction[index] === 1 ? 'primary' : ''" @click="setReaction(index, true)">sentiment_very_satisfied</v-icon>
</v-flex>
</v-layout>
</v-container>
</v-app>
</div>
new Vue({
el: "#app",
data() {
return {
selectedReaction: [],
foodItems: [
{
name: "Pizza",
value: "pizza"
},
{
name: "Pasta",
value: "pasta"
}
]
};
},
methods: {
setReaction(index, isSatisfied) {
const reaction = [...this.selectedReaction];
reaction[index] = isSatisfied ? 1 : -1;
this.selectedReaction = reaction;
}
}
});
Upvotes: 3