Search code examples
javascriptimagewhile-loopjquery-ui-tabspreview

Tabs content file image preview script not working


Image preview function works correctly on the first tab, why doesn't it work on other tabs, I'm reloading the image preview function by clicking the tab, I couldn't find an example in the net for this problem.
Is there any idea?

<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>jQuery UI Tabs - Default functionality</title>
  <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
  <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
  <script>
      $( function() {
        $( "#tabs" ).tabs();
    } );
    
    function PreviewImage() {
    var count   = $('.tab-content').data('id');
    var preview = document.getElementById('uploadPreview_'+count);
    var file    = document.getElementById('uploadImage_'+count).files[0];
    var reader  = new FileReader();

    reader.addEventListener("load", function () {
        preview.src = reader.result;
    }, false);

    if (file) {
        reader.readAsDataURL(file);
    }
};

$(document).on('click', '#tab',function(e){
    PreviewImage();
    e.preventDefault();
});
</script>
</head>
<body>
   <div id="tabs">
      <ul class="nav nav-tabs" data-toggle="tabs">
        <li id="tab"><a href="#tabs-1"> tab 1</a></li>
        <li id="tab"><a href="#tabs-2"> tab 2</a></li>
    </ul>
    <div id="tabs-1" class="tab-content" data-id="1">
     <img id="uploadPreview_1" src="" alt="background" class="img-responsive center-block widget-background" style="height: 180px; width: auto;"  alt="image-alt">
     <input id="uploadImage_1" type="file" accept="image/*" onchange="PreviewImage();"/>

 </div>
 <div id="tabs-2" class="tab-content" data-id="2">
     <img id="uploadPreview_2" src="" alt="background" class="img-responsive center-block widget-background" style="height: 180px; width: auto;"  alt="image-alt">
     <input id="uploadImage_2" type="file" accept="image/*" onchange="PreviewImage();"/>

 </div>
</div>
</body>
</html>


Solution

  • Here it is working now.

    I think it makes sense just by looking at code.

    But you can see we need to pass context to preview image.

    $(function() {
      $("#tabs").tabs();
    });
    
    function PreviewImage(tab) {
      var preview = tab.parentNode.querySelector('img');
      var file =  tab.files[0]; 
      var reader = new FileReader();
    
      reader.addEventListener("load", function() {
        preview.src = reader.result;
      }, false);
    
      if (file) {
        reader.readAsDataURL(file);
      }
    };
    
    document.addEventListener('change', (e) => {
      if(e.target.matches('input[type="file"]')) {
        console.log(e.target);
        PreviewImage(e.target);
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    
    <body>
      <div id="tabs">
        <ul class="nav nav-tabs" data-toggle="tabs">
          <!-- Corrected id : Should be unique / added class tab for click. -->
          <li id="tab1" class="tab"><a href="#tabs-1"> tab 1</a></li>
          <li id="tab2" class="tab"><a href="#tabs-2"> tab 2</a></li>
        </ul>
        <div id="tabs-1" class="tab-content" data-id="1">
          <img id="uploadPreview_1" src="" alt="background" class="img-responsive center-block widget-background" style="height: 180px; width: auto;" alt="image-alt">
          <input id="uploadImage_1"  type="file" accept="image/*" />
    
        </div>
        <div id="tabs-2" class="tab-content" data-id="2">
          <img id="uploadPreview_2" src="" alt="background" class="img-responsive center-block widget-background" style="height: 180px; width: auto;" alt="image-alt">
          <input id="uploadImage_2"  type="file" accept="image/*" />
    
        </div>
      </div>
    </body>