Xoog
Xoog

Reputation: 926

changing value of text field using keyup issues

I am dynamically inserting rows onto a page. What I'm trying to do is calculate all the Monday input data and show it in a total box. Numbers can be input in either whole numbers or in .25, .50, .75 increments and it will round up if you use any number in between.

I have this working when I use blur but I'd really like it to work on keyup so it updates on the fly.

My issue is that if I use keyup, the value will automatically change back to the value corrected value, unless I hold down delete. Type 2.23 for an example of this.

Without completely re-writing my code, is there a way I can have the total field update on the fly? I have been scratching my head over this most of the afternoon. Any help is appreciated.

$(document).on('keyup', '.Monday', findTotalMon);

function findTotalAll() {
  var arr = document.getElementsByName('total');
  var tot = 0;
  for (var i = 0; i < arr.length; i++) {
    if (parseFloat(arr[i].value))
      tot += parseFloat(arr[i].value);
  }
  document.getElementById('totalHoursAll').value = tot;
  if (tot === 0) {
    document.getElementById('totalHoursAll').value = '';
  }
}

function findTotalMon() {

  var arr = document.getElementsByClassName('Monday');

  var tot = 0;

  for (var i = 0; i < arr.length; i++) {
    if (parseFloat(arr[i].value)) {
        var newValue = '';
        newValue = (.25 * Math.round(4 * arr[i].value));
        arr[i].value = newValue;
        tot += parseFloat(newValue);
        
    }
  }

  document.getElementById('totalHoursMon').value = tot;
  if (tot === 0) {
    document.getElementById('totalHoursMon').value = '';
  }
 
  findTotalAll();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input class="form-control full-width Monday" name="monday" id="monday" type="number" />
<input name="total" id="totalHoursMon" type="text" readonly/>

Upvotes: 1

Views: 845

Answers (1)

Raphael Cunha
Raphael Cunha

Reputation: 1114

Original Answer


I’m on a mobile device, but I’m gonna try to explain what I meant.

$(document).on('keyup', '.Monday', findTotalMon);

function findTotalAll() {
  var arr = document.getElementsByName('total');
  var tot = 0;
  for (var i = 0; i < arr.length; i++) {
if (parseFloat(arr[i].value))
  tot += parseFloat(arr[i].value);
  }
  document.getElementById('totalHoursAll').value = tot;
  if (tot === 0) {
document.getElementById('totalHoursAll').value = '';
  }
}

function findTotalMon() {

  var arr = document.getElementsByClassName('Monday');

  var tot = 0;

  for (var i = 0; i < arr.length; i++) {
if (parseFloat(arr[i].value)) {
    var newValue = '';
    newValue = (.25 * Math.round(4 * arr[i].value));

    // Don’t change this value yet
    // This is causing the input to change as you type
    /* arr[i].value = newValue; */

   // Instead you can create an html element next to the input
  // And update the element with the new value
  // After the user clicks out of the input you can then either update the input with the new value
  // Or you can leave the input the way it is and keep the updated values beside the input 



    tot += parseFloat(newValue);

}
  }

  document.getElementById('totalHoursMon').value = tot;
  if (tot === 0) {
document.getElementById('totalHoursMon').value = '';
  }

  findTotalAll();
}

Edited Answer


This is what I had in mind when trying to explain above.

$(document).ready(function() {  
  // Set event listener on '.Monday' inputs
  $(document).on('keyup', '.Monday', findTotalMon);
  
  // Set event listener to add new input
  $('body').on('click', '#addMore', addInput);
  
  
  
  /**
   * Add new input
   */
  function addInput() {
    // Get array with all elements with class 'monday-group'
    var arr = $('.monday-group');
    // Get array length
    var length = arr.length;
    // Set length to the insert next number
    var inputIndex = length;
    // HTML code for the new input
    var newInput = '<div class="form-group col-md-4 monday-group">' +
                 '<input class="form-control full-width Monday d-inline-block mt-2 w-75" name="monday_' + inputIndex + '" id="monday_' + inputIndex + '" type="number" placeholder="Monday-' + inputIndex + '" />' +
                 '<span class="adjusted-' + inputIndex + ' text-muted d-inline-block ml-4"></span>' +
                '</div>';

    // Check if there are 5 fields or less
    // If there are 5 fields then hide the add more button
    if ( length >= 5 ) {
      $('#addMore').css('display', 'none');
      return false;
    }

    // Insert the new input field
    $(newInput).insertAfter(arr[length - 1]);
  }

  /**
  * Get grand total
  */
  function findTotalAll() {
    // Get array with all inputs with the class of 'row-total'
    var arr = $('.row-total');
    // Set total = 0
    var tot = 0;
    
    // Loop through array and add value to totals
    for (var i = 0; i < arr.length; i++) {
      if (parseFloat(arr[i].value))
        tot += parseFloat(arr[i].value);
    }
    
    // Show the totals
    $('#totalHoursAll').val(tot);
    
    // If totals = 0 then leave the totals input blank instead of 0
    if (tot === 0) {
      $('#totalHoursAll').val('');
    }
  }

  /**
  * Find totals for Monday
  */
  function findTotalMon() {
    // Get inputs with a class of 'Monday'
    var arr = $('.Monday');
    // Set totals to 0
    var tot = 0;

    // Loop through array adding the totals
    for (var i = 0; i < arr.length; i++) {
      if (parseFloat(arr[i].value)) {
        var newValue = '';
        // Calculate the adjusted value
        newValue = (.25 * Math.round(4 * arr[i].value));

        // This is the faded text with the adjusted value
        // Include the adjusted value and display in case it is hidden
        $('.adjusted-' + i).html(newValue).css('display', 'block');

        // Set the total value
        tot += parseFloat(newValue);
      } else {
        // Hide the adjusted value and make it blank
        $('.adjusted-' + i).html('').css('display', 'none');
      }
    }

    // Update the totals
    $('#totalHoursMon').val(tot);
    
    // If totals = 0 then leave the field blank instead of 0
    if (tot === 0) {
      $('#totalHoursMon').val('');
    }

    // Calculate Grand Totals
    findTotalAll();
  }
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.2/css/bootstrap.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>


<div class="container mt-4">
  <div class="row">
    <div class="col-12">
      <div class="form-group col-md-4 monday-group">
        <input class="form-control full-width Monday d-inline-block w-75" name="monday_0" id="monday_0" type="number" placeholder="Monday-0" />
        <span class="adjusted-0 text-muted d-inline-block ml-4"></span>
      </div>
      
      <div class="col-md-4">
        <input type="text" class="form-control row-total" id="totalHoursMon" placeholder="Monday Totals" readonly>
      <button id="addMore" class="btn btn-primary mt-4">Add More</button>
      </div>
    </div>
  </div>
  <div class="row mt-4">
    <div class="col-md-4 offset-md-8">
      <input class="form-control" name="total" id="totalHoursAll" type="text" placeholder="Grand Total" readonly/>
    </div>
  </div>
</div>

Upvotes: 1

Related Questions