Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

theUnforgiven's avatar

Quick JS question.

I need to get the values on each day in a week to total up each day and at the end of the week, but me been a bit shit at maths and JS I can't seem to work it out.

here's the screen

You will see it uses a 24 hour clock so you will on Monday a 8 shift is done then I need to minus off the break time so 7.5 hours needs to show in the total box for that day, once all the week is filled up and calculated I then need to show the full weekly amount of hours worked again minus the break time.

I have tried this:

function sum(){
        var a = parseInt($('input[data-attribute="startTime"]').val());
        var b = parseInt($('input[data-attribute="finishTime"]').val());

        var total = a+b;
        $('#total').val(a+b);
    }

But to no avail as I'm not sure how to do go about this, so please be gentle!

0 likes
36 replies
phildawson's avatar

Well I would say parsing the 'HH:MM:SS' into an integer is never going to be right. You'll be wanting to split it up into seconds. Then doing your finish - start - breaks and then converting to hours.

function hmsToSeconds(hms)
{
    var times = hms.split(':');
    var hrs = parseInt(times[0]);
    var mins = parseInt(times[1]);
    var secs = parseInt(times[2]);

    return (hrs*3600)+(mins*60)+secs;
}

function totalSecondsWorked(start, finish, breaks)
{
    return hmsToSeconds(finish) - hmsToSeconds(start) - hmsToSeconds(breaks);
}

function nearestFullHour(seconds)
{
    return Math.ceil(seconds/3600);
}

var start = '09:30:00';
var finish = '17:45:00';
var breaks = '00:30:00';

var totalSecondsWorked = totalSecondsWorked(start, finish, breaks);
var nearestFullHour = nearestFullHour(totalSecondsWorked);

alert(nearestFullHour);

Also if more than one row has that data-attribute it isn't going to work how it is atm. I assume one row per day.

2 likes
theUnforgiven's avatar

I have it set out like this.

With the html been outputted as:

