1

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.

3 Answers 3

3

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;
    }
    }
});
Sign up to request clarification or add additional context in comments.

Comments

3

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

Comments

1
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

4 Comments

Hope this works, it is the best approach to have reaction corresponding to each item
quick question. What if instead of assigning the @click="food.reaction='good'" and @click="food.reaction='bad'"inline, i want to assign it in a method call?
Surely you can do that, as you were initially calling function, the same way
Thanks, i like this way since i can track feedback for every object. Accepting as an answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.