0

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.

  • ```$(this).attr('id').split('-').pop()``` should do, to get the correct value at `id_input`. To show the preview, refer [here](https://stackoverflow.com/questions/4459379/preview-an-image-before-it-is-uploaded) – Rayon Nov 16 '22 at 22:19
  • 1
    Is there no way you can group those elements under a common ancestor to eliminate all that parsing hassle? You could then simply put a class on the input and watch for changes, then refer to the image in the same container element. – isherwood Nov 16 '22 at 22:24
  • I did group everything in a div and it was easier to change the image. Thanks – Célian CREPIN Nov 16 '22 at 22:33
  • You don’t have a parameter `event` - can you just use `this.files[0]`? – James Nov 16 '22 at 22:37
  • This doesn't work. I tried without using Jquery with a call to a function with K as parameter, and by using getElementById("frame-add-"+K), I can find my image. Then I used the "event.target.files[0]", and this time, it works. But I still don't know why it didn't with jquery. – Célian CREPIN Nov 16 '22 at 22:42

1 Answers1

0

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");
James
  • 20,957
  • 5
  • 26
  • 41
  • While this works, it's fragile. It depends on a very specific DOM structure. – isherwood Nov 16 '22 at 22:26
  • It’s way better than polluting the html with a ton of ids. Given more html context it can be improved – James Nov 16 '22 at 22:26
  • My code works fine. I had an issue with my label. It were instead of . Should I delete my post ? PS : I still do not know why event.target.files[0] does not work. – Célian CREPIN Nov 16 '22 at 22:30