I have a problem with modal popup images. I have a list of images and tried to use this code (with some changes): https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_modal_img But it works only for the first message. How can I make it work for all messages from the gallery?
<div>
<div class="portfolio-overlay">
<img src="img/portfolio/Transeco-small.jpg">
<div class="portfolio-image-overlay image-overlay-content">
<div class="portfolio-icons">
<i class="icon-zoom-in open-big"><img src="img/portfolio/Transeco-big.jpg" class="img-closed"></i>
<i class="icon-link"></i>
</div>
</div>
</div>
</div>
<div>
<div class="portfolio-overlay">
<img src="img/portfolio/Transeco-small.jpg">
<div class="portfolio-image-overlay image-overlay-content">
<div class="portfolio-icons">
<i class="icon-zoom-in open-big"><img src="img/portfolio/Transeco-big.jpg" class="img-closed"></i>
<i class="icon-link"></i>
</div>
</div>
</div>
</div>
<div>
<div class="portfolio-overlay">
<img src="img/portfolio/Transeco-small.jpg">
<div class="portfolio-image-overlay image-overlay-content">
<div class="portfolio-icons">
<i class="icon-zoom-in open-big"><img src="img/portfolio/Transeco-big.jpg" class="img-closed"></i>
<i class="icon-link"></i>
</div>
</div>
</div>
</div>
<!-- The Modal -->
<div class="modal myModal">
<span class="close">×</span>
<img class="modal-content img01">
</div>
// Get the modal
var modal = document.querySelector(".myModal");
// Get the image and insert it inside the modal - use its "alt" text as a caption
var img = document.querySelector('.open-big');
var modalImg = document.querySelector(".img01");
var probaa = document.querySelector('.open-big img');
img.onclick = function(){
modal.style.display = "block";
modalImg.src = probaa.src;
}
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
There are no errors in console, but it works only on firs image...
var img = document.querySelector('.open-big');
document.querySelector only selects a single element, in this case the first element with the class open-big
in order to select all elements you must use document.querySelectorAll
then you can iterate over that set an add event listeners to each one:
var imgs = document.querySelectorAll('.open-big');
for (i = 0; i < imgs.length; ++i) {
imgs[i].onclick = function(){
modal.style.display = "block";
modalImg.src = probaa.src;
}
}
you CANNOT use normal array methods on a node collection though. so, imgs.forEach will not work. There is a somewhere complicated workaround though:
[].forEach.call(imgs, function(img) {
// do whatever
});
There is more information at this link on css tricks.
Related
I want to use a selector to select every image on the page for putting into the modal without rewriting the entire script for each image. I feel like this a is a dumb question but I keep striking out trying different things. Right now I'm using var img = document.getElementById("article01"); to select one image because that's all you can do with getElementById. So I want to select both the images listed so that I'm not rewriting the entire script for each image because there will be many more on the page. I tried using getelementbyclass and tagname but I think I'm stuck.
HTML:
<!-- Trigger the Modal -->
<img id="article01" src="/images/article1.PNG" alt="" style="width:100%;max-width:300px">
<img id="article01-2" src="/images/article1-2.PNG" alt="" style="width:100%;max-width:300px">
<!-- The Modal -->
<div id="modal1" class="modal">
<!-- The Close Button -->
<span class="close">×</span>
<!-- Modal Content (The Image) -->
<img class="modal-content" id="img01">
<!-- Modal Caption (Image Text) -->
<div id="caption"></div>
</div>
Javascript:
<script>
// Get the modal
var modal = document.getElementById("modal1");
*var img = document.getElementById("article01");*
var modalImg = document.getElementById("img01");
var captionText = document.getElementById("caption");
img.onclick = function() {
modal.style.display = "block";
modalImg.src = this.src;
captionText.innerHTML = this.alt;
}
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
</script>
You can use document.querySelectorAll() to get a nodeList of all of the images. For example, if you created your list of images as such:
<img class="selectable" src="article-1" />
<img class="selectable" src="article-2" />
<img class="selectable" src="article-2" />
You can add an event listener to each using ...
document.querySelectorAll('img.selectable')
.forEach((img) => {
img.addEventListener('click', (e) => showModal(e.target)); //or use img.onclick = ...
});
Here is a link to a CodePen showing a demo of how to do this...
Here's what i got from your post. I think what you are looking for is document.querySelector()
<!-- Trigger the Modal -->
<img alt="this is a caption" src="https://livebrooks.com/wp-content/uploads/2017/07/fpo.gif" style="width:100%;max-width:300px">
<img alt="this is the second caption" src="https://livebrooks.com/wp-content/uploads/2017/07/fpo.gif" style="width:100%;max-width:300px">
<!-- The Modal -->
<div id="modalWrap" class="modal">
<!-- The Close Button -->
<span class="close" onclick="document.querySelector('#modalWrap').remove()">×</span>
</div>
for (var i of document.querySelectorAll("img")) {
makeModal(i.src, i.getAttribute("alt"));
}
function makeModal(src, caption) {
//modal wrap
var modalWrap = document.querySelector("#modalWrap");
//img
var imgElement = document.createElement("img");
imgElement.src = src;
imgElement.style.maxWidth = "300px";
//caption
var captionElement = document.createElement("p");
captionElement.innerText = caption;
//adding elements to modalWrap
modalWrap.appendChild(imgElement);
modalWrap.appendChild(captionElement);
}
I have in my site a lot of images and through each one, you can open a different iframe that includes an interactive ad that is related to the image from where you opened it.
The thing is that with the code that I´m using, I can only open the first iframe.
Here is a demo of my site and what I´m trying to do. You can see that if you click on the images, you will only me able to open the first iframe:
http://kickads.mobi/richmediagallery/index_test_iframe.html
I want to know if someone could help me to solve this.
The JS code that I´m using is this one:
<script>
// Get the modal
var modal = document.getElementById('MyModal');
// Get the button that opens the modal
var div = document.getElementById("myDiv");
// Get the button that opens the modal
var img = document.getElementById("myImg");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks on the button, open the modal
div.onclick = function() {
modal.style.display = "block";
}
// When the user clicks on the button, open the modal
img.onclick = function() {
modal.style.display = "block";
}
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
var freezeVp = function(e) {
e.preventDefault();
};
</script>
And here is a demo of how the image opens the iframe:
<div id="ad1" class="portfolio-item deporte col-md-3">
<div class="portfolio-box">
<div class="portfolio-image-wrap">
<img id="myImg" src="img/portfolio/image.jpg" alt="" />
</div>
<div class="portfolio-caption-mask" id="myDiv">
<div class="portfolio-caption-text">
<div class="portfolio-caption-tb-cell">
<h5 class="alt-title">Puzzle ad</h5>
<p>Nike Made to fly</p>
</div>
</div>
</div>
</div>
</div>
<div id="MyModal" class="modal">
<span class="close">×</span>
<div class="contenido">
<iframe style="height: 480px; width: 320px" src="http://kickads.mobi/test/ad" frameborder="0"></iframe>
</div>
</div>
As it's been said you cannot call multiple elements using same IDs.
Two elements cannot have the same ID.
If you want to assign multiple elements in the same variable I recomend you to use : var div = document.getElementsByClassName("name");
More details here.
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">×</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">×</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.
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!
I would like to get the other icons to work how the "Operations Management" is working. But I want it to say different things.
PLEASE HELP :(
Here is my fiddle : https://jsfiddle.net/RonaLochner/p4kt6oy1/
The Code:
<div class='circle-container'>
<a href='#' class='center'>
<h4 style="text-align:center;">Microsoft Dynamics 365</h4>
</a>
<div id="operations-management">
<img src='http://www.businesscentral.co.za/wp-content/uploads/2018/08/Business-Solutions-Icon2.png'>
</div>
<div id="reporting">
<img src='http://www.businesscentral.co.za/wp-content/uploads/2018/08/Business-Solutions-Icon3.png' id="myBtn">
</div>
<div id="supplychain">
<img src='http://www.businesscentral.co.za/wp-content/uploads/2018/08/Business-Solutions-Icon4.png' id="myBtn">
</div>
<div id="sales">
<img src='http://www.businesscentral.co.za/wp-content/uploads/2018/08/Business-Solutions-Icon5.png' id="myBtn">
</div>
<div id="financial">
<img src='http://www.businesscentral.co.za/wp-content/uploads/2018/08/Business-Solutions-Icon6.png' id="myBtn">
</div>
<div id="project">
<img src='http://www.businesscentral.co.za/wp-content/uploads/2018/08/Business-Solutions-Icon1.png' id="myBtn">
</div>
</div>
The model:
<div id="myModal" class="modal">
<!-- Modal content -->
<div class="modal-content">
<span class="close">×</span>
<p>OPERATIONS MANAGEMENT</p>
</div>
</div>
The Script
<script>
// Get the modal
var modal = document.getElementById('myModal')
// Get the button that opens the modal
var btn = document.getElementById("operations-management");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks 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";
}
}
</script>
I have tried to target using different ID's but not sue how to fix this.
So first thing you want to do is add a class to each of the icons/buttons like so;
<div class="toggle" id="operations-management">
<img src='http://www.businesscentral.co.za/wp-content/uploads/2018/08/Business-Solutions-Icon2.png'>
</div>
Then you want to call them using querySelectorAll and convert it to array
// Get the button that opens the modal
var btns = Array.from(document.querySelectorAll(".toggle"));
We convert it to array because querySelectorAll returns a node list but we need an array to iterate through all the buttons so thats where the Array. So then we itierate over all of the buttons and add a event listener that points to a new function showModal
btns.forEach(function(btn) {
btn.addEventListener("click", showModal);
});
The showModal function will show the modal.
function showModal(e) {
modal.style.display = "block";
}
now you have you probably want to have different content in each modal right? I would make the p tag in your modal with an id and then using the (e) variable from the showModal function I would find the id of the button and then have an if statment that would change the modal p tag depending on the id that is passed from e. (if you set console.log(e) just before I set the modal.style.display you will see an object and there you can find the id.
My second, third and so on buttons which open modal, doesn't work and I can't figure out the problem.
I think is a logic problem in my javascript code for sure, but I can't find a way to solve it ... maybe you can help me.
var modal = document.getElementById('myModal');
// Get the image and insert it inside the modal
var img = document.getElementById('myImg');
var modalImg = document.getElementById('img01');
var buton = document.getElementById('continut');
buton.onclick = function() {
modal.style.display = "block";
modalImg.src = img.src;
}
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
//When the user clicks on <span> (X), close the modal
span.onclick = function() {
modal.style.display = "none";
}
You have a demonstration on jsfiddle
Thanks in advance !
https://jsfiddle.net/qschptk9/1/
I've got 2 negative votes, and NO ONE Helped me.
Ok i've Changed the ID's, but still doesn't work, because getElementsByClassName return an array of elements ...
id should be unique so you should't use it for 2 elements
you use the same id 2 times for many elemets (button, modal, img, modalimg)
you can change the id's for all those elements (hard coded option), or you can add a class for both and add click event for both but you will need to differentiate each modal and each img (you can do this by passing ids for these elements in a function)
Edit
this is an optimized solution that i would use for you want to do
I added only one modal and used onclick event for each button to pass the header text and the img id to a function that show the appropriate modal
here is the HTML
<div class="portfolio_content">
<div class="row" id="portfolio">
<div class="col-xs-12 col-sm-4 websites responsive webDesign">
<div class="portfolio_single_content">
<img id="myImg1" src="http://www.w3schools.com/css/img_fjords.jpg" alt="title" />
<div>
<!--Continut because from here we access the content of this preview photo-->
<div class="continut">
<p>Portfolio Website</p>
<button class="seeBtn" onclick="showModal('Portfolio Website','myImg1')">
button
</button>
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-4 appsDevelopment">
<div class="portfolio_single_content">
<img id="myImg2" src="http://www.w3schools.com/css/img_fjords.jpg" alt="title" />
<div>
<!--Continut because from here we access the content of this preview photo-->
<div class="continut">
<p>Pomodoro Clock</p>
<button class="seeBtn" onclick="showModal('Pomodoro Clock','myImg2')">
button
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!--The modal-->
<div class="modal" id="myModal">
<!-- Modal content -->
<div class="modal-content">
<!--Modal header-->
<div class="modal-header">
<span class="close" id="close">CLOSE X<i class="fa fa-times" aria-hidden="true"></i></span>
<h2 id="modal_h1"></h2>
</div>
<div class="modal-body">
<img class="modal-image" id="img01">
</div>
<div class="modal-footer">
<h3>External link</h3>
</div>
</div>
</div>
and here is the js code
var modal = document.getElementById('myModal');
var modalImg = document.getElementById('img01');
var modalHeaderTxt = document.getElementById('modal_h1');
function showModal(header_txt,img_id){
// Get the image and insert it inside the modal
var img = document.getElementById(img_id);
modalImg.src = img.src;
modalHeaderTxt.innerHTML = header_txt;
modal.style.display = "block";
}
// Get the <span> element that closes the modal
var span = document.getElementById("close");
//When the user clicks on <span> (X), close the modal
span.onclick = function() {
modal.style.display = "none";
}
Demo
and here is the hard coded option (i don't recommend it)
var modal = document.getElementById('myModal');
var modal2 = document.getElementById('myModal2');
// Get the image and insert it inside the modal
var img = document.getElementById('myImg');
var img2 = document.getElementById('myImg');
var modalImg = document.getElementById('img01');
var modalImg2 = document.getElementById('img02');
var buton = document.getElementById('continut');
var buton2 = document.getElementById('continut2');
buton.onclick = function() {
modal.style.display = "block";
modalImg.src = img.src;
}
buton2.onclick = function() {
modal2.style.display = "block";
modalImg2.src = img2.src;
}
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
var span2 = document.getElementsByClassName("close")[1];
//When the user clicks on <span> (X), close the modal
span.onclick = function() {
modal.style.display = "none";
}
span2.onclick = function() {
modal2.style.display = "none";
}
Demo
You have two id's with same name hence first id will be picked everytime. The ids must be unique. Please try changing the id and it should work.
Or you can try to change it into class names and then work with classes
You need to change the id's for the models to classes. You can't assign multiple id's in HTML. That's why your code works only for one modal.
Change your id's to classes like this:
<div class="modal myModal">
i think you have more than one element that has id='myModal'
, in that case you should do:
var modal = document.getElementById('myModal')[correct element number]
example :
document.getElementById('myModal')[0] //for the first element
document.getElementById('myModal')[1] //for the second element
and so on...
for each button