How do display vue data of clicked element from v-for in modal

Viewed 590

This is how my json looks like. I display bunch of them in a v-for format and I am able to click on one of them. I would like to display the data from the element I clicked on in a modal.

[{
        "id": 1,
        "companyName": "test",
        "image": "https://mmelektronik.com.pl/wp-content/uploads/2017/10/Insert-logo.jpg.png",
        "location": "Warsaw",
        "salary": "10000",
        "skill": "Junior",
        "tags": "test",
        "jobDescription": "test",
        "title": "UI Designer"
    }

]    

Now I want to access only jobDescription and display it in the modal.

b-modal(hide-footer="", :id="id")
      template(#modal-title="")
        | Information
      .d-block.text-center
        p {{ want the jobDescription here }}
        b-button(variant="primary") Apply

This is how I open the modal.

  openModal(item) {
      this.offer = item;
      this.$bvModal.show(this.id);
    }

Component

  b-container
    b-card.joblist__post.mt-2(
      v-for="offer in filteredOffers",
      :id="id"
      :key="offer.id",
      @click="openModal"
    )
      .d-flex
        .joblist.d-flex.w-100
          .joblist__info.d-flex.align-items-center
            .company-logo.d-flex.align-items-center.mr-3
              b-img.logo(:src="offer.image")
            .joblist-name.d-flex.flex-column.text-left
              h5.mb-0.font-weight-bold {{ offer.title }}
              .located.d-flex.align-items-center.mt-2.justify-content-start
                b-icon.mr-2(icon="geo-alt-fill")
                p.m-0.text-secondary.joblist-span {{ offer.location }}
                b-icon.mx-2(icon="person-fill")
                p.m-0.text-secondary.joblist-span {{ offer.companyName }}
                b-icon.mx-2(icon="bar-chart-fill")
     

    b-modal(hide-footer="", :id="id")
      template(#modal-title="")
        | Information 
      .d-block.text-center
        p {{offer.jobDescription}}
      b-button(variant="primary") Ok


export default {
  data() {
    return {
      search: "",
    };
  },
  computed: {
    ...mapState({
      offers: (state) => state.offer.offers,
      loading: (state) => state.offer.loading
    }),
 
    filteredOffers(){
      return this.offers.filter((offer) => {
        return offer.title.match(this.search);
      })
      
    },

  },
  methods: {
    ...mapActions({
      fetchOffers: "fetch",
    }),
    openModal(item) {
      this.offer = item;
      this.$bvModal.show(this.id);
    }
  },
  mounted() {
    this.fetchOffers();
    this.id = this._uid;
},
  
};

2 Answers

Here's a simple approach you can take. Have a selectedItem attribute in data like so:

data: {
   return {
      selectedItem: {}
   }
}

and add an on click on the elements like so, where you assign the clicked object to selectedItem:

<button v-for="(e, i) in whateverDataArray" :key="i" @click="selectedItem=e">
    {{ e.companyName }}
</button>

Then simply pass the selectedItem as props to the modal and so when the modal appears, it'll show the props which was the clicked selectedItem!

Change your data to:

data() {
  return {
    search: "",
    offer: null
  };
},

Use the following in your template:

p {{ offer.jobDescription }}

And change the click handler to:

@click="openModal(offer)"

This suggestion from comments should work once offer is defined first in data and passed from the click. You do set offer in the openModal action.

Your modal should not be inside v-for. Take it out and hardcode an id:

b-modal(hide-footer="", id="offerModal")

Open it:

this.$bvModal.show('offerModal');
Related