<table class="table table-striped">
                        <thead>
                        <tr>
                            <th>Day</th>
                            <th>Start Time (24h)</th>
                            <th>End Time (24h)</th>
                            <th>Breaks</th>
                            <th>Payable Mileage</th>
                            <th>Total Payable Hours</th>
                            <th>Comments</th>
                        </tr>
                        </thead>
                        <tbody>
                                                <tr>
                            <td>
                                <label class="control-label">
                                    Monday                                </label>
                            </td>
                            <td>
                                <input class="form-control timepicker start" autocomplete="off" data-attribute="startTime" name="monday[startTime]" type="text">                            </td>

                            <td>
                                <input class="form-control timepicker finish" autocomplete="off" data-attribute="finishTime" name="monday[endTime]" type="text">                            </td>

                            <td>
                                <input type="text" name="breaks" class="form-control" autocomplete="off">
                            </td>

                            <td>
                                <input class="form-control" data-attribute="payableMileage" min="0" name="monday[payableMileage]" type="number" value="0">                            </td>

                            <td>
                                                                    <input name="total" id ="total" type="text" class="form-control" readonly>
                            </td>

                            <td>
                                <input class="form-control" name="monday[comments]" type="text">                            </td>
                        </tr>
                                                <tr>
                            <td>
                                <label class="control-label">
                                    Tuesday                                </label>
                            </td>
                            <td>
                                <input class="form-control timepicker start" autocomplete="off" data-attribute="startTime" name="tuesday[startTime]" type="text">                            </td>

                            <td>
                                <input class="form-control timepicker finish" autocomplete="off" data-attribute="finishTime" name="tuesday[endTime]" type="text">                            </td>

                            <td>
                                <input type="text" name="breaks" class="form-control" autocomplete="off">
                            </td>

                            <td>
                                <input class="form-control" data-attribute="payableMileage" min="0" name="tuesday[payableMileage]" type="number" value="0">                            </td>

                            <td>
                                                                    <input name="total" id ="total" type="text" class="form-control" readonly>
                            </td>

                            <td>
                                <input class="form-control" name="tuesday[comments]" type="text">                            </td>
                        </tr>
                                                <tr>
                            <td>
                                <label class="control-label">
                                    Wednesday                                </label>
                            </td>
                            <td>
                                <input class="form-control timepicker start" autocomplete="off" data-attribute="startTime" name="wednesday[startTime]" type="text">                            </td>

                            <td>
                                <input class="form-control timepicker finish" autocomplete="off" data-attribute="finishTime" name="wednesday[endTime]" type="text">                            </td>

                            <td>
                                <input type="text" name="breaks" class="form-control" autocomplete="off">
                            </td>

                            <td>
                                <input class="form-control" data-attribute="payableMileage" min="0" name="wednesday[payableMileage]" type="number" value="0">                            </td>

                            <td>
                                                                    <input name="total" id ="total" type="text" class="form-control" readonly>
                            </td>

                            <td>
                                <input class="form-control" name="wednesday[comments]" type="text">                            </td>
                        </tr>
                                                <tr>
                            <td>
                                <label class="control-label">
                                    Thursday                                </label>
                            </td>
                            <td>
                                <input class="form-control timepicker start" autocomplete="off" data-attribute="startTime" name="thursday[startTime]" type="text">                            </td>

                            <td>
                                <input class="form-control timepicker finish" autocomplete="off" data-attribute="finishTime" name="thursday[endTime]" type="text">                            </td>

                            <td>
                                <input type="text" name="breaks" class="form-control" autocomplete="off">
                            </td>

                            <td>
                                <input class="form-control" data-attribute="payableMileage" min="0" name="thursday[payableMileage]" type="number" value="0">                            </td>

                            <td>
                                                                    <input name="total" id ="total" type="text" class="form-control" readonly>
                            </td>

                            <td>
                                <input class="form-control" name="thursday[comments]" type="text">                            </td>
                        </tr>
                                                <tr>
                            <td>
                                <label class="control-label">
                                    Friday                                </label>
                            </td>
                            <td>
                                <input class="form-control timepicker start" autocomplete="off" data-attribute="startTime" name="friday[startTime]" type="text">                            </td>

                            <td>
                                <input class="form-control timepicker finish" autocomplete="off" data-attribute="finishTime" name="friday[endTime]" type="text">                            </td>

                            <td>
                                <input type="text" name="breaks" class="form-control" autocomplete="off">
                            </td>

                            <td>
                                <input class="form-control" data-attribute="payableMileage" min="0" name="friday[payableMileage]" type="number" value="0">                            </td>

                            <td>
                                                                    <input name="total" id ="total" type="text" class="form-control" readonly>
                            </td>

                            <td>
                                <input class="form-control" name="friday[comments]" type="text">                            </td>
                        </tr>
                                                <tr>
                            <td>
                                <label class="control-label">
                                    Saturday                                </label>
                            </td>
                            <td>
                                <input class="form-control timepicker start" autocomplete="off" data-attribute="startTime" name="saturday[startTime]" type="text">                            </td>

                            <td>
                                <input class="form-control timepicker finish" autocomplete="off" data-attribute="finishTime" name="saturday[endTime]" type="text">                            </td>

                            <td>
                                <input type="text" name="breaks" class="form-control" autocomplete="off">
                            </td>

                            <td>
                                <input class="form-control" data-attribute="payableMileage" min="0" name="saturday[payableMileage]" type="number" value="0">                            </td>

                            <td>
                                                                    <input name="total" id ="total" type="text" class="form-control" readonly>
                            </td>

                            <td>
                                <input class="form-control" name="saturday[comments]" type="text">                            </td>
                        </tr>
                                                <tr>
                            <td>
                                <label class="control-label">
                                    Sunday                                </label>
                            </td>
                            <td>
                                <input class="form-control timepicker start" autocomplete="off" data-attribute="startTime" name="sunday[startTime]" type="text">                            </td>

                            <td>
                                <input class="form-control timepicker finish" autocomplete="off" data-attribute="finishTime" name="sunday[endTime]" type="text">                            </td>

                            <td>
                                <input type="text" name="breaks" class="form-control" autocomplete="off">
                            </td>

                            <td>
                                <input class="form-control" data-attribute="payableMileage" min="0" name="sunday[payableMileage]" type="number" value="0">                            </td>

                            <td>
                                                                    <input name="total" id ="total" type="text" class="form-control" readonly>
                            </td>

                            <td>
                                <input class="form-control" name="sunday[comments]" type="text">                            </td>
                        </tr>
phildawson's avatar

It's going to much easier to do this in a framework Angular, React, Vue etc and generate the day rows dynamically.

Here's a quick example of what I might do based on my code above adding a calculateDay. At least for a first prototype anyway.

The totals are calculated on init, and after pressing enter on any of the time inputs. No validation included.

