0

Is there a way I can set input values of each dynamically created input fields based on a difference between 2 dynamically created fields. Below is my code and what am trying to achieve.

HTML

<table id="requested-wh-stock-table" class="table table-bordered table-hover dataTable" width="100%">
    <thead>
        <tr>
            <th>Luminaire</th>
            <th>Order Quantity</th>
            <th>Delivered Qty</th>
            <th>Back Order Qty</th>
        </tr>
    </thead>
    <tbody>
        @foreach ($salesorder as $request)
        <tr>
            <td><input type="text" class="form-control" name="luminaire" value="{{$request->luminaire}}" readonly></td>
            <td><input type="number" class="form-control" name="order_quantity" id="order_quantity"
                    value="{{$request->quantity}}" readonly /></td>
            <td><input type="number" class="form-control" name="delivered_quantity" id="delivered_quantity" value="" />
            </td>
            <td><input type="number" class="form-control" name="backorder_quantity" id="backorder_quantity" value=""
                    readonly /></td>
        </tr>
        @endforeach
    </tbody>
</table>

jQuery

//Update Backorder qty based on Delivered Quantity amount
$(document).ready(function () {
    $("#delivered_quantity").change(function () {
        var backorder_quantity = $("#order_quantity").val() - $("#delivered_quantity").val();
        $("#backorder_quantity").val(backorder_quantity);
    });
});

Currently, it only updates the first field, it does not update other fields, is there a way I can loop through all fields and update Backorder field as I change the Delivered Quantity field?

enter image description here

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
Inno
  • 31
  • 6
  • Does this answer your question? [getElementById returning value only for first element](https://stackoverflow.com/questions/24123707/getelementbyid-returning-value-only-for-first-element) – Heretic Monkey Feb 20 '20 at 15:22

2 Answers2

0

You should not use id on elements which are not unique. Since the inputs will be rendered multiple times (in rows), then I suggest to not use the id attribute. So let's try to use the name attribute instead for finding the DOM.

On the change event listener of delivered_quantity input, get the other fields in the same row. To do that, from this object inside the event handler, do seek the closest tr and then find the particular field from it's child.

$(document).ready(function() {
    $("[name=delivered_quantity]").change(function() {
        var order_quantity = $(this).closest('tr').find("[name=order_quantity]").val()
        var delivered_quantity = $(this).closest('tr').find("[name=delivered_quantity]").val();
        var backorder_quantity = order_quantity - delivered_quantity

        $(this).closest('tr').find("[name=backorder_quantity]").val(backorder_quantity);
    });
});
novalagung
  • 10,905
  • 4
  • 58
  • 82
0

If you are dynamically updated these fields within a loop, you will run into naming conflicts with the IDs. Instead, I would set the class name of each of the fields, and not the IDs:

<tr>
   <td><input type="text" class="form-control" name="luminaire" value="10" readonly></td>
   <td><input type="number" class="form-control order_quantity" name="order_quantity" id="order_quantity" value="20" readonly/></td>
   <td><input type="number" class="form-control delivered_quantity" name="delivered_quantity" id="delivered_quantity" value=""/></td>
   <td><input type="number" class="form-control backorder_quantity" name="backorder_quantity" id="backorder_quantity" value="" readonly/></td>
</tr>

Now you can attach an event listener in jQuery to every element with that class name, and you can reference it using the "this" keyword. Then sense they all have a parent that is a table row, we can use that to refer to the other input elements that are children of that parent element. Once we find the children in the row of the elements that you're targeting, we can update the values:

$(document).ready(function() {
    $('.delivered_quantity').on('change', function() {
        let parent = $(this).parents('tr');
        let order_quantity = parent.find('.order_quantity');
        let backQuant = parent.find('.backorder_quantity');
        let backorder_quantity = order_quantity.val() - $(this).val();
        backQuant.val(backorder_quantity);
    });
});

We attach the change event to EACH of the delivered_quantity elements that you could potentially be targeting in your table. When any of them experience this event, the callback function above will occur. Next we get the parent element that is a table row. We then get the order_quantity and backorder_quantity elements that are children within the table row. We then calculate the backorder_quantity variable and then update the backorder_quantity element to match that value. Note that I had to put in some random values for your luminair and order_quantity sense we don't know what those values will be sense you're using them in a loop.

Simeon Ikudabo
  • 2,152
  • 1
  • 10
  • 27
  • I got another problem, not sure if you could assist me here or if I should ask as a new question... I have got a Modal that shows up when the shelve text box is clicked, the modal has a dropdown list. I would like to pick an item from that list and assign it to the shelve number field, however I am having trouble as the "Save button" does nothing. below is my save modal code – Inno Feb 28 '20 at 14:25
  • `$('.shelve_number').on('change',function() { let parent = $(this).parents('tr'); let shelve = parent.find('.shelve_number'); var selected_shelve = jQuery("#shelve_no option:selected").val(); var shelve_selected =JSON.parse(selected_shelve).shelve_no; $('#save_modal').on('click',function(x){ shelve.val(shelve_selected); $('#myModal').modal('hide'); }); });` – Inno Feb 28 '20 at 14:26