user1477388
user1477388

Reputation: 21440

Why does this <li> get added multiple times?

http://jsfiddle.net/ay9d8cuq/3/

To recreate, try adding a location/service filter more than once. Notice how it adds empty items to the list.

Why does this code add the filter more than once to the DOM?

$('#addFilter').click(function(){
    var filter = $('#FilterTypes').val();

    switch (filter)
    {
        case "Location":
                $('#LocationFilter').show()
                .find('.addFilter').click(function() {
                    $(this).parent().hide();
                    AddLocationFilter();
                });
                break;
            case "Service":
                $('#ServiceFilter').show()
                .find('.addFilter').click(function() {
                    $(this).parent().hide();
                    AddServiceFilter();
                });
                break;
    }
});

var AddLocationFilter = function() {
    $('#Filters').append('<li>' + $('#City').val() + ', ' + $('#State').val() + '</li>');
    $('#City').val('');
    $('#State').val('');
};

var AddServiceFilter = function() {
    $('#Filters').append('<li>' + $('#Name').val() + '</li>');
    $('#Name').val('');
};

Upvotes: 3

Views: 65

Answers (3)

Paul Roub
Paul Roub

Reputation: 36448

You're adding a new click() handler to one of the .addFilter buttons every time #addFilter is clicked. They all call the same function, which adds an entry then clears the field values. The next "copy" of the handler then runs, adding those empty values.

Set the handlers once:

$('#addFilter').click(function() {
  var filter = $('#FilterTypes').val();

  switch (filter) {
    case "Location":
      $('#LocationFilter').show();
      break;
    case "Service":
      $('#ServiceFilter').show();
      break;
  }
});


$('#LocationFilter .addFilter').
click(function() {
  $(this).parent().hide();
  AddLocationFilter();
});

$('#ServiceFilter .addFilter').
click(function() {
  $(this).parent().hide();
  AddServiceFilter();
});

var AddLocationFilter = function() {
  $('#Filters').append('<li>' + $('#City').val() + ', ' + $('#State').val() + '</li>');
  $('#City').val('');
  $('#State').val('');
};

var AddServiceFilter = function() {
  $('#Filters').append('<li>' + $('#Name').val() + '</li>');
  $('#Name').val('');
};
#LocationFilter,
#ServiceFilter {
  display: none;
}
div,
ul,
select {
  margin: 1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<select id="FilterTypes">
  <option value="Location">Location</option>
  <option value="Service">Service</option>
</select>
<a href="#" id="addFilter">Add filter</a>
<div id="LocationFilter">
  <h4>Add Location Filter</h4>
  <input id="City" placeholder="City" />
  <input id="State" placeholder="State" />
  <input type="button" class="addFilter" value="Add">
</div>
<div id="ServiceFilter">
  <h4>Add Service Filter</h4>
  <input id="Name" placeholder="Service name" />
  <input type="button" class="addFilter" value="Add">
</div>
<ul id="Filters"></ul>

Upvotes: 2

haim770
haim770

Reputation: 49105

That's because you're re-attaching the click handler every time the AddFilter button is clicked, so for the second time it will run twice.

Try this instead:

.find('.addFilter').one('click', function() {

And

.find('.addFilter').one('click', function() {

See one() and Fiddle

Upvotes: 4

Holt
Holt

Reputation: 37626

Each time you click the Add Filter button, you add a listener to the Add button, which mean that if you click 3 times on Add Filter with Location selected, the listener is called 3 times and you get 3 entries in your list.

This code:

$('#LocationFilter').find('.addFilter').click(function() {
    $(this).parent().hide();
    AddLocationFilter();
});

Should be outside your click callback (same for ServiceFilter).

Upvotes: 4

Related Questions