<table>
<tr>
    <th>day</th>
    <th>start</th>
    <th>finish</th>
    <th>breaks</th>
    <th>total</th>
</tr>
<tr>
    <th>Monday</th>
    <td>
    <input data-day="monday" class="cal" name="monday[start]" value="09:30:00" />
    </td>
    <td>
    <input data-day="monday" class="cal" name="monday[finish]" value="17:45:00" />
    </td>
    <td>
    <input data-day="monday" class="cal" name="monday[breaks]" value="00:30:00" />
    </td>
    <td><input readonly name="monday[total]" /></td>
</tr>
<tr>
    <th>Tuesday</th>
    <td>
    <input data-day="tuesday" class="cal" name="tuesday[start]" value="08:40:00" />
    </td>
    <td>
    <input data-day="tuesday" class="cal" name="tuesday[finish]" value="16:25:40" />
    </td>
    <td>
    <input data-day="tuesday" class="cal" name="tuesday[breaks]" value="01:45:00" />
    </td>
    <td><input readonly name="tuesday[total]" /></td>
</tr>
</table>
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
function hmsToSeconds(hms)
{
    var times = hms.split(':');
    var hrs = parseInt(times[0]);
    var mins = parseInt(times[1]);
    var secs = parseInt(times[2]);

    return (hrs*3600)+(mins*60)+secs;
}

function totalSecondsWorked(start, finish, breaks)
{
    return hmsToSeconds(finish) - hmsToSeconds(start) - hmsToSeconds(breaks);
}

function nearestFullHour(seconds)
{
    return Math.ceil(seconds/3600);
}

function calculateDay(day)
{
    var start = $("input[name='"+day+"[start]']").val();
    var finish = $("input[name='"+day+"[finish]']").val();
    var breaks = $("input[name='"+day+"[breaks]']").val();

    var seconds = totalSecondsWorked(start, finish, breaks);
    var hours = nearestFullHour(seconds);

    $("input[name='"+day+"[total]']").val(hours);
}

$(function(){

    $.each([ 'monday', 'tuesday' ], function( index, day ) {
        calculateDay(day);
    });

    $(document).on('keyup', 'input.cal', function(e){
        if(e.keyCode != 13) return;

        calculateDay($(this).data('day'));
    });

});
</script>
1 like
phildawson's avatar

@lstables The best thing to do is open Chrome Developer Tools and click on Console and see what you get.

Based on your video you click between inputs, if you used the keyup code I put a return so it only calculates when enter is pressed on the input so it avoids validation to lustrate the example. In your code you'll to check it's a valid input.

The above example copied+pasted into a new file should work as a standalone example, it's just one way to crack a nut.

theUnforgiven's avatar

1st error in dev tools I see is Cannot read property 'split' of undefined and nothing else but I want this to fill the total for each day when the start, finish and break fields have been filled out, and not on form submission.

theUnforgiven's avatar

So how can I do on click or tab, based on just moving from one input to another. Rather than submit or enter

phildawson's avatar

Yeah so the split is causing an error as the input has no value. It's like doing this.

var x;
console.log(x.split(':'));

The enter was just used so I could type the correct format so it wouldn't complain, the initial values on finish/break also meant the error was not shown in my quick example.

As mentioned you'll want to check the input value and only use it if valid.

phildawson's avatar

@lstables I've spent another few mins and added a checkTime and removed the check so it only calculates when a valid hms value is entered and waits until the total hours is positive, this is just a very basic way to check but should be a starting point.

<table>
    <tr>
        <th>day</th>
        <th>start</th>
        <th>finish</th>
        <th>breaks</th>
        <th>total</th>
    </tr>
    <tr>
        <th>Monday</th>
        <td>
            <input data-day="monday" class="cal" name="monday[start]" />
        </td>
        <td>
            <input data-day="monday" class="cal" name="monday[finish]" />
        </td>
        <td>
            <input data-day="monday" class="cal" name="monday[breaks]" />
        </td>
        <td><input readonly name="monday[total]" /></td>
    </tr>
    <tr>
        <th>Tuesday</th>
        <td>
            <input data-day="tuesday" class="cal" name="tuesday[start]" />
        </td>
        <td>
            <input data-day="tuesday" class="cal" name="tuesday[finish]" />
        </td>
        <td>
            <input data-day="tuesday" class="cal" name="tuesday[breaks]" />
        </td>
        <td><input readonly name="tuesday[total]" /></td>
    </tr>
