-1

I'm making a webpage with a lot of references. I want to open modal when pressed on one reference to show more data about that said reference. I achieved that with one reference, but now when I have more references inserted it wont open other modals but always the same one if I do it with class, if I leave id (yea I know, I wasn't thinking ahead and did this with id) it will only open the first one, others wont even open.

Here is my HTML code:

<!-- reference item -->
<div class="grid-item set-bg osobj" data-setbg="img/portfolio/1.jpg">
    <a id="myBtn"></a>
    <div id="myModal" class="modal1">
        <!-- Modal content -->
        <div class="modal1-content">
            <span class="close1">&times;</span>
            <h2>REFERENCE NAME</h2>
            <div class="post1-container">
                <div class="post1-content">
                    <p>nekitext</p>
                    <h3>Neki header</h3>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- reference item -->
<div class="grid-item set-bg osobj" data-setbg="img/portfolio/1.jpg">
    <a id="myBtn"></a>
    <div id="myModal" class="modal1">
        <!-- Modal content -->
        <div class="modal1-content">
            <span class="close1">&times;</span>
            <h2>REFERENCE NAME</h2>
            <div class="post1-container">
                <div class="post1-content">
                    <p>nekitext</p>
                    <h3>Neki header</h3>
                </div>
            </div>
        </div>
    </div>
</div>

and here is my JS:

var modal = document.getElementById('myModal');


// Get the button that opens the modal

var btn = document.getElementById("myBtn");
console.log(btn);

// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close1")[0];

// When the user clicks on the button, open the modal 
btn.onclick = function() {
    modal.style.display = "block";
}

// When the user clicks on <span> (x), close the modal
span.onclick = function() {
    modal.style.display = "none";
}

// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
    if (event.target == modal) {
        modal.style.display = "none";
    }
}

I've tried using onclick event to determine which tag is myBtn but in this case it only works for one modal. Others wont open or work.

PS: I have modals pinned on an image.

EDIT:

I know I have multiple IDs and that IDs are unique in HTML. I didn't plan this ahead enough as I thought I'll have only one item and now I have multiple and the system collapsed. There has to be a better way to do this than to give each item a different id, right?

EDIT2:

I DO NOT WANT TO USE IDs. The question is about javascript as to how to determine which modal to open. If I do it with classes it will open only one modal that always has the same content.

sesmajster
  • 752
  • 7
  • 32
  • 2
    Give unique id value to modals. Currently you have `myModal` for both of them. And then use those unique ids to determine the model open/close – Ankit Agarwal Jan 11 '19 at 12:58
  • @AnkitAgarwal I don't want to do this for every modal, I know I could do that but then I would have to write another script for every added reference. – sesmajster Jan 11 '19 at 13:11
  • @Liam yea I know, I didn't plan this ahead enough, I thought I will only have one item and not I have multiple. – sesmajster Jan 11 '19 at 13:12
  • 1
    "There has to be a better way to do this than to give each item a different id, right?" - No. – markmoxx Jan 11 '19 at 13:17
  • Possible duplicate of [Does ID have to be unique in the whole page?](https://stackoverflow.com/questions/9454645/does-id-have-to-be-unique-in-the-whole-page) – Liam Jan 11 '19 at 13:18
  • @markmoxx but this would then mean that I have to write new js code for each item I would like to add. That dosen't seam right to me – sesmajster Jan 11 '19 at 13:19
  • 1
    @Liam you don't understand the question. I don't want to use IDs. If I do this with classes it opens only one modal and the modal content is always of one modal. – sesmajster Jan 11 '19 at 13:20
  • 1
    Liam is right. Use classes. In addition use **unique** IDs or other attributes to identify which button opens which modal. e.g. `` – hsan Jan 11 '19 at 13:45
  • @hsan read the question again. I ALREADY KNOW THIS. I do not want to have 1000 different id's to search from in javascript one day. – sesmajster Jan 11 '19 at 13:47
  • @Liam there is no other way of explaining my problem. If you can't solve it please leave it alone. I explained more than enough to understand. – sesmajster Jan 11 '19 at 14:00
  • 1
    You are too focused on the ids and classes to see that the problem is in javascript. It's a matter of algorithm I should use. If this was any other language than js I would have done this in a matter of minutes. – sesmajster Jan 11 '19 at 14:02
  • 1
    @user3029612 Maybe try to be a bit more appreciative when people help you for free. Anyways, you don't need to type 1000 IDs in your js. Find all the relevant buttons (e..g `document.querySelectorAll('.modalButton')`), loop through them and add the same listener to each of them. This listener uses the button's attributes to determine which modal to show (e.g. `button.getAttribute('data-modal-id')`). – hsan Jan 11 '19 at 14:35

1 Answers1

3

You will want to give each button a common class name, i.e.:

<a class="myButton"></a> // For the buttons

And then loop through those (and the closing span's) and add an event listener to each one, i.e.:

const buttons = document.querySelectorAll(".myButton");
const spans = document.querySelectorAll(".close1");

for(let i=0; i< buttons.length; i++) {
    buttons[i].addEventListener("click", openModal);
}

for(let i=0; i< spans.length; i++) {
    spans[i].addEventListener("click", closeModal);
}

function openModal(e) {
    e.preventDefault();
    const currentModal = e.currentTarget.parentNode.getElementsByClassName("modal1")[0];
    currentModal.style.display = "block";
}

function closeModal(e) {
    const currentModal = e.currentTarget.closest(".modal1");
    currentModal.style.display = "none";
}

This will find the closest modal to the button that was clicked, and toggle that instead of a hardcoded reference to a modal ID.

EDIT - See it in action

Hope that helps!

Gabor Szekely
  • 1,108
  • 5
  • 14