0

I try to achieve Total of two input fields and those fields got their value dynamically from database after selecting a dropdown option. The html code and the sql query looks like below:

<select name="getData" ID="getData" onchange="getData()">
    <option value="Select">Select Subscription Package</option>
    <?php
    $sql = "SELECT * FROM package WHERE status = 1";
    $result = $connect->query($sql);
    while($row = mysqli_fetch_row($result)){ 
        echo '<option data-price="'.$row[4].'" value='.$row[0].'> '.$row[1].' </option>';
        }
    ?>
</select>
<input type="text" id="price1" name="price1"/>
<input type="text" id="price2" name="price2"/>
<input type="text" id="totalAmount" name="totalAmount" onblur="totalCalc()">

Value of price1 & price2 changes when SELECT Option changed. Now I need to get total of these two fields by javascript. The js code is below:

<script>
    function totalCalc() {
        var A = document.getElementById("price1").value;
        var B = document.getElementById("price2").value;
        var C = A + B;
        document.getElementById("totalAmount").value = C;
    }
</script>

I got the total but it needs to click the total amount field. I want the calculation should be done automatically right after the first two fields got their values dynamically.

Any help is appreciated.

  • Just set up a `change` event handler for each of the two `input` fields that calls `totalCalc`. – Scott Marcus Oct 31 '18 at 14:33
  • Did u mean onchange = "totalCalc()" in both the input fields? – Jahangir Hossain Oct 31 '18 at 14:34
  • Well, that's if you used inline HTML event attributes. But, [that technique should no longer be used](https://stackoverflow.com/questions/43459890/javascript-function-doesnt-work-when-link-is-clicked/43459991#43459991) (although everyone still does). I mean more like `inputReference1.addEventListener("change", totalCalc)` and `inputReference2.addEventListener("change", totalCalc)`. – Scott Marcus Oct 31 '18 at 14:36
  • If that technique should no longer be used then what is the best practice. JS is not my cup of tea. But that simple sum created the complication. If u please tell me the best way to solve this. TIA – Jahangir Hossain Oct 31 '18 at 14:46
  • The best practice is to do what I showed (and linked to). Separate your JavaScript from your HTML and use the DOM `.addEventListener()` method to configure event callbacks. See my answer below for a working example. – Scott Marcus Oct 31 '18 at 14:58

1 Answers1

0

You should just set up change event handlers on both inputs that point to your totalCalc function and then, at the end of your getData() function, manually trigger the change event of one of the inputs.

If the code in getData is asynchronous, then the code that manually triggers the change event should be included in the success handler of the operation.

A note about the UI. If the two price fields are being auto-populated and users won't be inputting anything into them manually, disabling the fields is probably appropriate. With regards to the final total, an input there may not make sense at all - you just need to show the result, so a span element would work.

Also, inline HTML event attributes (onclick, onchange, etc.) should not be used. There are many reasons why this 20+ year old technique needs to die the death it deserves, but because so many people don't take the time to really learn JavaScript and modern best-practices, they just copy someone else's code that uses them and go on their merry way.

So, in the code below, I'm showing how to solve this problem using modern, standards-based code that follows best-practices.

// Get references to the DOM elements you'll need to work with
let a = document.getElementById("price1");
let b = document.getElementById("price2");
let total = document.getElementById("totalAmount");
let select = document.getElementById("getData");
let price1 = document.getElementById("price1");
let price2 = document.getElementById("price2");

// Set up event handlers in JavaScript, not HTML
select.addEventListener("change", getData);
price1.addEventListener("change", totalCalc);
price2.addEventListener("change", totalCalc);

function totalCalc() {
  total.textContent = +a.value + +b.value;
}

function getData(){
  // This is just mean to replicate what SQL does
  price1.value = 15;
  price2.value = 27;

  // Manually trigger the change event for either one of the inputs
  // If the existing code in getData is asynchronous, then this code
  // should be added to the "success" callback. If not, it can just be
  // placed at the end of the function as I'm showing it here.
  var event = new Event('change');
  price1.dispatchEvent(event);
}
<select name="getData" id="getData">
    <option value="Select">Select Subscription Package</option>
    <option>Data 1 from SQL</option>
    <option>Data 2 from SQL</option>
    <option>Data 3 from SQL</option>        
</select>
<input type="text" id="price1" name="price1" disabled>
<input type="text" id="price2" name="price2" disabled>

<!-- No need to place the result in an <input> since users won't
     be inputted data here. You just need to show it.  -->
<span id="totalAmount"></span>
balpha
  • 50,022
  • 18
  • 110
  • 131
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • I'd suggest using the eventListener `input` instead of `change` to immediately trigger the function when the input is changed – T. Dirks Oct 31 '18 at 15:01
  • @T.Dirks When the `value` is dynamically altered, `input` won't fire (just as `change` won't). For both/either, you have to manually dispatch an event. – Scott Marcus Oct 31 '18 at 15:04
  • I agree with you on that for the dispatch event, but I was talking about the `.addEventListener`. I think you can change those to `input` to trigger once a key is pressed instead of waiting untill the inputfield is out of focus and the `change` event is triggered – T. Dirks Oct 31 '18 at 15:12
  • Thanks Scott for the help. But as I said I haven't sufficient knowledge on JS so its hard for me to execute. I tried the way u just showed but I didn't understand the part: function getData(){ // This is just mean to replicate what SQL does price1.value = 15; price2.value = 27; var event = new Event('change'); price1.dispatchEvent(event); } what should I write here in price1.value = 15? – Jahangir Hossain Oct 31 '18 at 15:19
  • @JahangirHossain You don't add anything except the 2 ` var event = new Event('change'); price1.dispatchEvent(event);` lines at the very end. The other code was added simply to simulate what your existing code already does (goes to the server and gets the data to populate the two input boxes). – Scott Marcus Oct 31 '18 at 16:33
  • @T.Dirks Users won't be inputting into those fields at all. The fields get auto-populated by server-side code. So neither the `input` or `change` events will fire at all for these fields (so it doesn't matter which is used with `.addEventListener`). Whichever event is used, that event has to be manually dispatched for this very reason. Because of the manual dispatching of the event, we won't have to wait for the field to lose the focus. – Scott Marcus Oct 31 '18 at 16:34
  • @ScottMarcus Ah I get it now, must've misunderstood it. My bad! – T. Dirks Nov 01 '18 at 07:37