Pop-up message on card selection using JavaScript, CSS, and PHP

I have a total of 6 cards displayed in my HTML. Each card, when clicked, should trigger a modal window to pop up (with additional information corresponding to that specific card).

After spending a day searching for a solution online, I've come here seeking your assistance as I'm unsure how to proceed.

My approach so far has been to create the HTML structure for the animal cards separately from the modal. The content within will be dynamically changed using PHP. Additionally, I need JavaScript to modify the modal window's CSS properties to absolute position upon clicking.

Is there someone who can advise on achieving this functionality with JavaScript?

HTML :

<div class="animal_card">
    <div class="card_title">
        <h3>title</h3>
    </div>

    <div class="card_image">
        <img src="image.img" alt="">
    </div>
    <div class="card_text">
        <div class="card_info">
            <div class="card_info_age">
                <h4>Age</h4>
                <p>14</p>
            </div>
            <div class="card_info_gender">
                <h4>Gender :</h4>
                <p>Female</p>
            </div>
        </div>
        <h4>Who am I</h4>
        <p>Description Text</p>
    </div>
</div> 

<div class="bg-modal">
            <div class="modal-content">

                <div class="modal-animal">
                    <h1>Animal Name</h1>
                    <button class="close" onclick="closeModal()">&times</button>
                    <div><img src="img/greciaprofile.jpg" alt=""></div>

                    <div class="animal-informations">
                        <div class="left">
                            <label for="">Age</label>
                            <p>14</p>
                            <label for="">Sexe</label>
                            <p>Female</p>
                        </div>
                        <div class="right">
                            <label for="">Description</label>
                            <p>
                                Text
                            </p>
                        </div>
                    </div>

                    <div>
                        <button class="main">Adopt</button>
                        <button class="secondary">Support</button>
                    </div>
                </div>
            </div>
        </div>

CSS :

.bg-modal {
    width: 100%;
    height: 100%;
    background-color: rgba(0,0,0,0.7);
    position: absolute;
    top: 0;
    left: 0;
    display: flex;
    justify-content: center;
}

.modal-content {
    position: absolute;
    margin-top: 5rem;
    width: 75vw;
    background-color: $white;
    border-radius: 15px;
}

Javascript :

const cards = document.querySelectorAll('.animal_card');
const modal = document.getElementsByClassName('bg-modal');

const onCardClick = async (e) => {
    const card = e.currentTarget;

    modal.style.position = 'absolute';
}

cards.forEach(card => card.addEventListener('click', onCardClick));

function closeModal() {
    modal[0].style.position = 'none';
}

Answer №1

const cards = document.querySelectorAll('.animal_card');
const modal = document.getElementsByClassName('bg-modal');

const getKeyMap = (modal) => {
 if (modal) {
    let i;
    let keyMap = {};
    for (i = 0; i < modal.length; i++) {
      const item = modal[i];
      const key = item.getAttribute('key');
      keyMap[key] = item;
    }
    
    return keyMap;
 }
 
 return null;
};

const modalMap = getKeyMap(modal);

const onCardClick = async (e) => {
    const card = e.currentTarget && e.currentTarget.getAttribute('key') || null;
    const selectedModal = modalMap[card] || null;
    
   if (selectedModal) {
     selectedModal.style.position = 'absolute';
   } 
}

cards.forEach(card => card.addEventListener('click', onCardClick));
.bg-modal {
    width: 100%;
    height: 100%;
    background-color: rgba(0,0,0,0.7);
    /* position: absolute; */
    top: 0;
    left: 0;
    display: flex;
    justify-content: center;
}

.modal-content {
    position: absolute;
    margin-top: 5rem;
    width: 75vw;
    background-color: $white;
    border-radius: 15px;
}
<div key="5" class="animal_card">
    <div class="card_title">
        <h3>title</h3>
    </div>

    <div class="card_image">
        <img src="image.img" alt="">
    </div>
    <div class="card_text">
        <div class="card_info">
            <div class="card_info_age">
                <h4>Age</h4>
                <p>14</p>
            </div>
            <div class="card_info_gender">
                <h4>Gender :</h4>
                <p>Female</p>
            </div>
        </div>
        <h4>Who am I</h4>
        <p>Description Text</p>
    </div>
</div> 

<div class="bg-modal" key="5">
            <div class="modal-content">

                <div class="modal-animal">
                    <h1>Animal Name</h1>
                    <button class="close">&times</button>
                    <div><img src="img/greciaprofile.jpg" alt=""></div>

                    <div class="animal-informations">
                        <div class="left">
                            <label for="">Age</label>
                            <p>14</p>
                            <label for="">Sexe</label>
                            <p>Female</p>
                        </div>
                        <div class="right">
                            <label for="">Description</label>
                            <p>
                                Text
                            </p>
                        </div>
                    </div>

                    <div>
                        <button class="main">Adopt</button>
                        <button class="secondary">Support</button>
                    </div>
                </div>
            </div>
        </div>

When dealing with your provided example, the variable modal within the onCardClick function is returning a collection of elements rather than a single element. By selecting the first element using modal[0], you can correct the position update. I've included an example for clarification.

If you intend to display varying modals based on the clicked card, you will typically need a method to track them. This approach may involve utilizing IDs, index positions, or other means. Please let me know if this explanation is helpful.

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

