Selecting dynamic attribute and appending options to the selected "select" element

Viewed 22

This is the template for the dynamic HTML. When I click on the 'Add More', with id plus5, I am trying to get the dynamic form id so that I can select the #location element and can append options to it.

In the dynamic form I have dynamic_form, dynamic_form0, dynamic_form1 and location as location, location0, location1 etc.

$("#dynamic_form #plus5").on('click', function() {
  // select the specidic dynamic form id , which can be dynamic_form , dynamic_form0,  dynamic_form1 and then select the location and then append options 
  alert($(this).closest('#dynamic_form'));

});
<div class="form-group" id="dynamic_form">
  <div class="row">
    <div class="col-md-3">
      <select type="text" name="location" id="location" placeholder="Enter Product Name" class="form-control"></select>
    </div>
    <div class="col-md-3">
      <input type="text" class="form-control" name="quantity" id="quantity" placeholder="Enter Product Quantity" onkeyup="if (/\D/g.test(this.value)) this.value = this.value.replace(/\D/g,'')" ;>
    </div>
    <div class="col-md-4">
      <textarea class="form-control" rows="1" name="remarks" placeholder="Enter Remarks" id="remarks"></textarea>
    </div>
    <div class="button-group">
      <a href="javascript:void(0)" class="btn btn-primary" id="plus5">Add More</a>
      <a href="javascript:void(0)" class="btn btn-danger" id="minus5">Remove</a>
    </div>
  </div>
</div>

1 Answers

If this is dynamically created content, as the question states, then you should avoid putting any id attributes in the HTML that gets repeated, and certainly not any incremental id attributes generated at runtime.

The better approach is to use the same HTML structure with common classnames on the required elements and repeat that where/when necessary. You can then use delegated event handlers which use DOM traversal methods to find related content within the given structure.

Notice in the example below how the same JS logic works for all form elements in the example, and only affects the select within the related form.

$(document)
  .on('input', '.quantity', e => {
    e.target.value = e.target.value.replace(/\D/g, '');
  })
  .on('click', '.plus5', e => { 
    e.preventDefault();
    let $form = $(e.target).closest('.form-group');
    let $select = $form.find('.location');
    
    // for this demo only -- update as required for your own use case
    $select.append(i => `<option>${$select.children('option').length + 1}</option>`);
  })
  .on('click', '.minus5', e => {
    e.preventDefault();
    let $form = $(e.target).closest('.form-group');
    let $select = $form.find('.location');
    $select.children('option').slice(-5).remove();
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="form-group">
  <div class="row">
    <div class="col-md-3">
      <select type="text" name="location" placeholder="Enter Product Name" class="form-control location"></select>
    </div>
    <div class="col-md-3">
      <input type="text" class="form-control quantity" name="quantity" placeholder="Enter Product Quantity">
    </div>
    <div class="col-md-4">
      <textarea class="form-control remarks" rows="1" name="remarks" placeholder="Enter Remarks"></textarea>
    </div>
    <div class="button-group">
      <a href="#" class="btn btn-primary plus5">Add More</a>
      <a href="#" class="btn btn-danger minus5">Remove</a>
    </div>
  </div>
</div>

<div class="form-group">
  <div class="row">
    <div class="col-md-3">
      <select type="text" name="location" placeholder="Enter Product Name" class="form-control location"></select>
    </div>
    <div class="col-md-3">
      <input type="text" class="form-control quantity" name="quantity" placeholder="Enter Product Quantity">
    </div>
    <div class="col-md-4">
      <textarea class="form-control remarks" rows="1" name="remarks" placeholder="Enter Remarks"></textarea>
    </div>
    <div class="button-group">
      <a href="#" class="btn btn-primary plus5">Add More</a>
      <a href="#" class="btn btn-danger minus5">Remove</a>
    </div>
  </div>
</div>

As an aside, I removed the inline event handler as these are bad practice. I replaced it with another delegated event handler to handle updating the quantity value.

Related