</table>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
    function hmsToSeconds(hms)
    {
        var times = hms.split(':');
        var hrs = parseInt(times[0]);
        var mins = parseInt(times[1]);
        var secs = parseInt(times[2]);

        return (hrs*3600)+(mins*60)+secs;
    }

    function totalSecondsWorked(start, finish, breaks)
    {
        return hmsToSeconds(finish) - hmsToSeconds(start) - hmsToSeconds(breaks);
    }

    function nearestFullHour(seconds)
    {
        return Math.ceil(seconds/3600);
    }

    function checkTime(value)
    {
        var patt = /([0-9][0-9]):([0-5][0-9]):([0-5][0-9])/;

        if (patt.test(value))
        {
            return value;
        }

        return '00:00:00';
    }

    function calculateDay(day)
    {
        var start = checkTime($("input[name='"+day+"[start]']").val());
        var finish = checkTime($("input[name='"+day+"[finish]']").val());
        var breaks = checkTime($("input[name='"+day+"[breaks]']").val());

        var seconds = totalSecondsWorked(start, finish, breaks);
        var hours = nearestFullHour(seconds);

        $("input[name='"+day+"[total]']").val(hours > 0 ? hours : 0);
    }

    $(function(){

        $.each([ 'monday', 'tuesday' ], function( index, day ) {
            calculateDay(day);
        });

        $(document).on('keyup', 'input.cal', function(e){
            calculateDay($(this).data('day'));
        });

    });
</script>
theUnforgiven's avatar

Ok get that as well, but still doesn't enter value in total when start, finish and break time as been entered?

phildawson's avatar

@lstables Have you cut and paste just checkTime and calculateDay functions (as I also removed the if(e.keyCode != 13) return; from the keyup) or are testing the whole script pasted into a new file and saved as it seems to do the expected if I try. My expected and your expected may be different.

In testing mine enter 00:09:00 in start then 15:00:00 in the finish. It will enter 6 in total when the last 0 of '15:00:00' is typed to pass the basic format validation. The hours > 0 ? hours : 0 stops the total being -9 until a finish time is entered.

theUnforgiven's avatar

Yes copied everything you posted into my file but nothing seems to be doing this has you so rightly say

phildawson's avatar

In debugging the code do you get any console messages? I can only go on my code working as I haven't seen yours other than the OP.

Instead of pasting snippets into your file, if you paste my entirety of my last code post into a brand new file and save and it should work to the expected as described above.

In testing mine enter 00:09:00 in start then 15:00:00 in the finish. It will enter 6 in total when the last 0 of '15:00:00' is typed to pass the basic format validation. The hours > 0 ? hours : 0 stops the total being -9 until a finish time is entered.

theUnforgiven's avatar

I've pasted the whole JS and then added the appropriate classes and data attributes but still not no avail :(

phildawson's avatar

lol, before altering the code at all, and just copy+paste into new file+save does it work?

It's probably gone past the 'Quick JS question.' :) but as for your version with the added classes and data attributes, if you paste it here, we might be able to spot what the issue is. It's near impossible to say what the issue might be without seeing any code.

theUnforgiven's avatar

It's a little long but this is the whole file.

@extends('app')
@section('title')
    Submit a Timesheet
