1

I am having a input of type = " file " on my page. Also I have a button "Add Inputs" on the page which adds a new file input element on page and I want to run a function when user changes the value of any of those inputs by selecting a new file. Here is my code.

HTML

<div class="main">
    <div id="InpDiv">
        <input type="file" name="fname">
    </div>
</div>
<div>
    <button onclick="addInp()">Add Inputs</button>
</div>

JS

// Function that is going to run after change in file input.

    $(document).ready(function(){
        $("input[name='fname']").each(function(){
            $(this).change(function(){
                alert('hello');
                
                // Do some work here.

            });
        });
    });


// Function that adds new file inputs.

    function addInp()
    {
        $('#InpDiv').clone().appendTo(".main");
    }

Now the problem is .change() method works fine for those inputs which were present already on page but not works (won't prompt "hello" message here) on change of values in those newly created inputs. I made more than one file inputs already present on page and .change() worked for all of them but it didn't worked for any of the newly created inputs.

Is it so that events won't work with dynamically added elements on page ? And if so then how am I going to get this work done?

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Avi
  • 325
  • 1
  • 11
  • Make the change callback function into a named function (instead of anonymous) and apply the change event on the cloned element. – fredrik Jul 21 '20 at 13:19

1 Answers1

5

Try delegation approach using .on(). This will ensure that events will be attached to all the elements that are added to the DOM at a later time.

Also I will prefer using input event instead of change:

Change:

$(this).change(function(){

To:

$('.main').on('input', this, function(){

$(document).ready(function(){
  $("input[name='fname']").each(function(){
      $('.main').on('input', this, function(){
          alert('hello');

          // Do some work here.

      });
  });
});


// Function that adds new file inputs.

function addInp()
{
  $('#InpDiv').clone().appendTo(".main");
}
    
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">
    <div id="InpDiv">
        <input type="file" name="fname">
    </div>
</div>
<div>
    <button onclick="addInp()">Add Inputs</button>
</div>
Mamun
  • 66,969
  • 9
  • 47
  • 59
  • Yes you are correct. I guess I should have posted the question earlier. It could have saved my few hours which I wasted to figure why that .change() was not working. – Avi Jul 21 '20 at 13:30
  • One more doubt. So should I also prefer using .on('click' , myFunction) instead of . click () method ? – Avi Jul 21 '20 at 13:32
  • @Avi, yes, you should use that to be on the safe side.:) – Mamun Jul 21 '20 at 13:34
  • @Mamun `.click()` is a shortcut for `.on( "click", handler )`. Why would the latter be safer? – Ivar Jul 21 '20 at 13:48
  • 1
    @Ivar, didn't notice that, I mean the delegation approach...`.on( "click", this, handler )`:) – Mamun Jul 21 '20 at 13:51