1

I have this code and it works, i can add a new lines and also delete them.

The problem is when i select and option from the select input it changes the two inputs with the correct information.

When i add new line or several lines. I select an option from the select input (any select input created) changes all the inputs with the same information.

I figured that the problem is the IDs for the three elements, so the new elemenst they have the same IDs. I trid with a class but the same problem.

Here is the form:

<form method="post" action="/add">
    <input class="form-control" name="market_id" value="market_id" hidden>
    <div class="card mb-4">
        <div class="row card-body" id="inputFormRow">
        <div class="col-md-6 mb-2">
            <label class="form-label">Item</label>
            <select class="form-select mySelect" name="market_items[]" id="mySelect" required>
                <option></option>
                <option value="m_id" data-itemname="m_name" data-itemprice="m_price"></option>
                <option value="m_id_1" data-itemname="m_name_1" data-itemprice="m_price_1"></option>
                <option value="m_id_2" data-itemname="n_name_2" data-itemprice="m_price_2"></option>
            </select>
        </div>
        <input type="hidden" class="form-control myItemName" id="myItemName" name="itemName[]">
        <input type="hidden" class="form-control myItemPrice" id="myItemPrice" name="itemPrice[]">
        <div class="col-md-2 mb-2">
            <label class="form-label">Quantity</label>
            <input type="number" class="form-control" name="market_items_qty[]" required>
        </div>
        <div class="col-md-1 mb-2">
            <label class="form-label">Box(s)::EA</label>
            <select class="form-select" name="market_items_unit[]" required>
                <option></option>
                <option value="Box(s)">Box(s)</option>
                <option value="Each">Each</option>
            </select>
        </div>
        <div class="col-md-1 mb-2">
            <label class="form-label">Del::Row</label>
            <button id="removeRow" type="button" class="form-control btn btn-outline-danger">Remove</button>
        </div>
    </div>
    <div id="newRow"></div>
    </div>
    <div class="d-grid gap-2" hidden>
        <button id="addRow" type="button" class="btn btn-outline-info mb-3">Add Row</button>
    </div>
    <div class="d-grid gap-2">
        <button type="submit" class="btn btn-primary">ADD</button>
    </div>
</form>

Here is the js/jquery code:

// add row
$("#addRow").click(function () {
    var html = '';

    html += '<div class="row card-body" id="inputFormRow">';

    html += '<div class="col-md-6 mb-2">';
    html += '<label class="form-label">Item</label>';
    html += '<select class="form-select mySelect" name="market_items[]" id="mySelect" required>';
    html += '<option></option>';
    html += '<?php foreach($marketItems as $item): ?>';
    html += '<option value="<?= $item['item_id']; ?>" data-itemname="<?= $item['item_description']; ?>" data-itemprice="<?= $item['regular_price']; ?>"><?= $item['item_description']; ?></option>';
    html += '<?php endforeach; ?>';
    html += '</select>';
    html += '</div>';

    html += '<input type="hidden" class="myItemName" id="myItemName+=ticks;" name="itemName[]">';
    html += '<input type="hidden" class="myItemPrice" id="myItemPrice+=ticks;" name="itemPrice[]">';

    html += '<div class="col-md-2 mb-2">';
    html += '<label class="form-label">Quantity</label>';
    html += '<input type="number" class="form-control" name="market_items_qty[]" required>';
    html += '</div>';

    html += '<div class="col-md-2 mb-2">';
    html += '<label class="form-label">Box(s)::EA</label>';
    html += '<select class="form-select" name="market_items_unit[]" required>';
    html += '<option></option>';
    html += '<option value="Box(s)">Box(s)</option>';
    html += '<option value="Each">Each</option>';
    html += '</select>';
    html += '</div>';

    html += '<div class="col-md-2 mb-2">';
    html += '<label class="form-label">Del::Row</label>'
    html += '<button id="removeRow" type="button" class="form-control btn btn-outline-danger">Remove</button>';
    html += '</div>';

    html += '</div>';

    $('#newRow').append(html);
});

// remove row
$(document).on('click', '#removeRow', function () {
    $(this).closest('#inputFormRow').remove();
});

