Creating a unique Vue.js modal window for every individual product

Currently, I am in the process of creating a small online store using Vue.js. Within this store, I have a variety of products each with unique names and prices. In order to provide more information about each product, I have included a "Details" button.

My goal is to have a modal window pop up displaying the name and price of the product when the corresponding "Details" button is clicked. However, I am encountering an issue where only the data from the first product is being displayed, instead of the specific product that was clicked on. I am aware that I need to utilize "this" in order to achieve this functionality, but I have not been able to find a solution yet. I am utilizing Vue.js along with the <slot></slot> feature in the modal.

Within my methods:

showModal() {
  let myModal = new bootstrap.Modal(
    document.getElementById('exampleModal'),
    {}
  );
  myModal.show();
},

Here is how my button is set up:

<button @click="showModal">Details</button>

Answer №1

Assuming you are utilizing Bootstrap 5 based on the syntax provided.

It would be beneficial to create a Vue component for the product details modal where you can pass a product as a prop. This way, the content of the modal can dynamically change based on the selected product.

If you are iterating over a list of products, you can implement something similar to the following:

<!-- ProductList.vue -->
<template>
    <ul>
        <li v-for="product in products" :key="product.id">
            <span>{{ product.name }}</span>
            <button @click="showDetails(product)">Details</button>
        </li>
    </ul>
    <portal to="modals" v-if="showModal">
        <product-details-modal
            :product="product"
            :show="showModal"
            @hide="showModal = false"
        />
    </portal>
</template>

<script>
import ProductDetailsModal from './ProductDetailsModal.vue';

export default {
    components: {
        ProductDetailsModal,
    },
    data() {
        return {
            product: null,
            products: [],
            showModal: false,
        };
    },
    methods: {
        showDetails(product) {
            this.product = product;
            this.showModal = true;
        },
    },
    mounted() {
        // Fetch products from API or other source
        // Save array of products to this.products
    },
};
</script>

When the details button is clicked, the selected product becomes a data item and sets showModal to true. The product is then passed to the modal component for displaying the details:

<!-- ProductDetailsModal.vue -->
<template>
    <div class="modal fade" id="product-details-modal" ref="modalElement">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="product-details-modal-title">Product Details</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <p>Product name: {{ product.name }}</p>
                    <p>Product price: {{ product.price }}</p>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
import { Modal } from 'bootstrap';
 
export default {
    data() {
        return {
            modalElement: null,
        };
    },
    mounted() {
        this.modalElement = new Modal(this.$refs.modal);

        this.modalElement.addEventListener('hide.bs.modal', this.$emit('hide'));

        if (this.show) {
            this.modalElement.show();
        }
    },
    props: {
        product: {
            required: true,
            type: Object,
        },
        show: {
            default: false,
            required: false,
            type: Boolean,
        },
    },
    watch: {
        show(show) {
            if (this.modalElement) {
                show ? this.modalElement.show() : this.modalElement.hide();
            }
        },
    },
};
</script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The error message "Uncaught ReferenceError: require is not defined" is commonly encountered when using Webpack

Despite countless similar questions, none have provided a solution to my issue because the underlying problem seems to elude me. I am attempting to bundle files for the browser using webpack 4.26.1, but no matter what I try, I consistently encounter the er ...

What is the best way to determine if two external values are equal within a mongodb criteria object?

Consider the following collection: {id: 1, name:"abc"}, {id: 2, name:null} When testing a property, I typically use this method: db.collecton.find({name:"abc"}, {name:1}); // This will return the first document. Now, I want to incorporate two external ...

What is the most popular method for namespacing AngularJS modules?

I am new to AngularJS and currently exploring different ways to namespace modules in my application. One challenge I face is the need to integrate my Angular app into a designated placeholder div within a third-party website (which may also use Angular), ...

Retrieve information from the script tag

Is there a method to extract data from a <script> tag, specifically targeting the 30-minute table on AEMO's website (AEMO Website)? In order to access the data table, I attempted to scrape it but encountered an issue where the button and table ...

What is the best way to deliver an HTTP request from the controller to my Ajax function?

