tatty27
tatty27

Reputation: 1554

jQuery fire event once when an input is typed in

When a user starts typing in an empty input in a list I would like a new input to be appended to the list the for the next value to be added. Then, if they type in the new input, another new one is added and so on.

The code I have is..

$('.addNew').on('input', function(){
    var $parentUl = $(this).closest('ul');
    if($(this).val().length === 0){
        $(this).removeClass('addNew');
        $parentUl.append('<li class="catsLi"><input type="text" class="catItem addNew" name="reason[]" value=""/></li>');
    }
});

This works but it adds a new input every time the users type another character rather than just on the first one. I have tried using one instead of on but then it will only add extra input, if the user types in the new input nothing happens.

With this in mind I thought I would check if the input is empty before appending a new input so it only does it once per input but it isn't working.

I can see from chrome inspect that when I type in the input, it isn't actually changing it's value which is why it always adds a new input so I have tried checking for $(this).text().length instead but it still thinks it's empty.

Upvotes: 0

Views: 935

Answers (2)

tatty27
tatty27

Reputation: 1554

Managed to create my own solution based on the comments from above

$('.posUl').on('input', '.addNew', function(){
    var $parentUl = $(this).closest('ul');
    var $entered = $(this).val().length;
    if($entered === 1){
        $parentUl.append('<li class="catsLi"><input type="text" class="catItem addNew" name="reason[]" value=""/></li>');
    }
});

By checking the value of $entered I discovered it was never empty on change (obviously) then binding it on the ul meant it worked on the new input which was a dynamic element

Upvotes: 0

Briley Hooper
Briley Hooper

Reputation: 1271

Using .one() would be a good option, you just have to make sure you also add a listener to the new input field that you append. Here's a proof-of-concept:

// save a reference to the parent <ul> so we only have to look it up once
$parentUL = $('#parentUL');

function addNewField() {
  // create a new <li>
  var $newLI = $('<li class="catsLi"><input type="text" class="catItem" name="reason[]" value=""/></li>');

  // when the user first types in this new field, call addNewField() to add another "new" field to the list
  // (.one() ensures that the event will only fire once per field)
  $newLI.find('input').one('input', addNewField);

  // add the new <li> element to the end of the <ul>
  $parentUL.append($newLI);
}

// add a "new" field as soon as the page loads
addNewField();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul id="parentUL">
  <li class="catsLi"><input type="text" class="catItem" value="Existing One"/></li>  
  <li class="catsLi"><input type="text" class="catItem" value="Existing Two"/></li>  
</ul>

Upvotes: 1

Related Questions