0

below is my order form where i am taking inputs for item count. On the basis of that , dynamically Input boxe comes for quantity and rates .. Now whenever user enters quantity and rate, amount should be calculated correspondingly and displayed in amount textbox.

<!DOCTYPE html>
<html>
<head>
    <title>Order Form</title>
    <script>
        function addItemDetails() {
            var itemCount = document.getElementById("item_count").value;
            var itemDetailsDiv = document.getElementById("item_details");

            itemDetailsDiv.innerHTML = ""; // Clear previous item details

            for (var i = 1; i <= itemCount; i++) {
                var itemDetailHTML = `
                    <div>
                        <h3>Item ${i}</h3>
                        <label for="item_name_${i}">Item Name:</label>
                        <input type="text" name="item_name_${i}" required>
                        
                        <label for="qty_${i}">Qty:</label>
                        <input type="number" name="qty_${i}" min="1" required>
                        
                        <label for="rate_${i}">Rate:</label>
                        <input type="number" name="rate_${i}" min="0.01" step="0.01" required>
                        
                        <label for="amount_${i}">Amount:</label>
                        <input type="number" name="amount_${i}" readonly>
                    </div>
                `;
                itemDetailsDiv.innerHTML += itemDetailHTML;
            }
        }
        $(".rate_${i}").bind("blur", calculateAmount);
        function calculateAmount(itemIndex) {
            //document.write(5+6);
            var qty = parseFloat(document.getElementsByName(`qty_${itemIndex}`)[0].value);
            var rate = parseFloat(document.getElementsByName(`rate_${itemIndex}`)[0].value);
            var amount = qty * rate;
            document.getElementsByName(`amount_${itemIndex}`)[0].value = amount.toFixed(2);
        }
    </script>
</head>
<body>
    <h2>Order Form</h2>
    <form method="post" action="process_order.php">
        <label for="customer_name">Customer Name:</label>
        <input type="text" name="customer_name" required><br>
        
        <label for="mobile_number">Mobile Number:</label>
        <input type="text" name="mobile_number" required><br>
        
        <label for="item_count">Item Count:</label>
        <input type="number" name="item_count" id="item_count" min="1" onchange="addItemDetails()" required><br>
        
        <div id="item_details"></div>
        
        <button type="submit">Submit Order</button>
    </form>
</body>
</html>

I am having issues while calling calculateAmount function- when should it call? if i provide on change function also for qty, it is not working.

and further how would i pass index to calculate amount function? Please help !!

Barmar
  • 741,623
  • 53
  • 500
  • 612
Coder
  • 81
  • 13
  • Why are you not including the jQuery library in your code? After you include it then you'd get a second error in the console for `$(".rate_${i}").bind("blur", calculateAmount);` ***Error: Syntax error, unrecognized expression: .rate_${i}***. Also, use `.on()` method instead of `.bind()` – Roko C. Buljan Aug 24 '23 at 20:51
  • I dont know how to use jquery library ! can you please elaborate? – Coder Aug 24 '23 at 20:53
  • Sure I can: `$(".rate_${i}")` is jQuery syntax. Not plain JavaScript. If you don't want to use jQuery (not needed nowadays) then use `document.querySelector(".rate_${i}").addEventListener("blur", calculateAmount);` - but clearly, not outside the desired funtion and loop block. – Roko C. Buljan Aug 24 '23 at 20:54
  • Can you tell me exactly at which place it should be used? – Coder Aug 24 '23 at 20:55
  • In the same block of code where you use all the other `${i}` – Roko C. Buljan Aug 24 '23 at 20:56
  • Another problem: To use `${i}` you have to write a template literal, not an ordinary string. Template literals use backticks instead of quotes as the delimiters. – Barmar Aug 24 '23 at 20:58
  • I have tried using it ! Can you check here ? https://jsfiddle.net/nsf9gr4m/ – Coder Aug 24 '23 at 20:59
  • @Barmar woops great catch. Eagle eyes. Yes, there's also missing backticks – Roko C. Buljan Aug 24 '23 at 21:00
  • The `.` prefix in a selector is for class. You don't have `class="rate_${i}"` in your HTML. – Barmar Aug 24 '23 at 21:00
  • Don't bind a separate click handler to each input. Just give them all `class="rate"`, and then use `$(".rate").click(calculateAmount)` – Barmar Aug 24 '23 at 21:01
  • `.bind()` is deprecated, you should be using `.on()`. – Barmar Aug 24 '23 at 21:01
  • I really think overall the above code needs a complete rewrite. Not sure if it's just easily salvageable by just fixing here and there... – Roko C. Buljan Aug 24 '23 at 21:02
  • Since you're adding these dynamically, you should use event delegation. See https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements – Barmar Aug 24 '23 at 21:02
  • Can you guys please help me in jsfiddle. I have change blur to on, class is added. still not working – Coder Aug 24 '23 at 21:03
  • @Barmar OP is actually not using jQuery at all. That line was most likely a remnant from another source. – Roko C. Buljan Aug 24 '23 at 21:04
  • Also notice that you use the `for=""` attribute wrongly. `for` should be related to an Input's `is`, not to the `name`. Actually the `for` is not needed at all if you wrap input in the label element. – Roko C. Buljan Aug 24 '23 at 21:14

1 Answers1

0

I have made a bunch of updates.

First, I'm using [name^=''] a lot in my CSS selectors. This will allow you to delegate the event handler to a function that only needs to be created once and will respond to dynamic fields.

Then when the rate is inputted, I grab the closest div as that becomes the "group" where all of the other fields are children of. Then I simply use find on that group to find the related fields.

$(document).on("input","[name^='rate_']", calculateAmount);
      $("[name='item_count']").on("input",addItemDetails);
      
        function calculateAmount(e) {
           const group = $(this).closest("div");
           const qty = parseFloat(group.find("[name^='qty_']").val());
           const rate = parseFloat(group.find("[name^='rate_']").val());
           group.find("[name^='amount_']").val((qty * rate).toFixed(2));
        }
        
        

function addItemDetails() {
            var itemCount = document.getElementById("item_count").value;
            var itemDetailsDiv = document.getElementById("item_details");

            itemDetailsDiv.innerHTML = ""; // Clear previous item details

            for (var i = 1; i <= itemCount; i++) {
                var itemDetailHTML = `
                    <div>
                        <h3>Item ${i}</h3>
                        <label for="item_name_${i}">Item Name:</label>
                        <input type="text" name="item_name_${i}" required>
                        
                        <label for="qty_${i}">Qty:</label>
                        <input type="number" name="qty_${i}" min="1" required>
                        
                        <label for="rate_${i}">Rate:</label>
                        <input type="number" name="rate_${i}" min="0.01" step="0.01" required>
                        
                        <label for="amount_${i}">Amount:</label>
                        <input type="number" name="amount_${i}" readonly>
                    </div>
                `;
                itemDetailsDiv.innerHTML += itemDetailHTML;
            }
        }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h2>Order Form</h2>
    <form method="post" action="process_order.php">
        <label for="customer_name">Customer Name:</label>
        <input type="text" name="customer_name" required><br>
        
        <label for="mobile_number">Mobile Number:</label>
        <input type="text" name="mobile_number" required><br>
        
        <label for="item_count">Item Count:</label>
        <input type="number" name="item_count" id="item_count" min="1" required><br>
        
        <div id="item_details"></div>
        
        <button type="submit">Submit Order</button>
    </form>
imvain2
  • 15,480
  • 1
  • 16
  • 21
  • Can you also help me with process_order.php ? where i am calculating total of all the amounts calculated here? – Coder Aug 24 '23 at 21:20