Search code examples
javascriptvue.jsvuejs2vue-componentbootstrap-vue

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


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;
},
  
};


Solution

  • 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');