Is there a way to send HTTP OK and error responses from the controller to my AJAX request? For example, using HttpStatusCode.OK and HttpStatusCode.BadRequest. When I inspect in my browser it shows impresion.js 304 not modified. $(document).ready(functi ...

Is it possible to divide a text string into distinct arrays using spaces?

One method I am familiar with for splitting a string involves using the .split() method, like so: function split(txt) { return txt.split(' '); } When executed, this function would return ['hello', 'world'] if provided wi ...

Can you explain the process of accessing data from [[PromiseValue]] while utilizing React hooks?

My current challenge involves fetching data from an API and utilizing it in various components through the Context API. The issue arises when I receive a response, but it's wrapped under a Promise.[[PromiseValue]]. How can I properly fetch this data ...

Error in cloned selections with bootstrap-selectpicker showing one less item

When duplicating a bootstrap-select dropdown, the duplicate dropdown appears to be offsetting selections by 1. For example, if the second option is clicked, the first one is actually selected. Here is an illustration: If "New Castle" is clicked in the ...

Create genuinely private methods within an ES6 Module/Class specifically for use in a nodejs-exclusive environment, ensuring that no data is exposed

Although there are no true private methods within ES6 classes, I stumbled upon something interesting while experimenting... While it's not possible to completely hide object properties, I attempted to follow OOP principles by dividing my classes into ...

Vue: Exploring the intricacies of detecting reactive object changes within a v-for loop

After reviewing this documentation, I encountered challenges implementing the suggested solution. I currently have a v-for loop iterating over objects. These objects are subject to dynamic changes and I require these modifications to be reflected reactive ...

What causes the server to give an incorrect response despite receiving a correctly read request?

After setting up a new project folder and initializing NPM in the Node.js repl, I proceeded to install the Express package. In my JavaScript file, I included the following code: const express = require('express'); const app = express(); ...

What is the best way to use toggleClass on a specific element that has been extended

I have been experimenting with this code snippet for a while. The idea is that when I hover my mouse over the black box, a red box should appear. However, it doesn't seem to be working as expected. Could someone please review this script and let me k ...

Tips for utilizing the .clone() method within a loop or for each individual element of an array

Due to certain requirements, I find myself in a situation where I need to customize the invoice template within the software I use. The invoices are generated in HTML format, prompting me to consider utilizing Stylish and Grease Monkey for this task since ...

Update the button text dynamically when clicked without using an identifier or a class

If we take a look at my button in the following code: <input type="button" value="BLUE" name="button_blue" /> My goal is to have the value="BLUE" changed to value="RED" or any other desired value when the button is clicked. ...

Javascript - Could anyone provide a detailed explanation of the functionality of this code snippet?

Ever since joining a new company 9 months ago, I've been encountering this line of code in JavaScript. It seems to work fine and I've been incorporating it into my coding style to align with the previous developers. However, I'm not entirely ...

What is causing my background image to move upward when I include this JavaScript code for FlashGallery?

There's an issue on my website where adding a flash gallery script is causing the background image to shift unexpectedly. You can view the affected page here: The culprit seems to be the "swfobject.js" script. I've identified this by toggling t ...

I never rely on the browser back button, I prefer to remain on the same page

Being new to Angular, I have come across the following code snippet: HTML template: <a href="" ng-click="goToCategories();">See categories</a> JS File: $scope.goToCategories= function () { CategoriesService.getCateg ...

Determine in Typescript if a value is a string or not

In my code, I have a component: export type InputData = string | number | null; interface InputData { data?: string | number | null; validate: boolean; } const App: React.FC<InputData> = ({ data = '', validate = true, }) => ...

What is the Best Time to Renew a JWT Token?

Currently, I am utilizing JWT-Auth in my Laravel backend to secure my API routes using a token. However, I have noticed that after a certain period of time, the token becomes invalid and I encounter the error 401 Unauthorized. It seems like I need to refre ...

Jsonip.com is providing both internal and external IP addresses

I'm utilizing to retrieve the IP address of users. In some cases, it is returning both an internal and external IP as a string separated by commas. I am interested in only obtaining the external IP address. Can I assume a specific order for the retur ...