mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-01-28 10:37:52 +08:00
Add DateTimeRange renderer
This commit is contained in:
parent
2a63854123
commit
5d4453470a
8 changed files with 184 additions and 28 deletions
|
@ -41,7 +41,67 @@ var DateTimeHelper = (function() {
|
||||||
return `${y}/${m}/${d} ${hours}:${mins}`;
|
return `${y}/${m}/${d} ${hours}:${mins}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function insertHiddenField($input, date, timeStr, format) {
|
function findSecondRangeInput($input) {
|
||||||
|
let $container = $input.parent().parent();
|
||||||
|
let $secondInput;
|
||||||
|
if ($input.parent().hasClass('start-time')) {
|
||||||
|
$secondInput = $container.find('.end-time input').first();
|
||||||
|
} else {
|
||||||
|
$secondInput = $container.find('.start-time input').first();
|
||||||
|
}
|
||||||
|
return $secondInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
function replaceForRangeHiddenField($container) {
|
||||||
|
let startTimeContainer = $container.find('.start-time')
|
||||||
|
let endTimeContainer = $container.find('.end-time')
|
||||||
|
let startTime = startTimeContainer.find('input[type=hidden]').val();
|
||||||
|
let endTime = endTimeContainer.find('input[type=hidden]').val();
|
||||||
|
let formId = startTimeContainer.find('input[type!=hidden]').data('form-id');
|
||||||
|
let columnId = startTimeContainer.find('input[type!=hidden]').data('column-id');
|
||||||
|
let json = {};
|
||||||
|
let hiddenField;
|
||||||
|
let value;
|
||||||
|
|
||||||
|
json.start_time = startTime;
|
||||||
|
json.end_time = endTime;
|
||||||
|
|
||||||
|
if (startTime && endTime) {
|
||||||
|
value = JSON.stringify(json);
|
||||||
|
} else {
|
||||||
|
value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
hiddenField = `
|
||||||
|
<input type="hidden"
|
||||||
|
form="${formId}"
|
||||||
|
name="repository_cells[${columnId}]"
|
||||||
|
value='${value}' />`;
|
||||||
|
|
||||||
|
$container.find('.cell-range-container').html(hiddenField);
|
||||||
|
startTimeContainer.find('.cell-timestamp-container').html('');
|
||||||
|
endTimeContainer.find('.cell-timestamp-container').html('');
|
||||||
|
}
|
||||||
|
|
||||||
|
function insertHiddenField($input) {
|
||||||
|
let fieldType = $input.data('datetime-part')
|
||||||
|
let $container = $input.parent().find('.cell-timestamp-container');
|
||||||
|
let dateStr = $container.data('current-date');
|
||||||
|
let columnType = $container.data('datetime-type');
|
||||||
|
let timeStr;
|
||||||
|
|
||||||
|
if (fieldType === 'time') {
|
||||||
|
timeStr = $input.val();
|
||||||
|
} else if (fieldType === 'date') {
|
||||||
|
timeStr = $input.parent().find('input[data-mask-type=time]').val();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (columnType === 'time' && !isValidDate(dateStr)) {
|
||||||
|
// new time without value for date
|
||||||
|
dateStr = stringDateTimeFormat(new Date(), 'dateonly');
|
||||||
|
}
|
||||||
|
let date = new Date(dateStr);
|
||||||
|
|
||||||
let formId = $input.data('form-id');
|
let formId = $input.data('form-id');
|
||||||
let columnId = $input.data('column-id');
|
let columnId = $input.data('column-id');
|
||||||
let hiddenFieldContainer = $input.parent().find('.cell-timestamp-container');
|
let hiddenFieldContainer = $input.parent().find('.cell-timestamp-container');
|
||||||
|
@ -52,9 +112,9 @@ var DateTimeHelper = (function() {
|
||||||
|
|
||||||
if (!hasDate) { // Date needs to be presence
|
if (!hasDate) { // Date needs to be presence
|
||||||
value = '';
|
value = '';
|
||||||
} else if (format === 'time' && !hasTime) { // Delete time value
|
} else if (columnType === 'time' && !hasTime) { // Delete time value
|
||||||
value = '';
|
value = '';
|
||||||
} else if (format === 'datetime' && !hasTime) { // Delete date time value
|
} else if (columnType === 'datetime' && !hasTime) { // Delete date time value
|
||||||
value = '';
|
value = '';
|
||||||
} else {
|
} else {
|
||||||
// create date time format
|
// create date time format
|
||||||
|
@ -72,29 +132,36 @@ var DateTimeHelper = (function() {
|
||||||
|
|
||||||
function initChangeEvents($cell) {
|
function initChangeEvents($cell) {
|
||||||
$cell.find('input[data-mask-type=time]').on('change', function() {
|
$cell.find('input[data-mask-type=time]').on('change', function() {
|
||||||
let timeStr = $(this).val();
|
let $input = $(this);
|
||||||
let $container = $(this).parent().find('.cell-timestamp-container');
|
insertHiddenField($input);
|
||||||
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);
|
if ($input.parent('.range-type').length) {
|
||||||
|
let $secondInput = findSecondRangeInput($input);
|
||||||
|
|
||||||
|
insertHiddenField($secondInput);
|
||||||
|
replaceForRangeHiddenField($input.parent().parent());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$cell.find('.calendar-input').on('dp.change', function(e) {
|
$cell.find('.calendar-input').on('dp.change', function(e) {
|
||||||
|
let $input = $(this)
|
||||||
let date = e.date._d;
|
let date = e.date._d;
|
||||||
let timeStr = $(this).parent().find('input[data-mask-type=time]').val();
|
let $container = $input.parent().find('.cell-timestamp-container');
|
||||||
let $container = $(this).parent().find('.cell-timestamp-container');
|
|
||||||
|
|
||||||
if (date !== undefined) {
|
if (date !== undefined) {
|
||||||
$container.data('current-date', stringDateTimeFormat(date, 'dateonly'));
|
$container.data('current-date', stringDateTimeFormat(date, 'dateonly'));
|
||||||
} else {
|
} else {
|
||||||
$container.data('current-date', '');
|
$container.data('current-date', '');
|
||||||
}
|
}
|
||||||
insertHiddenField($(this), date, timeStr, $container.data('datetime-type'));
|
|
||||||
|
insertHiddenField($input);
|
||||||
|
|
||||||
|
if ($input.parent('.range-type').length) {
|
||||||
|
let $secondInput = findSecondRangeInput($input);
|
||||||
|
|
||||||
|
insertHiddenField($secondInput);
|
||||||
|
replaceForRangeHiddenField($input.parent().parent());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +169,7 @@ var DateTimeHelper = (function() {
|
||||||
return `
|
return `
|
||||||
<input class="form-control editing calendar-input"
|
<input class="form-control editing calendar-input"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
|
data-datetime-part="date"
|
||||||
data-form-id="${formId}"
|
data-form-id="${formId}"
|
||||||
data-column-id="${columnId}"
|
data-column-id="${columnId}"
|
||||||
value='${value}'/>
|
value='${value}'/>
|
||||||
|
@ -111,7 +179,8 @@ var DateTimeHelper = (function() {
|
||||||
function timeInputField(formId, columnId, value) {
|
function timeInputField(formId, columnId, value) {
|
||||||
return `
|
return `
|
||||||
<input class="form-control editing"
|
<input class="form-control editing"
|
||||||
type="text"
|
type="text"
|
||||||
|
data-datetime-part="time"
|
||||||
data-mask-type="time"
|
data-mask-type="time"
|
||||||
data-form-id="${formId}"
|
data-form-id="${formId}"
|
||||||
data-column-id="${columnId}"
|
data-column-id="${columnId}"
|
||||||
|
@ -178,9 +247,50 @@ var DateTimeHelper = (function() {
|
||||||
initChangeEvents($cell);
|
initChangeEvents($cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initDateTimeRangeEditMode(formId, columnId, $cell, startDate, startTime, startDatetime, endDate, endTime, endDatetime) {
|
||||||
|
let inputFields = `
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="cell-range-container"></div>
|
||||||
|
<div class="start-time range-type">
|
||||||
|
<div class="cell-timestamp-container" data-current-date="${startDatetime}" data-datetime-type="datetime"></div>
|
||||||
|
${dateInputField(formId, columnId, startDate)}
|
||||||
|
${timeInputField(formId, columnId, startTime)}
|
||||||
|
</div>
|
||||||
|
<div class="end-time range-type">
|
||||||
|
<div class="cell-timestamp-container" data-current-date="${endDatetime}" data-datetime-type="datetime"></div>
|
||||||
|
${dateInputField(formId, columnId, endDate)}
|
||||||
|
${timeInputField(formId, columnId, endTime)}
|
||||||
|
</div>
|
||||||
|
</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"]'));
|
||||||
|
|
||||||
|
let $cal1 = $cell.find('.calendar-input').first().datetimepicker({ ignoreReadonly: true, locale: 'en', format: formatJS });
|
||||||
|
let $cal2 = $cell.find('.calendar-input').last().datetimepicker({ ignoreReadonly: true, locale: 'en', format: formatJS });
|
||||||
|
|
||||||
|
$cal1.on('dp.change', function(e) {
|
||||||
|
$cal2.data('DateTimePicker').minDate(e.date);
|
||||||
|
});
|
||||||
|
$cal2.on('dp.change', function(e) {
|
||||||
|
$cal1.data('DateTimePicker').maxDate(e.date);
|
||||||
|
});
|
||||||
|
|
||||||
|
initChangeEvents($cell);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
initDateEditMode: initDateEditMode,
|
initDateEditMode: initDateEditMode,
|
||||||
initTimeEditMode: initTimeEditMode,
|
initTimeEditMode: initTimeEditMode,
|
||||||
initDateTimeEditMode: initDateTimeEditMode,
|
initDateTimeEditMode: initDateTimeEditMode,
|
||||||
|
initDateTimeRangeEditMode: initDateTimeRangeEditMode
|
||||||
};
|
};
|
||||||
}());
|
}());
|
||||||
|
|
|
@ -117,7 +117,17 @@ $.fn.dataTable.render.editRepositoryTimeValue = function(formId, columnId, cell)
|
||||||
};
|
};
|
||||||
|
|
||||||
$.fn.dataTable.render.editRepositoryDateTimeRangeValue = function(formId, columnId, cell) {
|
$.fn.dataTable.render.editRepositoryDateTimeRangeValue = function(formId, columnId, cell) {
|
||||||
return '';
|
let $cell = $(cell.node());
|
||||||
|
let $startSpan = $cell.find('span').first();
|
||||||
|
let startDate = $startSpan.data('date');
|
||||||
|
let startTime = $startSpan.data('time');
|
||||||
|
let startDatetime = $startSpan.data('datetime');
|
||||||
|
let $endSpan = $cell.find('span').last();
|
||||||
|
let endDate = $endSpan.data('date');
|
||||||
|
let endTime = $endSpan.data('time');
|
||||||
|
let endDatetime = $endSpan.data('datetime');
|
||||||
|
|
||||||
|
DateTimeHelper.initDateTimeRangeEditMode(formId, columnId, $cell, startDate, startTime, startDatetime, endDate, endTime, endDatetime);
|
||||||
};
|
};
|
||||||
|
|
||||||
$.fn.dataTable.render.editRepositoryDateRangeValue = function(formId, columnId, cell) {
|
$.fn.dataTable.render.editRepositoryDateRangeValue = function(formId, columnId, cell) {
|
||||||
|
|
|
@ -98,6 +98,20 @@ $.fn.dataTable.render.newRepositoryDateValue = function(formId, columnId, $cell)
|
||||||
DateTimeHelper.initDateEditMode(formId, columnId, $cell, '', '');
|
DateTimeHelper.initDateEditMode(formId, columnId, $cell, '', '');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$.fn.dataTable.render.newRepositoryDateTimeRangeValue = function(formId, columnId, $cell) {
|
||||||
|
// let $cell = $(cell.node());
|
||||||
|
// let $startSpan = $cell.find('span').first();
|
||||||
|
// let startDate = $startSpan.data('date');
|
||||||
|
// let startTime = $startSpan.data('time');
|
||||||
|
// let startDatetime = $startSpan.data('datetime');
|
||||||
|
// let $endSpan = $cell.find('span').last();
|
||||||
|
// let endDate = $endSpan.data('date');
|
||||||
|
// let endTime = $endSpan.data('time');
|
||||||
|
// let endDatetime = $endSpan.data('datetime');
|
||||||
|
|
||||||
|
DateTimeHelper.initDateTimeRangeEditMode(formId, columnId, $cell, '', '', '', '', '', '');
|
||||||
|
};
|
||||||
|
|
||||||
$.fn.dataTable.render.newRepositoryCheckboxValue = function(formId, columnId) {
|
$.fn.dataTable.render.newRepositoryCheckboxValue = function(formId, columnId) {
|
||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
|
|
|
@ -90,7 +90,12 @@ $.fn.dataTable.render.defaultRepositoryDateTimeRangeValue = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
$.fn.dataTable.render.RepositoryDateTimeRangeValue = function(data) {
|
$.fn.dataTable.render.RepositoryDateTimeRangeValue = function(data) {
|
||||||
return data.value;
|
return `<span data-time="${data.value.start_time.time_formatted}"
|
||||||
|
data-datetime="${data.value.start_time.datetime}"
|
||||||
|
data-date="${data.value.start_time.date_formatted}">${data.value.start_time.formatted}</span> -
|
||||||
|
<span data-time="${data.value.end_time.time_formatted}"
|
||||||
|
data-datetime="${data.value.end_time.datetime}"
|
||||||
|
data-date="${data.value.end_time.date_formatted}">${data.value.end_time.formatted}</span>`;
|
||||||
};
|
};
|
||||||
|
|
||||||
$.fn.dataTable.render.defaultRepositoryDateRangeValue = function() {
|
$.fn.dataTable.render.defaultRepositoryDateRangeValue = function() {
|
||||||
|
|
|
@ -70,21 +70,21 @@ class RepositoryCell < ApplicationRecord
|
||||||
belongs_to :repository_date_time_range_value,
|
belongs_to :repository_date_time_range_value,
|
||||||
(lambda do
|
(lambda do
|
||||||
includes(:repository_cell)
|
includes(:repository_cell)
|
||||||
.where(repository_cells: { value_type: 'RepositoryDateTimeRangeValue' })
|
.where(repository_cells: { value_type: 'RepositoryDateTimeRangeValueBase' })
|
||||||
end),
|
end),
|
||||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||||
|
|
||||||
belongs_to :repository_date_range_value,
|
belongs_to :repository_date_range_value,
|
||||||
(lambda do
|
(lambda do
|
||||||
includes(:repository_cell)
|
includes(:repository_cell)
|
||||||
.where(repository_cells: { value_type: 'RepositoryDateRangeValue' })
|
.where(repository_cells: { value_type: 'RepositoryDateTimeRangeValueBase' })
|
||||||
end),
|
end),
|
||||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||||
|
|
||||||
belongs_to :repository_time_range_value,
|
belongs_to :repository_time_range_value,
|
||||||
(lambda do
|
(lambda do
|
||||||
includes(:repository_cell)
|
includes(:repository_cell)
|
||||||
.where(repository_cells: { value_type: 'RepositoryTimeRangeValue' })
|
.where(repository_cells: { value_type: 'RepositoryDateTimeRangeValueBase' })
|
||||||
end),
|
end),
|
||||||
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
|
|
||||||
class RepositoryDateTimeRangeValue < RepositoryDateTimeRangeValueBase
|
class RepositoryDateTimeRangeValue < RepositoryDateTimeRangeValueBase
|
||||||
def data_changed?(new_data)
|
def data_changed?(new_data)
|
||||||
st = Time.zone.parse(new_data[:start_time])
|
data = JSON.parse(new_data).symbolize_keys
|
||||||
et = Time.zone.parse(new_data[:end_time])
|
st = Time.zone.parse(data[:start_time])
|
||||||
|
et = Time.zone.parse(data[:end_time])
|
||||||
st.to_i != start_time.to_i || et.to_i != end_time.to_i
|
st.to_i != start_time.to_i || et.to_i != end_time.to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -12,9 +13,11 @@ class RepositoryDateTimeRangeValue < RepositoryDateTimeRangeValueBase
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.new_with_payload(payload, attributes)
|
def self.new_with_payload(payload, attributes)
|
||||||
|
data = JSON.parse(payload).symbolize_keys
|
||||||
|
|
||||||
value = new(attributes)
|
value = new(attributes)
|
||||||
value.start_time = Time.zone.parse(payload[:start_time])
|
value.start_time = Time.zone.parse(data[:start_time])
|
||||||
value.end_time = Time.zone.parse(payload[:end_time])
|
value.end_time = Time.zone.parse(data[:end_time])
|
||||||
value
|
value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,8 +16,9 @@ class RepositoryDateTimeRangeValueBase < ApplicationRecord
|
||||||
SORTABLE_VALUE_INCLUDE = :repository_date_time_range_value
|
SORTABLE_VALUE_INCLUDE = :repository_date_time_range_value
|
||||||
|
|
||||||
def update_data!(new_data, user)
|
def update_data!(new_data, user)
|
||||||
self.start_time = Time.zone.parse(new_data[:start_time])
|
data = JSON.parse(new_data).symbolize_keys
|
||||||
self.end_time = Time.zone.parse(new_data[:end_time])
|
self.start_time = Time.zone.parse(data[:start_time])
|
||||||
|
self.end_time = Time.zone.parse(data[:end_time])
|
||||||
self.last_modified_by = user
|
self.last_modified_by = user
|
||||||
save!
|
save!
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,20 @@
|
||||||
module RepositoryDatatable
|
module RepositoryDatatable
|
||||||
class RepositoryDateTimeRangeValueSerializer < RepositoryBaseValueSerializer
|
class RepositoryDateTimeRangeValueSerializer < RepositoryBaseValueSerializer
|
||||||
def value
|
def value
|
||||||
I18n.l(object.start_time, format: :full_with_comma) + ' - ' + I18n.l(object.end_time, format: :full_with_comma)
|
{
|
||||||
|
start_time: {
|
||||||
|
formatted: I18n.l(object.start_time, format: :full_with_comma),
|
||||||
|
date_formatted: I18n.l(object.start_time, format: :full_date),
|
||||||
|
time_formatted: I18n.l(object.start_time, format: :time),
|
||||||
|
datetime: object.start_time.strftime('%Y/%m/%d %H:%M')
|
||||||
|
},
|
||||||
|
end_time: {
|
||||||
|
formatted: I18n.l(object.end_time, format: :full_with_comma),
|
||||||
|
date_formatted: I18n.l(object.end_time, format: :full_date),
|
||||||
|
time_formatted: I18n.l(object.end_time, format: :time),
|
||||||
|
datetime: object.end_time.strftime('%Y/%m/%d %H:%M')
|
||||||
|
}
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue