Mafia
Mafia

Reputation: 812

Selecting siblings of parent of $(this) element

I need to update the id of all li that are siblings of the parent of the $(this) element by dynamically counting the present li that belong to the same "family" every time one is removed.

Note that there's more than one ul.customFieldUl on the page and more than one li.customFieldLi in each.

$('.customFieldUl').on('click', '.remove-button', function() {
  var field = $(this).parents('li.customFieldLi');
  if (field.length) {
    field.remove();

    // PROBLEMATIC SELECTOR BELOW:
    $(this).parent().siblings().each(function(i) {
      var id = i + 1;

      $(this).prop('id', 'field_' + id);
      $(this).find('label#top_title').html('Custom Field #: <b>' + id + '</b> &raquo;');
    });
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="customFieldUl">
  <li class="customFieldLi">
    <label id="top_title">Additional Field</label>
    <div class="additionalFieldForm"></div>
    <div class="remove-button">Remove</div>
  </li>
  <li class="customFieldLi">
    <label id="top_title">Additional Field</label>
    <div class="additionalFieldForm"></div>
    <div class="remove-button">Remove</div>
  </li>
</ul>

Upvotes: 0

Views: 58

Answers (2)

Rory McCrossan
Rory McCrossan

Reputation: 337743

The issue you have is that you're removing the element then trying to select elements based on it. This won't work as the element no longer exists. To fix this, get the related elements first, then perform the removal.

Note that you can simplify the code by using the index parameter provided by each(). Also, you've repeated the top_title id. You should make that a class. Try this:

$('.customFieldUl').on('click', '.remove-button', function() {
  var $button = $(this);
  var $ul = $button.closest('.customFieldUl');
  
  $button.closest('.customFieldLi').remove();
  $ul.find('.customFieldLi').each(function(i) {
    $(this).prop('id', 'field_' + i);
    $(this).find('label.top_title').html('Custom Field #: <b>' + i + '</b> &raquo;');
  })
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul class="customFieldUl">
  <li class="customFieldLi">
    <label class="top_title">Additional Field</label>
    <div class="additionalFieldForm"></div>
    <div class="remove-button">Remove</div>
  </li>
  <li class="customFieldLi">
    <label class="top_title">Additional Field</label>
    <div class="additionalFieldForm"></div>
    <div class="remove-button">Remove</div>
  </li>
  <li class="customFieldLi">
    <label class="top_title">Additional Field</label>
    <div class="additionalFieldForm"></div>
    <div class="remove-button">Remove</div>
  </li>
  <li class="customFieldLi">
    <label class="top_title">Additional Field</label>
    <div class="additionalFieldForm"></div>
    <div class="remove-button">Remove</div>
  </li>
  <li class="customFieldLi">
    <label class="top_title">Additional Field</label>
    <div class="additionalFieldForm"></div>
    <div class="remove-button">Remove</div>
  </li>
</ul>

It's also worth noting that changing id attributes dynamically is not a good idea. They are meant to be immutable.

Upvotes: 1

Satpal
Satpal

Reputation: 133453

You need to target siblings() of LI before removing the LI element.

$('.customFieldUl').on('click', '.remove-button', function() {
  var field = $(this).closest('li.customFieldLi');
  //Take reference of siblings
  var siblings = field.siblings();
  
  //Remove element
  field.remove();

  // Now iterate and update properties.
  siblings.each(function(i) {
    var id = i + 1;
    $(this).prop('id', 'field_' + id);
    $(this).find('label#top_title').html('Custom Field #: <b>' + id + '</b> &raquo;');
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="customFieldUl">
  <li class="customFieldLi">
    <label id="top_title">Additional Field</label>
    <div class="additionalFieldForm"></div>
    <div class="remove-button">Remove</div>
  </li>
  <li class="customFieldLi">
    <label id="top_title">Additional Field</label>
    <div class="additionalFieldForm"></div>
    <div class="remove-button">Remove</div>
  </li>
</ul>

Identifiers in HTML must be unique, You are using id="top_title" multiple times which renders HTML invalid

Note: I totally agree with @Rory's comment, changing id attributes dynamically is not a good idea

Upvotes: 1

Related Questions