0

On my project, I generate div elements that contain input fields with the request response data from my database given the search parameters. I need to be able to use a keyup event on it to do some extra work, however the class selector does not work when the input was generated by using append, even though it has the class on inspection.

I created a CodePen that demonstrates it: http://codepen.io/leofontes/pen/PNgabB?editors=1111

HTML

<div class="container" id="container">
  <button id="button">Click</button><br>
</div>

CSS

.container {
  background-color: #F00;
  height: 200px;
  width: 200px;
}

.dynamic-input {
  margin: 5px;
}

Javascript / jQuery

$(document).ready(function () {
  $('#button').click(function() {
    for(var i = 0; i < 5; i++) {
      $('#container').append('<input type="text" class="dynamic-input">')
    }
  });


  $('.dynamic-input').keyup(function() {
    console.log($(this).val());
  });
});

The jQuery code works great, I tested it with inputs generated within the $(document).ready function and it did what I intended, I don't understand why it doesn't when it is generated later on.

I also tried having a hidden input with the class already loaded with the HTML but that doesn't work either.

All ideas or suggestions are appreciated, thank you

Ibrahim Khan
  • 20,616
  • 7
  • 42
  • 55
leofontes
  • 898
  • 4
  • 16
  • 40
  • Possible duplicate of [Event binding on dynamically created elements?](http://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) – Dave May 14 '16 at 18:44
  • You could try `on('input', function()` instead of `keyup`... – mk117 May 14 '16 at 19:08

4 Answers4

2

You need event delegation for dynamically generated element.

$('#container').on('keyup', '.dynamic-input', function () {
    console.log($(this).val());
});
Ibrahim Khan
  • 20,616
  • 7
  • 42
  • 55
  • I would stress the use of on() rather than keyup() which allows event delegation for elements that aren't yet on the page. – Andy G May 14 '16 at 18:39
  • I think `$(document)` is too high in the DOM tree, every `keyup` in the entire document will be caught. I would opt for `$("#container")` (the immediate parent). –  May 14 '16 at 18:40
1

try this :

$(document).ready(function () {
  $('#button').click(function() {
    for(var i = 0; i < 5; i++) {
      $('#container').append('<input type="text" class="dynamic-input">')
    }
  });


  $(document).on('keyup', '.dynamic-input', function() {
    console.log($(this).val());
  });
});
Neta Meta
  • 4,001
  • 9
  • 42
  • 67
0

The issue is that you are creating the button separately from creating the binding. What you should be doing is creating the input AND binding the click event as part of the callback. Right now, you're binding the element correctly, syntax-wise, but it doesn't exist yet. So, what you would like is.

$(document).ready(function () {
  $('#button').click(function() {
    for(var i = 0; i < 5; i++) {
      $('#container').append('<input type="text" class="dynamic-input">')
    }
    //You're still within the scope of the callback, so this is the appropriate location
     $('.dynamic-input').on('keyup, function() {
        console.log($(this).val());
    });

  });
napo
  • 869
  • 9
  • 19
-1

That's because you performed the jquery binding BEFORE the element is created. When the $('.dynamic-input').keyup is executed. Your inputs, which are created AFTER you clicked the button, does not exist yet.

ShuberFu
  • 689
  • 3
  • 15