$(document.body).on('change', '#mySelect', function() {
    // Get the selected option's data attribute value
    var itemName = $(this).find('option:selected').data('itemname');
    var itemPrice = $(this).find('option:selected').data('itemprice');
                                
    // Update the hidden input's value
    $('#myItemName').val(itemName);
    $('#myItemPrice').val(itemPrice);
});

I have no idea how to generate the IDs dynamically and also how to pass the IDs on change function. Any help is welcome!

3
  • generating dynamic IDs is usually not the best practice. You probably should. Why are you need to generate elements and why do you need a new id for it?Is the a checkout cart where you list items and want to submit the item list?
    – tacoshy
    Commented Sep 20, 2024 at 5:22
  • PS: What has this question to do with Java? Java is not a shortform for JavaScript. They are completely different languages where Java is an object-orientated server-side language and JS is a client-side (with exception of Node.js) language that primarily focus on ladder logic (while you have classes then can be object-orientated)
    – tacoshy
    Commented Sep 20, 2024 at 5:57
  • go for the class concept instead of dynamically generating ids, later you can use $(this) to refer current element of the same class which is clicked Commented Sep 20, 2024 at 6:07

2 Answers 2

0

No need to create dynamic IDs. Use the class concept.

Also, use the .clone() method to shorten your code.

Since you gonna generate new rows dynamically using clone so use .on for event handling

Here is a sample example code:

$(document).on('click', "#addRow", function() {
  $('#newRow').append($('.card-body:first').clone());
});
$(document).on('click', ".removeRow", function() {
  if ($('.card-body').length == 1) {
    alert('Minimum one row is required, so you cannot delete');
    return false;
  }
  $(this).closest('.card-body').remove();
});

$(document.body).on('change', '.mySelect', function() {
  // Get the selected option's data attribute value
  var itemName = $(this).find('option:selected').data('itemname');
  var itemPrice = $(this).find('option:selected').data('itemprice');

  // Update the hidden input's value
  $(this).closest('.card-body').find('.myItemName').val(itemName);
  $(this).closest('.card-body').find('.myItemPrice').val(itemPrice);
});
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<form method="post" action="/add">
  <input class="form-control" name="market_id" value="<?= $market['market_id']; ?>" hidden>
  <div class="card mb-4">
    <div class="row card-body">
      <div class="col-md-6 mb-2">
        <label class="form-label">Item</label>
        <select class="form-select mySelect" name="market_items[]" required>
          <option></option>
          <option value="1" data-itemname="my_item_1" data-itemprice="10">my_item_1</option>
          <option value="2" data-itemname="my_item_2" data-itemprice="20">my_item_2</option>
        </select>
      </div>
      <input type="hidden" class="form-control myItemName" name="itemName[]">
      <input type="hidden" class="form-control myItemPrice" name="itemPrice[]">
      <div class="col-md-2 mb-2">
        <label class="form-label">Quantity</label>
        <input type="number" class="form-control" name="market_items_qty[]" required>
      </div>
      <div class="col-md-1 mb-2">
        <label class="form-label">Box(s)::EA</label>
        <select class="form-select" name="market_items_unit[]" required>
          <option></option>
          <option value="Box(s)">Box(s)</option>
          <option value="Each">Each</option>
        </select>
      </div>
      <div class="col-md-1 mb-2">
        <label class="form-label">Del::Row</label>
        <button type="button" class="form-control btn btn-outline-danger removeRow">Remove</button>
      </div>

    </div>
    <div id="newRow"></div>
  </div>
  <div class="d-grid gap-2" hidden>
    <button id="addRow" type="button" class="btn btn-outline-info mb-3">Add Row</button>
  </div>
  <div class="d-grid gap-2">
    <button type="submit" class="btn btn-primary">ADD</button>
  </div>
</form>

1
  • 1
    Thanks mate!! Your example code works! and solve the problem. At the end i was over thinking in how to solve it. I have no expirience with JavaScript/Jquery.
    – Achim
    Commented Sep 21, 2024 at 1:40
-1

For options value, use a index variable as well like

  html += '<?php foreach($marketItems as $index => $item): ?>';
  html += '<option value="<?= $item['item_id'].$index; ?>" data-itemname="<?= $item['item_description']; ?>" data-itemprice="<?= $item['regular_price']; ?>"><?= $item['item_description']; ?></option>';
  html += '<?php endforeach; ?>';```

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.