0

I make a button to dynamically create input field. After uploading file the image should be previewed . But find that , at first one image is previewed , then 2nd time after selecting file 2 copy of same image is previewed, then 3rd time 3 copy of same image and goes on…

Html code

<form method="post" action=" " class="form" id="form" accept-charset="UTF-8" 
enctype="multipart/form-data" >

<div class="field" align="left"> 
<h3>Upload your images</h3>
<input type="text" placeholder="Event name">
<input type="file" id="1" class="gallery_input" name="files[]" multiple />
</div>

Js code

   <script type="text/javascript"> 

   var event_id=3;
   var input_id;

  $(document).ready(function ()
 {
 function readURL(input)
 {
    if(input.files && input.files[0])
    {
      var reader=new FileReader();
      reader.onload = (function(e) {
      var file = e.target;
      $("<span class=\"pip\">" +
        "<img class=\"imageThumb\" src=\"" + e.target.result + "\" title=\"" + file.name + "\"/>" +
        "<br/><span class=\"remove\">Remove image</span>" +
        "</span>").insertAfter("#"+input_id);
      $(".remove").click(function(){
        $(this).parent(".pip").remove();
      }); 
    });
      reader.readAsDataURL(input.files[0]);
    }
 }


 $("body").click(function()
{
  $(".gallery_input").change(function()
    {
      var target_input=$(this).attr('id');
      input_id=target_input;
        readURL(this);
    });
 });
});
 </script> 

If I remove

    $("body").click(function()

line it’s work . But I need this because it work’s with dynamically created
input filed .
I remove some HTML and js code like input filed create Js code, etc. Because I think it works.

Alimur Razi Rana
  • 87
  • 1
  • 2
  • 9
  • `$(function() { $("#form").on("change",".gallery_input",function() { ... }); $("#form").on("click",".remove",function() { ... }); });` – mplungjan Jun 19 '17 at 05:57

1 Answers1

2

Attachment of event handlers using jQuery.on() (and its shortcut methods .click(), .change() etc) doesn't work quite the way you think. Each time a handler is attached in this way, it is added to any handlers already attached. This behaviour is different from foo.onclick = fn, which replaces a previously attached handler.

So, as it stands ...

  • each time body is clicked, a further change handler is attached to all .gallery_input element(s) on the page.
  • each time reader.onload fires, a further click handler is attached no only to the .remove element in the fresh content, but is also added to the .remove elements in previously appended content.

The code can be fixed in a number of ways, chief amongst which (as indicated above by @mplungjan) is to permanently delegate change and click handling to the form, and to simplify readURL().

$(document).ready(function () {
    function readURL(e) {
        var input = e.target;
        if(input.files && input.files[0]) {
            var reader = new FileReader();
            reader.onload = function(e) {
                var file = e.target;
                $("<span class=\"pip\"><img class=\"imageThumb\" src=\"" + file.result + "\" title=\"" + file.name + "\"/><br/><span class=\"remove\">Remove image</span></span>").insertAfter(input); // you already know `input` so it doesn't need to be rediscovered with `'#'+input_id`
            };
            reader.readAsDataURL(input.files[0]);
        }
    }
    $("#form")
    .on('change', '.gallery_input', readURL)
    .on('click', '.remove', function() {
        $(this).parent(".pip").remove();
    });
});

The $("body").click(...) handler appears to be unnecessary and has disappeard.

Roamer-1888
  • 19,138
  • 5
  • 33
  • 44