improved duration and minute selector (#2264)
* do not close modal if form is dirty * deprecated TimesheetConfiguration * inject timezone in form types * cleanup usage of UserDateTimeFactory * allow to configure increment steps for minutes * use 15 minutes step for datetimepicker in project edit form * use rounding rules for increments in minute select for begin and end * allow duration in multi user and admin timesheet forms * make dropdown values configurable
This commit is contained in:
@@ -94,18 +94,23 @@
|
||||
{% if form.begin is defined and form.end is defined and form.duration is defined %}
|
||||
{% set blockPrefix = form.vars.id %}
|
||||
<script type="text/javascript">
|
||||
$('body').on('blur change', '#{{ blockPrefix }}_begin', function(ev) {
|
||||
$('body').on('change', '#{{ blockPrefix }}_begin', function(ev) {
|
||||
changedBegin($(this).val());
|
||||
});
|
||||
|
||||
$('body').on('blur change', '#{{ blockPrefix }}_end', function(ev) {
|
||||
$('body').on('change', '#{{ blockPrefix }}_end', function(ev) {
|
||||
changedEnd($(this).val());
|
||||
});
|
||||
|
||||
$('body').on('blur change', '#{{ blockPrefix }}_duration', function(ev) {
|
||||
changedDuration($(this).val());
|
||||
$('body').on('change', '#{{ blockPrefix }}_duration', function(ev) {
|
||||
changedDuration();
|
||||
});
|
||||
|
||||
|
||||
function getDurationField()
|
||||
{
|
||||
return document.getElementById('{{ blockPrefix }}_duration');
|
||||
}
|
||||
|
||||
{#
|
||||
Ruleset:
|
||||
- invalid begin => skip
|
||||
@@ -117,15 +122,14 @@
|
||||
function changedBegin(value)
|
||||
{
|
||||
var endField = document.getElementById('{{ blockPrefix }}_end');
|
||||
var durationField = document.getElementById('{{ blockPrefix }}_duration');
|
||||
var format = endField.dataset.format;
|
||||
var momentDuration = moment.duration(durationField.value);
|
||||
var momentDuration = getParsedDuration();
|
||||
|
||||
var momentBegin = moment(value, format);
|
||||
if (!momentBegin.isValid()) {
|
||||
return;
|
||||
setDurationAsString(null);
|
||||
}
|
||||
|
||||
|
||||
if (endField.value === '' && momentDuration.asSeconds() > 0) {
|
||||
applyDateToField(endField, momentBegin, format);
|
||||
}
|
||||
@@ -143,12 +147,8 @@
|
||||
momentEnd = moment(endField.value, format);
|
||||
|
||||
var durationMoment = moment.duration(momentEnd.diff(momentBegin));
|
||||
var hours = Math.floor(durationMoment.asHours());
|
||||
if (hours < 10) {
|
||||
hours = '0' + hours;
|
||||
}
|
||||
|
||||
durationField.value = hours + ':' + ('0' + durationMoment.minutes()).slice(-2);
|
||||
|
||||
setDurationAsString(durationMoment);
|
||||
}
|
||||
|
||||
{#
|
||||
@@ -162,13 +162,12 @@
|
||||
function changedEnd(value)
|
||||
{
|
||||
var beginField = document.getElementById('{{ blockPrefix }}_begin');
|
||||
var durationField = document.getElementById('{{ blockPrefix }}_duration');
|
||||
var format = beginField.dataset.format;
|
||||
var momentDuration = moment.duration(durationField.value);
|
||||
var momentDuration = getParsedDuration();
|
||||
|
||||
var momentEnd = moment(value, format);
|
||||
if (!momentEnd.isValid()) {
|
||||
return;
|
||||
setDurationAsString(null);
|
||||
}
|
||||
|
||||
if (beginField.value === '') {
|
||||
@@ -188,12 +187,8 @@
|
||||
momentEnd = moment(value, format);
|
||||
|
||||
var durationMoment = moment.duration(momentEnd.diff(momentBegin));
|
||||
var hours = Math.floor(durationMoment.asHours());
|
||||
if (hours < 10) {
|
||||
hours = '0' + hours;
|
||||
}
|
||||
|
||||
durationField.value = hours + ':' + ('0' + durationMoment.minutes()).slice(-2);
|
||||
|
||||
setDurationAsString(durationMoment);
|
||||
}
|
||||
|
||||
{#
|
||||
@@ -204,9 +199,9 @@
|
||||
- if begin is not empty and end is empty and duration is > 0 (running records = 0): set end to begin plus duration
|
||||
#}
|
||||
|
||||
function changedDuration(value)
|
||||
function changedDuration()
|
||||
{
|
||||
var momentDuration = moment.duration(value);
|
||||
var momentDuration = getParsedDuration();
|
||||
if (!momentDuration.isValid()) {
|
||||
return;
|
||||
}
|
||||
@@ -227,6 +222,44 @@
|
||||
applyDateToField(endField, moment(beginField.value, format).add(duration, 'seconds'), format);
|
||||
}
|
||||
}
|
||||
|
||||
{# writes the value of a moment-duration object as human readable string into the duration field #}
|
||||
function setDurationAsString(durationMoment)
|
||||
{
|
||||
if (durationMoment === null) {
|
||||
getDurationField().value = '';
|
||||
}
|
||||
|
||||
if (!durationMoment.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var hours = Math.floor(durationMoment.asHours());
|
||||
if (hours < 10) {
|
||||
hours = '0' + hours;
|
||||
}
|
||||
|
||||
getDurationField().value = hours + ':' + ('0' + durationMoment.minutes()).slice(-2);
|
||||
}
|
||||
|
||||
{# returns a moment duration object from the duration input field #}
|
||||
function getParsedDuration()
|
||||
{
|
||||
var duration = getDurationField().value.toUpperCase();
|
||||
var momentDuration = moment.duration(NaN);
|
||||
|
||||
if (duration.indexOf(':') !== -1) {
|
||||
momentDuration = moment.duration(duration);
|
||||
} else if (duration.indexOf('.') !== -1 || duration.indexOf(',') !== -1) {
|
||||
duration = duration.replace(/,/, '.');
|
||||
duration = parseFloat(duration) * 3600;
|
||||
momentDuration = moment.duration('PT' + duration + 'S');
|
||||
} else if (duration.indexOf('H') !== -1 || duration.indexOf('M') !== -1 || duration.indexOf('S') !== -1) {
|
||||
momentDuration = moment.duration('PT' + duration);
|
||||
}
|
||||
|
||||
return momentDuration;
|
||||
}
|
||||
|
||||
function applyDateToField(field, momentObj, format)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user