@endsection
@section('content')
    <div class="panel panel-default">
        <div class="panel-heading">Submit Timesheet</div>
        <div class="panel-body">
            
            <div class="row">
                <div class="col-md-12">
                    <div class="form-group">
                        <label class="col-sm-2 control-label"><?php echo Lang::get('staff-timesheets.form.table.placement'); ?></label>
                        {!! Form::open(['url' => 'staff-timesheet']) !!}
                        <div class="col-sm-2">
                            <select name="placement" class="form-control">
                                @foreach($placements as $placement)
                                    <option value="{!! $placement->id !!}">{!! $placement->name !!}</option>
                                @endforeach
                            </select>
                        </div>

                        <label class="col-sm-2 control-label"><?php echo Lang::get('staff-timesheets.form.table.manager'); ?></label>
                        <div class="col-sm-2 {{ $errors->has('placementLineManager') ? 'has-error' : '' }}">
                            <?php
                            echo Form::text('placementLineManager', null, array(
                                    'class' => 'form-control',
                            ));
                            ?>
                            {!! $errors->first('placementLineManager', '<span class="help-block">required field</span>') !!}
                        </div>

                        <label class="col-sm-2 control-label"><?php echo Lang::get('staff-timesheets.form.table.week'); ?></label>
                        <div class="col-sm-2">
                            <?php
                            echo Form::select('weekCommencing', $weeks, null, array(
                                    'class' => 'form-control',
                            ));
                            ?>
                        </div>
                    </div>

                    <hr />

                    <table class="table table-striped">
                        <thead>
                        <tr>
                            <th><?php echo Lang::get('staff-timesheets.form.table.day'); ?></th>
                            <th><?php echo Lang::get('staff-timesheets.form.table.startTime'); ?></th>
                            <th><?php echo Lang::get('staff-timesheets.form.table.endTime'); ?></th>
                            <th>Breaks</th>
                            <th><?php echo Lang::get('staff-timesheets.form.table.payableMileage'); ?></th>
                            <th><?php echo Lang::get('staff-timesheets.form.table.totalPayableHours'); ?></th>
                            <th><?php echo Lang::get('staff-timesheets.form.table.comments'); ?></th>
                        </tr>
                        </thead>
                        <tbody>
                        <?php
                        foreach($days as $key=>$day) {
                        ?>
                        <tr>
                            <td>
                                <label class="control-label">
                                    <?php echo Lang::get('staff-timesheets.form.table.' . $day); ?>
                                </label>
                            </td>
                            <td>
                                <?php
                                echo Form::text($day . '[startTime]', (isset($timesheetDays[$key]) ? $timesheetDays[$key]->startTime : null), array(
                                        'class' => 'form-control timepicker calculate',
                                        'autocomplete' => 'off',
                                        'data-day' => $day,

                                ));
                                ?>
                            </td>

                            <td>
                                <?php
                                echo Form::text($day . '[endTime]', (isset($timesheetDays[$key]) ? $timesheetDays[$key]->endTime : null), array(
                                        'class' => 'form-control timepicker calculate',
                                        'autocomplete' => 'off',
                                        'data-day' => $day,
                                ));
                                ?>
                            </td>

                            <td>
                                <input type="text" name="breaks" class="form-control calculate" autocomplete="off" data-day="<?php echo $day; ?>">
                            </td>

                            <td>
                                <?php
                                echo Form::input('number', $day . '[payableMileage]', (isset($timesheetDays[$key]) ? $timesheetDays[$key]->payableMileage : 0), array(
                                        'class' => 'form-control',
                                        'data-attribute' => 'payableMileage',
                                        'min' => '0',
                                ));
                                ?>
                            </td>

                            <td>
                                <?php
                                //echo Form::text($day . '[totalPayableHours]', (isset($timesheetDays[$key]) ? $timesheetDays[$key]->totalPayableHours : null), array(
                                 //       'class' => 'form-control timepicker',
                                   //     'data-attribute' => 'totalPayableHours',
                                     //   'autocomplete' => 'off'
                                //));
                                ?>
                                    <input name="<?php echo $day; ?>[total]" id ="total" type="text" class="form-control" readonly>
                            </td>

                            <td>
                                <?php
                                echo Form::text($day . '[comments]', (isset($timesheetDays[$key]) ? $timesheetDays[$key]->comments : null), array(
                                        'class' => 'form-control',
                                ));
                                ?>
                            </td>
                        </tr>
                        <?php
                        }

                        ?>

                        <tr class="totals">
                            <td class="text-right" colspan="3">
                                <h3><?php echo Lang::get('staff-timesheets.form.table.totals'); ?></h3>
                            </td>
                            <td></td>
                            <td>
                                <h3 id="payableMileageTotal"><?php echo $payableMileageTotal; ?></h3>
                            </td>

                            <td colspan="2">
                                <h3 id="totalPayableHoursTotal"></h3>
                            </td>
                        </tr>
                        </tbody>
                    </table>
                    <div class="form-group">
                        <div class="col-lg-3">
                            <?php
                            echo Form::submit(Lang::get('staff-timesheets.form.table.save'), array(
                                    'class' => 'btn',
                                    'name' => 'save',
                            ));
                            ?>
                            {{--<a href="/staff-timesheet/save-later" class="btn btn-primary" name="save">Save for Later</a>--}}
                            {{--<button type="submit" class="btn btn-success" name="send">Submit Timesheet</button>--}}
                            <?php
                            echo Form::submit(Lang::get('staff-timesheets.form.table.submit'), array(
                                    'class' => 'btn-success btn',
                                    'name' => 'send',
                            ));
                            ?>
                        </div>
                    </div>
                    {!! Form::close() !!}
                </div>
            </div><!-- /row -->
        </div>
    </div>

