Reputation: 926
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
Reputation: 1114
Original Answer
$(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
$(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