What might be the reason for npm live-server to cease detecting file updates?

Everything was working perfectly on my system, but now I'm facing an issue. I have the live-server version 0.8.1 installed globally. npm install live-server -g However, when I start it, I no longer see the "Live reload enabled." message in the brow ...

The Module Design Pattern in Jquery

In my project, there is a jQuery module pattern that I am having trouble understanding its purpose. There is also a custom plugin called jquery.skInit.js (function($) { $.fn.skInit = function() { return this.each(function(i,element) { var e = ...

What is the best way to set tab spacing within a textarea using ReactJS and Bootstrap?

One of my goals is to adjust the indentation within the text area by a specific amount when the Tab button is clicked. I am utilizing React JS and Bootstrap. Within the render function, I have set up a bootstrap text area as shown below: <textarea cl ...

A tool designed to create a function that can fetch information from a JSON file

Currently, I am working on a function that accepts arguments and combines them to form a line for searching data in a JSON file. To accomplish this, I have initialized a variable for the readFileSync and then added the function's arguments to it in or ...

I am encountering a problem with IE11 where I am unable to enter any text into my

When using Firefox, I can input text in the fields without any issues in the following code. However, this is not the case when using IE11. <li class="gridster-form" aria-labeledby="Gridster Layout Form" alt="Tile Display Input column Input Row ...

What is the best way to incorporate both images and text in PHP code?

I'm currently working on creating a large image call-to-action (CTA) for my new WordPress website. I've set up a new field group with the type "group" in ACF, and added some functions in PHPStorm. However, none of my images, text, or links are ap ...

How can I trigger the rendering of a component by clicking a button in a separate component?

I am currently facing a challenge in rendering a component with an "Edit" button that is nested within the component. I attempted to use conditional rendering in my code, but unfortunately, I am struggling to make it work as expected. Does anyone have any ...

Transferring a JavaScript variable to C# to execute an SQL SELECT query, then sending the returned result back to JavaScript

I am facing an issue while trying to execute code in my Code Behind to query my SQL Server using a JavaScript variable and then return the result as an Integer back to my Javascript. My approach involves running some Javascript code initially to obtain a ...

Implementing React router for dynamic page rendering

I'm struggling to make sense of a particular piece of code. Can someone provide an explanation? I'm particularly confused about the role of "props" in this section and how it is essential for the code to work correctly. If I remove "props," my co ...

Aligning the <div> list to the center of the webpage

Is there a way to center this list element on the page? It consists of three boxes that are all the same size, and I want them to always remain in the middle. body { width: 100%; } .boxes { display: block; margin: 0 auto; } .box-container ...

Upon refreshing the page, next.js 13's useSession() function fails to fetch session information

Currently, I am working on replicating an ecommerce site using nextjs 13. On the order page, I am utilizing useSession from next-auth/react to check if a user is signed in or not. Everything works fine when I navigate to the page through a link, but if I r ...

Offspring of div should have equal height without the top and bottom padding

Looking to ensure that the height of child divs matches the height of the parent divs. Currently, the divs expand as the page is resized. This is for search results, so there are multiple identical code blocks. function matchHeight() { $result = $(&a ...

ajax is providing identical data when called too frequently

Using my barcode scanner triggers the function below, but scanning multiple barcodes quickly results in duplicate data being processed. The issue seems to be related to the async setting - when it's false, the process slows down significantly. Is the ...

What is the optimal method for invoking a Javascript function via a hyperlink?

I'm looking to include links on my website that will activate a javascript function when clicked, and I do not want these links to be underlined. Additionally, I want the cursor to change to a standard pointer. What is the most effective way to achiev ...

converting time stamps to written text

Is there a JavaScript library available that can convert a timestamp (Date Java class value) to text? For example: Just two minutes ago 4 hours back 23 August 2009 Does such a library exist? If not, I'll take on the challenge of implementing it ...

Error connecting Node.js, express, and socket.io application

My app is a simple one that utilizes the socket.io module for node.js. Everything runs smoothly when I start my server with the command node express_server.js. However, when I try to open my page at http://localhost:8080 in the browser, Node.js throws an e ...

Positioning an individual element to the right side of the navigation bar in Bootstrap 5

I've been attempting to shift a single nav-item to the right side of the navbar, but I'm having trouble. My navbar is fairly basic, without a search tool or dropdown menu, as seen below: <nav class="navbar navbar-expand-lg bg-body-tertiar ...

Exploring the Use of data- Attributes in SVG Circle Elements

Looking for a way to dynamically update the color of a Circle element in your SVG when it is clicked? You can achieve this by using jQuery's .css() method in conjunction with the data-* attribute. CHECK OUT AN EXAMPLE: STYLING IN CSS svg { height ...

Looking to display an element right away, like a loading spinner, in Vue? If nextTick isn't doing the trick, here's what you can try

Imagine having a Vue component stored in a .vue file with a data member called isLoading: false. The template includes: <div v-show="isLoading" id="hey" ref="hey">Loading...</div> <button @click="loadIt()">Load it</button> Along w ...

Is there a way for me to invoke a different function that is located external to

I am currently in the process of setting up an event that triggers on any change within the form input class. import React, { useState } from "react"; DealerRegistration extends React.Component { state = { business_type : 'd ...