0

I have an HTML loaded like this:-

if(isset($company_admin))
{
    $tot_admin = count($company_admin);
    for($i = 0; $i < $tot_admin; $i++)
    {?>
       <div class="form-group col-sm-12">
        <label class="col-sm-2">Admin Image <?php if($i > 0) echo ($i+1);?></label>
        <div class="col-sm-9">
            <input type="hidden" name="hid_admin_img[]" id="hid_admin_img<?php if($i > 0) echo '_'.($i+1);?>" value="<?php if(isset($company_admin[$i]['admin_img'])) { echo $company_admin[$i]['admin_img'];} ?>">
             <input type="file" name="admin_img[]" id="admin_img<?php if($i > 0) echo '_'.($i+1);?>" class="form-control"></br>
        <div id="imagePreview3<?php if($i > 0) echo '_'.($i+1);?>"></div>
        <div id="existImage3<?php if($i > 0) echo '_'.($i+1);?>">
        <?php if(isset($company_admin[$i]['admin_img'])) {?>
            <?php if($company_admin[$i]['admin_img'] != ''){?><img src="<?php echo base_url();?>uploads/admin_org/<?php echo $company_admin[$i]['admin_img'];?>" height="100" width="100"><?php } else {?><img src="<?php echo base_url();?>uploads/new-user-image-default.png" height="100" width="100"><?php } }?>
        </div>
        </div>
    </div>
   <?php
  }
}?>

Now, when a file is selected then the corresponding imagePreview3_2, imagePreview3_3 DIVs load the image as a preview.

To achieve this, here's the following code:-

$(function(){
for(var i = 2; i<=4; i++)
{
    $("#admin_img_"+i).on("change", function()
    {
        var files = !!this.files ? this.files : [];
        if (!files.length || !window.FileReader) 
                return; // no file selected, or no FileReader support
        if (/^image/.test( files[0].type))
        { // only image file
            var _this = $(this);
            alert("huu");
            var reader = new FileReader(); // instance of the FileReader
            reader.readAsDataURL(files[0]); // read the local file
            reader.onloadend = function(){ // set image data as background of div
                _this.siblings("div[id^=existImage]").hide();
                _this.siblings("div[id^=imagePreview]").show().css("background-image", "url(" + this.result + ")");
            }
        }
    });
}
});

Now, the problem rises like this. I have added a new functionality. When a particular button will be clicked, new admin_img_, imagePreview3_, imagePreview3_ will be added dynamically.

This is done by the following code:

function append_admin()
{
    var tot_admin = $('#tot_admin').val();
    if(tot_admin < 4)
    {
        tot_admin = parseInt (parseInt(tot_admin) + 1);
        $('#tot_admin').val(tot_admin);


        var admin_image_obj =    '<div class="form-group col-sm-12">';
            admin_image_obj +=  '<label class="col-sm-2">Admin_'+tot_admin+' Image</label>';
            admin_image_obj +=  '<div class="col-sm-9">';
            admin_image_obj +=  '<input type="hidden" name="hid_admin_img[]" id="hid_admin_img_'+tot_admin+'" value="">';
            admin_image_obj +=  '<input type="file" name="admin_img[]" id="admin_img_'+tot_admin+'" class="form-control"></br>';
            admin_image_obj +=  '<div id="imagePreview3_'+tot_admin+'"></div>';
            admin_image_obj +=  '</div></div>'; 

        $('#more_admin_container').append(admin_image_obj);
    }   
}

However, with the dynamically created admin_img_ and imagePreview_, the preview of a selected image is not working.

What am I doing wrong?

Saswat
  • 12,320
  • 16
  • 77
  • 156

1 Answers1

2

If the elements are appended in the DOM after the event assignment, you can use event delegation to avoid the problem:

  $(document).on("change", "#admin_img_"+i, function() {
  });

You can change $(document) with a parent element that will not change during the appended elements, or you can use $(document) to iterate through all DOM elements in the moment of the event delegation.

Marcos Pérez Gude
  • 21,869
  • 4
  • 38
  • 69
  • 2
    Correct me if I am wrong but isnt it should be `$(document).on( "change","#admin_img_"+i, function() { });`? According to [jquery on()](http://api.jquery.com/on/) – Anupam Jun 21 '16 at 11:55
  • Still a bit confused. How shall I iterate $(document)....... within the for loop? A bit more elaborated example would have been appreciable. – Saswat Jun 21 '16 at 11:57
  • @anu Yeah, something wrong in my brain today. Thank you I will edit :) – Marcos Pérez Gude Jun 21 '16 at 11:57
  • @Saswat simply change that line, and it will work because doesn't matter if the element exists when the event is assigned, because it will be asigned to `$(document)` object and then it will delegate by itself in the element that you need, without any intervention by you. – Marcos Pérez Gude Jun 21 '16 at 11:59
  • @Saswat Go through [this doc](http://api.jquery.com/on/) to understand event delegation for dynamically generated elements. – Anupam Jun 21 '16 at 12:00