@endsection
@section('endjs')
    <script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
    <script>
        function hmsToSeconds(hms)
        {
            var times = hms.split(':');
            var hrs = parseInt(times[0]);
            var mins = parseInt(times[1]);
            var secs = parseInt(times[2]);

            return (hrs*3600)+(mins*60)+secs;
        }

        function totalSecondsWorked(start, finish, breaks)
        {
            return hmsToSeconds(finish) - hmsToSeconds(start) - hmsToSeconds(breaks);
        }

        function nearestFullHour(seconds)
        {
            return Math.ceil(seconds/3600);
        }

        function checkTime(value)
        {
            var patt = /([0-9][0-9]):([0-5][0-9]):([0-5][0-9])/;

            if (patt.test(value))
            {
                return value;
            }

            return '00:00:00';
        }

        function calculateDay(day)
        {
            var start = checkTime($("input[name='"+day+"[start]']").val());
            var finish = checkTime($("input[name='"+day+"[finish]']").val());
            var breaks = checkTime($("input[name='"+day+"[breaks]']").val());

            var seconds = totalSecondsWorked(start, finish, breaks);
            var hours = nearestFullHour(seconds);

            $("input[name='"+day+"[total]']").val(hours > 0 ? hours : 0);
        }

        $(function(){

            $.each([ 'monday', 'tuesday', 'wednesday', 'thursday', 'friday' , 'saturday', 'sunday' ], function( index, day ) {
                calculateDay(day);
            });

            $(document).on('keyup', 'input.calculate', function(e){
                calculateDay($(this).data('day'));
            });

        });
    </script>
@endsection

phildawson's avatar

@lstables instead of the php code, can you post the rendered html of the page (ie view source then copy+paste). We can then open the file locally without needing to figure out what the blade is producing.

theUnforgiven's avatar

Just post to tuesday otherwise it's really long

                        <div class="col-sm-2">
                            <select name="placement" class="form-control">
                                                                    <option value="11">gkjhkjhk</option>
                                                            </select>
                        </div>

                        <label class="col-sm-2 control-label">Placement Manager</label>
                        <div class="col-sm-2 ">
                            <input class="form-control" name="placementLineManager" type="text">                            
                        </div>

                        <label class="col-sm-2 control-label">Week Commencing</label>
                        <div class="col-sm-2">
                            <select class="form-control" name="weekCommencing"><option value="2015-08-10">10/08/2015</option><option value="2015-08-03">03/08/2015</option><option value="2015-07-27">27/07/2015</option><option value="2015-07-20">20/07/2015</option><option value="2015-07-13">13/07/2015</option><option value="2015-07-06">06/07/2015</option><option value="2015-06-29">29/06/2015</option><option value="2015-06-22">22/06/2015</option><option value="2015-06-15">15/06/2015</option><option value="2015-06-08">08/06/2015</option><option value="2015-06-01">01/06/2015</option><option value="2015-05-25">25/05/2015</option></select>                        </div>
                    </div>

                    <hr />

                    <table class="table table-striped">
                        <thead>
                        <tr>
                            <th>Day</th>
                            <th>Start Time (24h)</th>
                            <th>End Time (24h)</th>
                            <th>Breaks</th>
                            <th>Payable Mileage</th>
                            <th>Total Payable Hours</th>
                            <th>Comments</th>
                        </tr>
                        </thead>
                        <tbody>
                                                <tr>
                            <td>
                                <label class="control-label">
                                    Monday                                </label>
                            </td>
                            <td>
                                <input class="form-control timepicker calculate" autocomplete="off" data-day="monday" name="monday[startTime]" type="text">                            </td>

                            <td>
                                <input class="form-control timepicker calculate" autocomplete="off" data-day="monday" name="monday[endTime]" type="text">                            </td>

                            <td>
                                <input type="text" name="breaks" class="form-control calculate" autocomplete="off" data-day="monday">
                            </td>

                            <td>
                                <input class="form-control" data-attribute="payableMileage" min="0" name="monday[payableMileage]" type="number" value="0">                            </td>

                            <td>
                                                                    <input name="monday[total]" id ="total" type="text" class="form-control" readonly>
                            </td>

                            <td>
                                <input class="form-control" name="monday[comments]" type="text">                            </td>
                        </tr>
                                                <tr>
                            <td>
                                <label class="control-label">
                                    Tuesday                                </label>
                            </td>
                            <td>
                                <input class="form-control timepicker calculate" autocomplete="off" data-day="tuesday" name="tuesday[startTime]" type="text">                            </td>

                            <td>
                                <input class="form-control timepicker calculate" autocomplete="off" data-day="tuesday" name="tuesday[endTime]" type="text">                            </td>

                            <td>
                                <input type="text" name="breaks" class="form-control calculate" autocomplete="off" data-day="tuesday">
                            </td>

                            <td>
                                <input class="form-control" data-attribute="payableMileage" min="0" name="tuesday[payableMileage]" type="number" value="0">                            </td>

                            <td>
                                                                    <input name="tuesday[total]" id ="total" type="text" class="form-control" readonly>
                            </td>

                            <td>
                                <input class="form-control" name="tuesday[comments]" type="text">                            </td>
                        </tr>
