Search code examples
javascriptvue.jsvuejs2drop-down-menudropdown

How to display selected value's information in Vue


I have an API to fetch data and it is coming like this:

"data": {
    "type": "products",
    "id": "2021-01-04.1.1",
    "attributes": {
      "name": "product 1",
      "descriptions": "some description",
      "image": null,
      "date": "2021-01-04",
      "valid_from": null,
      "valig_untill": null,
      "xparc_paid_product_id": 1,
      "xparc_unpaid_product_id": 1,
      "xparc_access_id": 1,
      "stock": null,
      "variations": [
        {
          "id": 1,
          "product_template_id": "1",
          "name": "child ticket",
          "description": "Only for children!",
          "price_excl_vat": 1,
          "created_at": "2021-09-15T13:16:00.000000Z",
          "updated_at": "2021-09-15T13:16:00.000000Z"
        },
        {
          "id": 2,
          "product_template_id": "1",
          "name": "Adults",
          "description": "Not for children!",
          "price_excl_vat": 2,
          "created_at": "2021-09-15T13:16:10.000000Z",
          "updated_at": "2021-09-15T13:16:10.000000Z"
        },
        {
          "id": 3,
          "product_template_id": "1",
          "name": "Test",
          "description": "Test",
          "price_excl_vat": 10,
          "created_at": "2021-09-30T11:29:44.000000Z",
          "updated_at": "2021-09-30T11:29:44.000000Z"
        }
      ]
    },

What I am trying to do is I put these variations of the data into the dropdown as you see in the picture: enter image description here

So here is my dropdown component:

<template>
    <div class="custom-select" :tabindex="tabindex" @blur="open = false">
        <div class="selected" :class="{ open: open }" @click="open = !open">
            {{ selected }}
        </div>
        <div class="items" :class="{ selectHide: !open }">
            <div
                v-for="(option, i) of options"
                :key="i"
                @click="
          selected = option;
          open = false;
          $emit('input', option);
        "
            >
                {{ option }}
            </div>
        </div>
    </div>
</template>

<script>
export default {
    props: {
        options: {
            type: Array,
            required: true,
        },
        default: {
            type: String,
            required: false,
            default: null,
        },
        tabindex: {
            type: Number,
            required: false,
            default: 0,
        },
    },
    data() {
        return {
            selected: this.default
                ? this.default
                : this.options.length > 0
                    ? this.options[0]
                    : null,
            open: false,
        };
    },
    mounted() {
        this.$emit("input", this.selected);
    },
};
</script>

And this is how I displayed the names of the variants into the dropdown:

<Dropdown
   :options="getVariations"
   :default="'Choose an option'"
   class="select"
/>
computed: {
  getVariations() {
    return this.product.attributes.variations.map(p => p.name);
  },
},

So what I am trying to do is according to the selected value I want to display more information of the selected variations inside of the div. For example here:

{{variations.description}} But I dont know how to do. Can you help me?

Solution

  • To show it in Dropdown component send data from computed like:

    computed: {
      variations() {
        return this.data.attributes.variations
      }
    }
    

    then i template show data like:

    {{ selected.name }}
    

    To show description on parent component emit event $emit('input', option), so try to listen to @input="getSelected" and filter data in method

    getSelected(opt) {
      this.sel = opt.description
    }
    

    Vue.component('Dropdown', {
      template: `
        <div class="custom-select" :tabindex="tabindex" @blur="open = false">
            <div class="selected" :class="{ open: open }" @click="open = !open">
                {{ selected.name }}
            </div>
            <p>Description child :{{ selected.description }}</p>
            <div class="items" :class="{ selectHide: !open }">
                <div
                    v-for="(option, i) of options"
                    :key="i"
                    @click="
              selected = option;
              open = false;
              $emit('input', option);
            "
                >
                    {{ option.name }}
                </div>
            </div>
            
        </div>
      `,
       props: {
            options: {
                type: Array,
                required: true,
            },
            default: {
                type: String,
                required: false,
                default: null,
            },
            tabindex: {
                type: Number,
                required: false,
                default: 0,
            },
        },
        data() {
            return {
                selected: this.default
                    ? this.default
                    : this.options.length > 0
                        ? this.options[0]
                        : null,
                open: false,
            };
        },
        mounted() {
            this.$emit("input", this.selected);
        },
    })
    
    new Vue({
      el: '#demo',
      data(){
        return {
          "data": 
              {
                "type": "products",
                "id": "2021-01-04.1.1",
                "attributes": {
                  "name": "product 1",
                  "descriptions": "some description",
                  "image": null,
                  "date": "2021-01-04",
                  "valid_from": null,
                  "valig_untill": null,
                  "xparc_paid_product_id": 1,
                  "xparc_unpaid_product_id": 1,
                  "xparc_access_id": 1,
                  "stock": null,
                  "variations": [
                    {
                      "id": 1,
                      "product_template_id": "1",
                      "name": "child ticket",
                      "description": "Only for children!",
                      "price_excl_vat": 1,
                      "created_at": "2021-09-15T13:16:00.000000Z",
                      "updated_at": "2021-09-15T13:16:00.000000Z"
                    },
                    {
                      "id": 2,
                      "product_template_id": "1",
                      "name": "Adults",
                      "description": "Not for children!",
                      "price_excl_vat": 2,
                      "created_at": "2021-09-15T13:16:10.000000Z",
                      "updated_at": "2021-09-15T13:16:10.000000Z"
                    },
                    {
                      "id": 3,
                      "product_template_id": "1",
                      "name": "Test",
                      "description": "Test",
                      "price_excl_vat": 10,
                      "created_at": "2021-09-30T11:29:44.000000Z",
                      "updated_at": "2021-09-30T11:29:44.000000Z"
                    }
                  ]
                },
              },
              sel: ''
            
        }
      },
      computed: {
        variations() {
          return this.data.attributes.variations
        }
      },
      methods: {
        getSelected(opt) {
          this.sel = opt.description
        }
      }
    })
    
    Vue.config.productionTip = false
    Vue.config.devtools = false
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="demo">
      <h3>Description parent :{{ sel }}</h3>
      <Dropdown
        :options="variations"
        :default="'Choose an option'"
        class="select"
        @input="getSelected"
      />
      
    </div>