I generate procedurally a div containing an image and an input file in an HTML file.
The ID of all the element change by 1 each time. Here is the sample of the div that is repeated with K as the number that is incremented each time I generate this div, so every item has a different ID.
<div>
<img id="frame-add-K" src="" class="img-fluid" />
</div>
<label style="border: 2px solid black" for="img-input-K" class="btn">Select Image</label>
<input type="file" name="image_content_K" id="img-input-K" style="display:none; visibility:hidden;" accept="image/*" />
The div containing the image is supposed to work as a preview. So when the user input his image, I want to change the img source to the newly updated image.
I have tried something like this using jquery:
$(document).ready(function() {
$("input[id^=img-input-]").on("input", function() {
var id_input = $(this).attr('id').substring('img-input-'.length); //get me only the number at the end
$("#frame-add-" + id_input).attr("src", event.target.files[0]);
});
});
But id_input is always egual 1, so the change only affect my first div and change always the first image source. Moreover "event.target.files[0]" doesn't work there.
I ideally would like to make a generic function using jquery that would get the K of the element changed et update the image src associated with this K but I am open to any suggestion solving my issue.
Rather than use any ids, you can select the image which is the child of the div element two before the input.
const theImg = $(this).prev().prev().find("img");
Related
I have a page that show lots of photos which can be opened with lightgallery.js
I've already made some custom HTML caption which works fine. But now I want to add a label to the image itself. How can I do that?
I will show an example of what my photos page looks like:
When you open an image this is what it looks like:
The left part is a custom HTML caption which I linked with this attribute: data-sub-html.
Example code of my looped code:
$photomasonry .= '
<div class="tile scale-anm noselect">
<a href="https://studio.website.nl/'.$getphotos['preview'].'" data-sub-html="#caption'.$imgcount.'" class="item masonrytile" data-src="https://studio.website.nl/'.$getphotos['preview'].'">
<img src="https://studio.website.nl/'.$getphotos['preview'].'"/>
<span class="idlabel">'.$getphotos['id'].'</span>
<span class="sizelabel">'.$size.'</span>
</a>
</div>';
$photomasonry .= '
<div id="caption'.$imgcount.'" style="display:none">
<img src="https://studio.website.nl/images/logo.png">
<h4 class="subhtmlh4">Maak iets moois met deze foto</h4>
<div class="gallerypopupbtns">
<button class="btnstyle purplebtn" type="button" name="button">Maak iets moois</button>
</div>
</div>';
$imgcount++;
But now I want this purple size icon (L, XL, XX) as a label on the image when lightgallery is opened. How can I do this? The html of the lightgallery is only generated after the page is loaded.
I want to add an element inside this part:
<div class="lg-img-wrap">
<img class="lg-object lg-image" src="https://studio.website.nl/images/photos/previews/preview-bb58317c8d05e29b32963e7a295a5b9f.jpg">
</div>
But not just that, the content is dynamic, so display the correct size for the correct image. I already created this for the photo overview page but not when clicking a photo.
According to the lightgallery docs, you can use the event lgAfterOpen to execute code once the gallery is opened. However, lightgallery makes this slightly difficult as you can't access the image clicked on from this event, but you can access it from the event lgBeforeOpen. With this in mind, I'd accomplish this by doing two things.
Firstly, add the size as a data attribute of each image:
<img src="https://studio.website.nl/'.$getphotos['preview'].'" data-size="'.$size.'"/>
Secondly, add the following functions when initialising lightgallery:
// example gallery definition
const lg = document.getElementById('custom-events-demo');
// add the following functions
lg.addEventListener('lgBeforeOpen', (event) => {
//add datasize property to target so it can be accessed in the afterOpen function
event.target.dataset.size = event.explicitOriginalTarget.dataset.size;
});
lg.addEventListener('lgAfterOpen', (event) => {
// get size from data attribute
var size = event.target.dataset.size;
// get the .lg-img-wrap div to append size to
var imgWrap = document.querySelector(".lg-container.lg-show .lg-img-wrap");
// create and append span
var sizeSpan = document.createElement("span");
sizeSpan.classList.add("sizelabel");
sizeSpan.innerHTML = size;
imgWrap.appendChild(sizeSpan);
});
//initialise lightgallery
lightGallery(lg);
You may be using a different version of lightgallery, but when I tested this the .lg-img-wrap element was a picture element not a div, so I replaced the last line of the event listener function with the following to get the size to show:
imgWrap.parentElement.appendChild(sizeSpan);
You might need a bit of extra CSS to position the size span as you wish, but just to get it to show all you need is:
.sizelabel {
position: relative;
}
Note: I don't think this will work if you navigate to a different image from within lightgallery as it won't update the size, and in fact the size might just get removed. To fix this you'd probably need to do something using the lgAfterSlide event and the index of the image, but from your screenshot it looks like you don't expect the user to scroll through images within lightgallery anyway so this may not be an issue.
I have the current HTML code:
<div class="container" onMouseOver"testfunction(this)">
<img id=test1 />
<div id=test2>
<iframe id=test3></iframe>
</div>
</div>
and the current Javascript function:
// This way every container in the page change always the first id=image of the page
function testfunction(obj)
{
$('#test1').css("display","none");
}
How can I get the current object image id, is it possible using this type of setup?
already tried a few options but none of them works properly:
$('#' + 'obj.test1').css("display","none");
$(obj.test1).css("display","none");
I don't quite understand what you actually want but I hope this answers.
Note: It's important that the img element is the first one inside the div with the "container" class.
If you want the id value of the img:
function testfunction(x){
var id = x.children["0"].id;
console.log(id);
}
If you want the img to disappear:
function testfunction(x){
x.children["0"].style.display="none";
}
I have three clickable images. One image on the first row, two images on the second row. The image on the first row is a reflection of whichever image on the second row was last clicked. I can make the image on the second row modify the src of the image on the first row, but am having difficulty modifying the onclick parameter of the anchor tag. I can't just change the href of the first image, it has to actually mimic the clicking of the second row image. Here's my code, along with by a jsfiddle of it:
https://jsfiddle.net/2hgzmnmb/
<a onclick="document.getElementById('image1').click();" id="previewLink"><img id="previewImage" src="http://i.imgur.com/UevhwuA.png"></a>
<br><br>
<a id="image1" onclick="document.getElementById('previewImage').src='http://i.imgur.com/UevhwuA.png';alert('1')"><img src="http://i.imgur.com/UevhwuA.png"></a>
<a id="image2" onclick="document.getElementById('previewImage').src='http://i.imgur.com/121fy0E.png';alert('2')"><img src="http://i.imgur.com/121fy0E.png"></a>
I want to add the following: document.getElementById('previewLink').onclick='document.getElementById('image1').click();' to the onclick parameter for the first image on the bottom row, and: document.getElementById('previewLink').onclick='document.getElementById('image2').click();'
to the second image on the bottom row, so the image on the first row will not only look like whichever image was last clicked on the second row, but will also mimic the actual click. Right now, obviously from the code, it will only mimic clicking the first image on the second row, no matter what image was last clicked, and I'm thinking it's because my syntax isnt correct when I try to modify the onclick property of the anchor tag for the image on the first row.
I also tried doing this with variables but got a bit tied in knots.
Any ideas on how I could go about doing this? I'm close, just not there yet.
Thanks!
Fiddle: https://jsfiddle.net/2hgzmnmb/1/
this: document.getElementById('previewLink').onclick='document.getElementById('image1').click();'
should be:
document.getElementById('previewLink').onclick=this.onclick
because onclick attribute is actually running a JS code, so if you pass a string there, it will interpret it as just a string.
onclick='document.getElementById('image1').click();' is the same as the string "document.getElementById('image1').click();", it does nothing.
add the line below to each anchor tag in the second row
document.getElementById('previewLink').related_id=this.id
<a onclick="if(document.getElementById(this.related_id)!=null){document.getElementById(this.related_id).click()};" id="previewLink"><img id="previewImage" src="http://i.imgur.com/UevhwuA.png"></a>
<br><br>
<a id="image1" onclick="this.related_id=this.id;document.getElementById('previewImage').src='http://i.imgur.com/UevhwuA.png';alert('1');document.getElementById('previewLink').related_id=this.id"><img src="http://i.imgur.com/UevhwuA.png"></a>
<a id="image2" onclick="this.related_id=this.id;document.getElementById('previewImage').src='http://i.imgur.com/121fy0E.png';document.getElementById('previewLink').related_id=this.id;alert('2')"><img src="http://i.imgur.com/121fy0E.png"></a>
I'd remove the inline handlers and use addEventListener() instead - except for demo purposes I've left your alert() messages in the inline onclick attributes to simulate the click behaviour that you want clicks on the preview image to mimic.
By putting the logic into JS in a <script> element you'll find it much easier to maintain because you can format the code in a readable manner.
Then simply use a variable to keep track of what the currently selected image is:
// the following JS should be in a script element at the end of the body
// and/or wrapped in a window onload handler
function imageClick(e) {
currentImage = e.currentTarget;
document.getElementById("previewImage").src = currentImage.querySelector("img").src;
}
var images = document.querySelectorAll(".image");
for (var i = 0; i < images.length; i++) {
images[i].addEventListener("click", imageClick);
}
var currentImage = images[0]; // default to first image
document.getElementById('previewLink').addEventListener("click", function() {
currentImage.click();
});
<a id="previewLink"><img id="previewImage" src="http://i.imgur.com/UevhwuA.png"></a>
<br><br>
<a id="image1" class="image" onclick="alert('1')"><img src="http://i.imgur.com/UevhwuA.png"></a>
<a id="image2" class="image" onclick="alert('2')"><img src="http://i.imgur.com/121fy0E.png"></a>
Note also that I added a class to your lower images in order to make it easy to process them in a loop to add their click handler. This is optional, you could select by id instead with .querySelectorAll("#image1,#image2").
In my function I would like to take an image add a dynamically created caption then wrap it all neatly in a div.
Before:
<img src="whatever" />
After:
<div class="imageBlock">
<img src="whatever" />
<span class="caption">The Caption</span>
</div>
This is what I currently have:
var imageCaption = '<span class="caption">'+array[1]+'</span>'
$(this).after(imageCaption).wrap('<div class="imageBlock '+array[0]+'" />');
This is working BUT is placing the span outside of the closing div tag.
You have to pay attention to what this actually refers to.
To get what you want just reverse the order,
var imageCaption = '<span class="caption">'+array[1]+'</span>'
$(this).wrap('<div class="imageBlock '+array[0]+'" />').after(imageCaption);
This is because your object that is being passed is the original image tag. Originally you call after on your tag so it does that correctly, but what gets returned from that call is still just the original image element, not both. So when you call wrap, you are only calling it on the original image tag. By wrapping first, the image tag becomes the child of the wrapped element, then after will insert it in the correct location.
This might be clearer,
var myImage = $(this);
myImage.after(imageCaption);
myImage.wrap('<div class="imageBlock '+array[0]+'" />');
See the problem?
try
$(document).ready(function() {
$('#x').wrap('<div class="imageBlock">');
$('<span class="caption">The Caption</span>').insertAfter($('#x'));
});
'x' is the ID attribute value of <img src="whatever"> element
Here is a fiddle to start you off:
http://jsfiddle.net/c3nxe/
I've got some server side PHP code that dynamically displays thumbnails of all the images contained in a directory:
<form>
<input type="hidden" name="animal">
<div id="thumbs">
\\ Dynamically created thumbnails start
<img src="images/bat.jpg">
<img src="images/cat.jpg">
<img src="images/rat.jpg">
\\ Dynamically created thumbnails end
</div>
</form>
I want the correct jQuery syntax so that when a user clicks on one of the images it:
Removes border styles from all of the thumbnails
Highlights the selected thumbnail by adding a coloured border
Changes the value of the form field "animal" to the file name shown in the image.
Any help much appreciated.
demo: http://jsfiddle.net/9rFKB/
jquery
$('#thumbs').delegate('img', 'click', function() {
var $this = $(this);
// Clear formatting
$('#thumbs img').removeClass('border-highlight');
// Highlight with coloured border
$this.addClass('border-highlight');
// Changes the value of the form field "animal" to the file name shown in the image.
$('[name="animal"]').val( $this.attr('src').substring($this.attr('src').lastIndexOf('/')+1) );
alert( $('[name="animal"]').val() );
});
css
.border-highlight {
border:5px dashed red;
}
I've used delegate instead of click since you have stated that the images are to be created dynamically.
If by "removes formatting on thumbnails" means removing all css on your images, then I think what you want is this.