theUnforgiven's avatar

Then at the bottom the corresponding JS provided by you Phil.

<script>
        function hmsToSeconds(hms)
        {
            var times = hms.split(':');
            var hrs = parseInt(times[0]);
            var mins = parseInt(times[1]);
            var secs = parseInt(times[2]);

            return (hrs*3600)+(mins*60)+secs;
        }

        function totalSecondsWorked(start, finish, breaks)
        {
            return hmsToSeconds(finish) - hmsToSeconds(start) - hmsToSeconds(breaks);
        }

        function nearestFullHour(seconds)
        {
            return Math.ceil(seconds/3600);
        }

        function checkTime(value)
        {
            var patt = /([0-9][0-9]):([0-5][0-9]):([0-5][0-9])/;

            if (patt.test(value))
            {
                return value;
            }

            return '00:00:00';
        }

        function calculateDay(day)
        {
            var start = checkTime($("input[name='"+day+"[start]']").val());
            var finish = checkTime($("input[name='"+day+"[finish]']").val());
            var breaks = checkTime($("input[name='"+day+"[breaks]']").val());

            var seconds = totalSecondsWorked(start, finish, breaks);
            var hours = nearestFullHour(seconds);

            $("input[name='"+day+"[total]']").val(hours > 0 ? hours : 0);
        }

        $(function(){

            $.each([ 'monday', 'tuesday', 'wednesday', 'thursday', 'friday' , 'saturday', 'sunday' ], function( index, day ) {
                calculateDay(day);
            });

            $(document).on('keyup', 'input.calculate', function(e){
                calculateDay($(this).data('day'));
            });

        });
    </script>
theUnforgiven's avatar

@phildawson great thanks really appreciate your help and FYI i started learning vueJS last night so this sort of problem doesn't stop me in future :)

phildawson's avatar

@lstables Two things I've spotted which need to be changed to make it work.

The field names are startTime and endTime not start and finish.

var start = checkTime($("input[name='"+day+"[startTime]']").val());
var finish = checkTime($("input[name='"+day+"[endTime]']").val());

The breaks should have:

name="monday[breaks]" and name="tuesday[breaks]"
theUnforgiven's avatar

That's it! My bad, always good to have a second pair or eyes on it, thanks @phildawson greatly appreciated. I knew it would be something I missed.

theUnforgiven's avatar

I just need it to minus the breaks now as people won't be paid for breaks so 08:00 to 18:00 is 10 hours but with a 30 minute is 9.5 hours, how can this be achieved?

phildawson's avatar

@lstables it's already working like that :) enter 00:30:00 in the breaks input.

return hmsToSeconds(finish) - hmsToSeconds(start) - hmsToSeconds(breaks); // <<<

If you just want to enter the minutes like 30 then change the above line to

return hmsToSeconds(finish) - hmsToSeconds(start) - (breaks*60);

^ 60 seconds in a minute :)

If you've kept the Math.ceil then remember it's being rounded up to the nearest int. so 9hrs 45min with a 30 min break is still 10 hrs.

theUnforgiven's avatar

@phildawson Are right that ceil may need to come out then I need it to say a user worked 9hrs 45 mins with a 30 min break not included within that, so should I just remove the Math.ceil method?

Next

Please or to participate in this conversation.