mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-04 04:04:36 +08:00
Edit and new renderers for DateTime columns
This commit is contained in:
parent
7c71159303
commit
2a63854123
10 changed files with 265 additions and 15 deletions
|
@ -0,0 +1,186 @@
|
|||
/* global Inputmask formatJS */
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
var DateTimeHelper = (function() {
|
||||
|
||||
function isValidTimeStr(timeStr) {
|
||||
return /^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$/.test(timeStr);
|
||||
}
|
||||
|
||||
function isValidDate(date) {
|
||||
return (Object.prototype.toString.call(date) === '[object Date]') && !isNaN(date.getTime());
|
||||
}
|
||||
|
||||
function addLeadingZero(value) {
|
||||
return ('0' + value).slice(-2);
|
||||
}
|
||||
|
||||
function recalcTimestamp(date, timeStr) {
|
||||
if (!isValidTimeStr(timeStr)) {
|
||||
date.setHours(0);
|
||||
date.setMinutes(0);
|
||||
return date;
|
||||
}
|
||||
let hours = timeStr.split(':')[0];
|
||||
let mins = timeStr.split(':')[1];
|
||||
date.setHours(hours);
|
||||
date.setMinutes(mins);
|
||||
return date;
|
||||
}
|
||||
|
||||
function stringDateTimeFormat(date, format) {
|
||||
let y = date.getFullYear();
|
||||
let m = addLeadingZero(date.getMonth() + 1);
|
||||
let d = addLeadingZero(date.getDate());
|
||||
let hours = addLeadingZero(date.getHours());
|
||||
let mins = addLeadingZero(date.getMinutes());
|
||||
|
||||
if (format === 'dateonly') {
|
||||
return `${y}/${m}/${d}`;
|
||||
}
|
||||
return `${y}/${m}/${d} ${hours}:${mins}`;
|
||||
}
|
||||
|
||||
function insertHiddenField($input, date, timeStr, format) {
|
||||
let formId = $input.data('form-id');
|
||||
let columnId = $input.data('column-id');
|
||||
let hiddenFieldContainer = $input.parent().find('.cell-timestamp-container');
|
||||
let hasTime = isValidTimeStr(timeStr);
|
||||
let hasDate = isValidDate(date);
|
||||
let value;
|
||||
let hiddenField;
|
||||
|
||||
if (!hasDate) { // Date needs to be presence
|
||||
value = '';
|
||||
} else if (format === 'time' && !hasTime) { // Delete time value
|
||||
value = '';
|
||||
} else if (format === 'datetime' && !hasTime) { // Delete date time value
|
||||
value = '';
|
||||
} else {
|
||||
// create date time format
|
||||
value = stringDateTimeFormat(recalcTimestamp(date, timeStr), 'full');
|
||||
}
|
||||
|
||||
hiddenField = `
|
||||
<input type="hidden"
|
||||
form="${formId}"
|
||||
name="repository_cells[${columnId}]"
|
||||
value="${value}" />`;
|
||||
|
||||
hiddenFieldContainer.html(hiddenField);
|
||||
}
|
||||
|
||||
function initChangeEvents($cell) {
|
||||
$cell.find('input[data-mask-type=time]').on('change', function() {
|
||||
let timeStr = $(this).val();
|
||||
let $container = $(this).parent().find('.cell-timestamp-container');
|
||||
let dateStr = $container.data('current-date');
|
||||
let columnType = $container.data('datetime-type');
|
||||
if (columnType === 'time' && !isValidDate(dateStr)) {
|
||||
// new time without value for date
|
||||
dateStr = stringDateTimeFormat(new Date(), 'dateonly');
|
||||
}
|
||||
|
||||
insertHiddenField($(this), new Date(dateStr), timeStr, columnType);
|
||||
});
|
||||
|
||||
$cell.find('.calendar-input').on('dp.change', function(e) {
|
||||
let date = e.date._d;
|
||||
let timeStr = $(this).parent().find('input[data-mask-type=time]').val();
|
||||
let $container = $(this).parent().find('.cell-timestamp-container');
|
||||
|
||||
if (date !== undefined) {
|
||||
$container.data('current-date', stringDateTimeFormat(date, 'dateonly'));
|
||||
} else {
|
||||
$container.data('current-date', '');
|
||||
}
|
||||
insertHiddenField($(this), date, timeStr, $container.data('datetime-type'));
|
||||
});
|
||||
}
|
||||
|
||||
function dateInputField(formId, columnId, value) {
|
||||
return `
|
||||
<input class="form-control editing calendar-input"
|
||||
type="datetime"
|
||||
data-form-id="${formId}"
|
||||
data-column-id="${columnId}"
|
||||
value='${value}'/>
|
||||
`;
|
||||
}
|
||||
|
||||
function timeInputField(formId, columnId, value) {
|
||||
return `
|
||||
<input class="form-control editing"
|
||||
type="text"
|
||||
data-mask-type="time"
|
||||
data-form-id="${formId}"
|
||||
data-column-id="${columnId}"
|
||||
value='${value}'
|
||||
placeholder="HH:mm"/>
|
||||
`;
|
||||
}
|
||||
|
||||
function initDateEditMode(formId, columnId, $cell, date, datetime) {
|
||||
let inputFields = `
|
||||
<div class="form-group">
|
||||
<div class="cell-timestamp-container" data-current-date="${datetime}" data-datetime-type="date"></div>
|
||||
${dateInputField(formId, columnId, date)}
|
||||
</div>
|
||||
`;
|
||||
|
||||
$cell.html(inputFields);
|
||||
|
||||
$cell.find('.calendar-input').datetimepicker({ ignoreReadonly: true, locale: 'en', format: formatJS });
|
||||
initChangeEvents($cell);
|
||||
}
|
||||
|
||||
function initTimeEditMode(formId, columnId, $cell, time, datetime) {
|
||||
let inputFields = `
|
||||
<div class="form-group">
|
||||
<div class="cell-timestamp-container" data-current-date="${datetime}" data-datetime-type="time"></div>
|
||||
${timeInputField(formId, columnId, time)}
|
||||
</div>
|
||||
`;
|
||||
|
||||
$cell.html(inputFields);
|
||||
|
||||
Inputmask('datetime', {
|
||||
inputFormat: 'HH:MM',
|
||||
placeholder: 'HH:mm',
|
||||
clearIncomplete: true,
|
||||
showMaskOnHover: true,
|
||||
hourFormat: 24
|
||||
}).mask($cell.find('input[data-mask-type="time"]'));
|
||||
|
||||
initChangeEvents($cell);
|
||||
}
|
||||
|
||||
function initDateTimeEditMode(formId, columnId, $cell, date, time, datetime) {
|
||||
let inputFields = `
|
||||
<div class="form-group">
|
||||
<div class="cell-timestamp-container" data-current-date="${datetime}" data-datetime-type="datetime"></div>
|
||||
${dateInputField(formId, columnId, date)}
|
||||
${timeInputField(formId, columnId, time)}
|
||||
</div>
|
||||
`;
|
||||
|
||||
$cell.html(inputFields);
|
||||
|
||||
Inputmask('datetime', {
|
||||
inputFormat: 'HH:MM',
|
||||
placeholder: 'HH:mm',
|
||||
clearIncomplete: true,
|
||||
showMaskOnHover: true,
|
||||
hourFormat: 24
|
||||
}).mask($cell.find('input[data-mask-type="time"]'));
|
||||
|
||||
$cell.find('.calendar-input').datetimepicker({ ignoreReadonly: true, locale: 'en', format: formatJS });
|
||||
initChangeEvents($cell);
|
||||
}
|
||||
|
||||
return {
|
||||
initDateEditMode: initDateEditMode,
|
||||
initTimeEditMode: initTimeEditMode,
|
||||
initDateTimeEditMode: initDateTimeEditMode,
|
||||
};
|
||||
}());
|
|
@ -1,4 +1,4 @@
|
|||
/* global ListColumnHelper ChecklistColumnHelper Status SmartAnnotation I18n GLOBAL_CONSTANTS */
|
||||
/* global ListColumnHelper ChecklistColumnHelper Status SmartAnnotation I18n GLOBAL_CONSTANTS DateTimeHelper*/
|
||||
|
||||
$.fn.dataTable.render.editRowName = function(formId, cell) {
|
||||
let $cell = $(cell.node());
|
||||
|
@ -89,15 +89,31 @@ $.fn.dataTable.render.editRepositoryStatusValue = function(formId, columnId, cel
|
|||
};
|
||||
|
||||
$.fn.dataTable.render.editRepositoryDateTimeValue = function(formId, columnId, cell) {
|
||||
return '';
|
||||
let $cell = $(cell.node());
|
||||
let $span = $cell.find('span').first();
|
||||
let date = $span.data('date');
|
||||
let time = $span.data('time');
|
||||
let datetime = $span.data('datetime');
|
||||
|
||||
DateTimeHelper.initDateTimeEditMode(formId, columnId, $cell, date, time, datetime);
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.editRepositoryDateValue = function(formId, columnId, cell) {
|
||||
return '';
|
||||
let $cell = $(cell.node());
|
||||
let $span = $cell.find('span').first();
|
||||
let date = $span.data('date');
|
||||
let datetime = $span.data('datetime');
|
||||
|
||||
DateTimeHelper.initDateEditMode(formId, columnId, $cell, date, datetime);
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.editRepositoryTimeValue = function(formId, columnId, cell) {
|
||||
return '';
|
||||
let $cell = $(cell.node());
|
||||
let $span = $cell.find('span').first();
|
||||
let time = $span.data('time');
|
||||
let datetime = $span.data('datetime');
|
||||
|
||||
DateTimeHelper.initTimeEditMode(formId, columnId, $cell, time, datetime);
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.editRepositoryDateTimeRangeValue = function(formId, columnId, cell) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* global ListColumnHelper ChecklistColumnHelper Status SmartAnnotation I18n GLOBAL_CONSTANTS */
|
||||
/* global ListColumnHelper ChecklistColumnHelper Status SmartAnnotation I18n GLOBAL_CONSTANTS DateTimeHelper formatJS */
|
||||
|
||||
$.fn.dataTable.render.newRowName = function(formId, $cell) {
|
||||
$cell.html(`
|
||||
|
@ -85,3 +85,19 @@ $.fn.dataTable.render.newRepositoryNumberValue = function(formId, columnId, $cel
|
|||
|
||||
SmartAnnotation.init($cell.find('input'));
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.newRepositoryDateTimeValue = function(formId, columnId, $cell) {
|
||||
DateTimeHelper.initDateTimeEditMode(formId, columnId, $cell, '', '', '');
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.newRepositoryTimeValue = function(formId, columnId, $cell) {
|
||||
DateTimeHelper.initTimeEditMode(formId, columnId, $cell, '', '');
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.newRepositoryDateValue = function(formId, columnId, $cell) {
|
||||
DateTimeHelper.initDateEditMode(formId, columnId, $cell, '', '');
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.newRepositoryCheckboxValue = function(formId, columnId) {
|
||||
return '';
|
||||
};
|
||||
|
|
|
@ -55,7 +55,7 @@ $.fn.dataTable.render.defaultRepositoryDateValue = function() {
|
|||
};
|
||||
|
||||
$.fn.dataTable.render.RepositoryDateValue = function(data) {
|
||||
return data.value;
|
||||
return `<span data-datetime="${data.value.datetime}" data-date="${data.value.formatted}">${data.value.formatted}</span>`;
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.defaultRepositoryDateTimeValue = function() {
|
||||
|
@ -63,7 +63,9 @@ $.fn.dataTable.render.defaultRepositoryDateTimeValue = function() {
|
|||
};
|
||||
|
||||
$.fn.dataTable.render.RepositoryDateTimeValue = function(data) {
|
||||
return data.value;
|
||||
return `<span data-time="${data.value.time_formatted}"
|
||||
data-datetime="${data.value.datetime}"
|
||||
data-date="${data.value.date_formatted}">${data.value.formatted}</span>`;
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.defaultRepositoryTimeValue = function() {
|
||||
|
@ -71,7 +73,8 @@ $.fn.dataTable.render.defaultRepositoryTimeValue = function() {
|
|||
};
|
||||
|
||||
$.fn.dataTable.render.RepositoryTimeValue = function(data) {
|
||||
return data.value;
|
||||
return `<span data-time="${data.value.formatted}"
|
||||
data-datetime="${data.value.datetime}">${data.value.formatted}</span>`;
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.defaultRepositoryTimeRangeValue = function() {
|
||||
|
@ -79,7 +82,7 @@ $.fn.dataTable.render.defaultRepositoryTimeRangeValue = function() {
|
|||
};
|
||||
|
||||
$.fn.dataTable.render.RepositoryTimeRangeValue = function(data) {
|
||||
return data.value;
|
||||
return `<span data-datetime="${data.value.datetime}">${data.value.formatted}</span>`;
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.defaultRepositoryDateTimeRangeValue = function() {
|
||||
|
|
|
@ -37,3 +37,7 @@ $.fn.dataTable.render.RepositoryChecklistValueValidator = function() {
|
|||
$.fn.dataTable.render.RepositoryNumberValueValidator = function() {
|
||||
return true;
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.RepositoryDateTimeValueValidator = function() {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ class RepositoryCell < ApplicationRecord
|
|||
belongs_to :repository_date_value,
|
||||
(lambda do
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryDateValue' })
|
||||
.where(repository_cells: { value_type: 'RepositoryDateTimeValueBase' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
belongs_to :repository_list_value,
|
||||
|
@ -56,14 +56,14 @@ class RepositoryCell < ApplicationRecord
|
|||
belongs_to :repository_date_time_value,
|
||||
(lambda do
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryDateTimeValue' })
|
||||
.where(repository_cells: { value_type: 'RepositoryDateTimeValueBase' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
|
||||
belongs_to :repository_time_value,
|
||||
(lambda do
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryTimeValue' })
|
||||
.where(repository_cells: { value_type: 'RepositoryDateTimeValueBase' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||
|
||||
|
|
|
@ -3,7 +3,12 @@
|
|||
module RepositoryDatatable
|
||||
class RepositoryDateTimeValueSerializer < RepositoryBaseValueSerializer
|
||||
def value
|
||||
I18n.l(object.data, format: :full_with_comma)
|
||||
{
|
||||
formatted: I18n.l(object.data, format: :full_with_comma),
|
||||
date_formatted: I18n.l(object.data, format: :full_date),
|
||||
time_formatted: I18n.l(object.data, format: :time),
|
||||
datetime: object.data.strftime('%Y/%m/%d %H:%M')
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
module RepositoryDatatable
|
||||
class RepositoryDateValueSerializer < RepositoryBaseValueSerializer
|
||||
def value
|
||||
I18n.l(object.data, format: :full_date)
|
||||
{
|
||||
formatted: I18n.l(object.data, format: :full_date),
|
||||
datetime: object.data.strftime('%Y/%m/%d %H:%M')
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
module RepositoryDatatable
|
||||
class RepositoryTimeValueSerializer < RepositoryBaseValueSerializer
|
||||
def value
|
||||
I18n.l(object.data, format: :time)
|
||||
{
|
||||
formatted: I18n.l(object.data, format: :time),
|
||||
datetime: object.data.strftime('%Y/%m/%d %H:%M')
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -170,3 +170,17 @@
|
|||
<%= javascript_include_tag "repositories/show" %>
|
||||
<%= javascript_include_tag "repositories/index" %>
|
||||
<%= javascript_pack_tag 'custom/inputmask' %>
|
||||
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
<%
|
||||
js_format = I18n.backend.date_format.dup
|
||||
js_format.gsub!(/%-d/, 'D')
|
||||
js_format.gsub!(/%d/, 'DD')
|
||||
js_format.gsub!(/%-m/, 'M')
|
||||
js_format.gsub!(/%m/, 'MM')
|
||||
js_format.gsub!(/%b/, 'MMM')
|
||||
js_format.gsub!(/%B/, 'MMMM')
|
||||
js_format.gsub!('%Y', 'YYYY')
|
||||
%>
|
||||
const formatJS = "<%= js_format %>"
|
||||
</script>
|
||||
|
|
Loading…
Add table
Reference in a new issue