Ad

How Do I Send Request To Server From A Dynamic Form Using Jquery

- 1 answer

I am working on an inventory management system that involves sales of products

The form is dynamic

when a user click on add new product it sends to the server and get the price of the product

My HTML Code

<form role="form" action="{{ url('admin/sales/store') }}" method="get">
    @csrf
    <div class="card-body">
        <div class="row">
            <div class="col-md-12">
            </div>
            <div class="col-md-12 right my-3">
                <a href="#" class="btn btn-danger" id="add-product">Add New Product</a>
            </div>
            <div id="wrapper" class="col-md-12">
                <div id="new-field" class="col-md-12">
                    <div class="row">

                        <div class="col-md-4">
                            <div class="form-group">
                                <label>Product Name</label>
                                <select name="product[]" id="product" class="form-control">
                                    <option value="">Select Product Name</option>
                                    @foreach ($products as $product)
                                        <option value="{{ $product->id }}" name="product[]">
                                            {{ $product->name }}</option>
                                    @endforeach
                                </select>
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group">
                                <label>Quantity</label>
                                <input type="text" name="quantity[]" class="form-control"
                                    value="{{ old('quantity') }}"
                                    placeholder="Enter Quantity">
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group">
                                <label>Unit Price</label>
                                <input type="text" name="price[]" disabled
                                    id="price"
                                    class="form-control"
                                    placeholder="Enter Quantity">
                            </div>
                        </div>
                    </div>
                </div>

            </div>
        </div>
    </div>
    <div class="card-footer">
        <button type="submit" class="btn btn-primary float-md-right">Add Sales</button>
    </div>
</form>

JQUERY

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        $("#add-product").click(function(e) {
            e.preventDefault();
            $("#new-field").clone().appendTo("#wrapper");
        });
        $("#product").change(function(e) {
            e.preventDefault();
            axios.get("/ims/api/get-price/" + $(this).val())
                .then(function(response) {
                    $("#price").val(response.data.price);
                });
        })
</script>

JSON

{
   price: 34000.42
}

enter image description here

but it is only the first row that works

How can I make other rows to work?

Ad

Answer

The issue is that you're using the id attribute to select your elements.

Initially, your product rows (simplified) look like this:

<div id="wrapper">
    <div id="new-field">
        ...
        <select name="product[]" id="product"></select>       
        ...
        <input type="text" name="quantity[]" value="{{ old('quantity') }}" >
        ...
        <input type="text" name="price[]" disabled id="price">
        ...
    </div>
</div>

After the #add-product element is clicked, you clone the whole #new-field element, and append it to the #wrapper element with this code:

$("#add-product").click(function(e) {
    e.preventDefault();
    $("#new-field").clone().appendTo("#wrapper");
});

Then the simplified view of your product rows looks like this:

<div id="wrapper">
    <div id="new-field">
        ...
        <select name="product[]" id="product"></select>       
        ...
        <input type="text" name="quantity[]" value="{{ old('quantity') }}" >
        ...
        <input type="text" name="price[]" disabled id="price">
        ...
    </div>
    <div id="new-field">
        ...
        <select name="product[]" id="product"></select>       
        ...
        <input type="text" name="quantity[]" value="{{ old('quantity') }}" >
        ...
        <input type="text" name="price[]" disabled id="price">
        ...
    </div>
</div>

Note particularly that you have doubled-up id attributes for new-field, product and price.

id is supposed to be unique in HTML.

Then, when your price update code runs, it's always going to cause an issue. The HTML engine in your browser is ignoring all the duplicate id attributes:

// This line tries to get the unique element with the id "product"
// after it's found it (i.e. the first element in the DOM), it stops
// so this line only selects the first element with an id of "product"
$("#product").change(function(e) {
    e.preventDefault();
    axios.get("/ims/api/get-price/" + $(this).val())
        .then(function(response) {

            // This line tries to get the unique element with the id
            // "price", after it finds the first one, it stops looking
            // so this will never select the duplicated elements.
            $("#price").val(response.data.price);

        });
})

To fix it, you need to stop using id to select the product. Do something like this:

Change your id attributes on the #new-field, #product and #price elements to class:

<div class="new-field">
    <select name="product[]" class="product"></select>
    ...
    <input type="text" name="price[]" disabled class="price">
</div>

And modify your JS to select based on class:

$(".wrapper").on('change', '.product', function(e) {
    e.preventDefault();
    axios.get("/ims/api/get-price/" + $(this).val())
        .then(function(response) {

            $(this).parent('.new-field').find('.price').val(response.data.price);

        });
})

You'll also need to update your JavaScript to correctly add new products.

Ad
source: stackoverflow.com
Ad