|
|
@@ -835,6 +835,60 @@ export default class GridRow { |
|
|
|
: ""; |
|
|
|
add_class += ["Check"].indexOf(df.fieldtype) !== -1 ? " text-center" : ""; |
|
|
|
|
|
|
|
let grid; |
|
|
|
let grid_container; |
|
|
|
|
|
|
|
let inital_position_x = 0; |
|
|
|
let start_x = 0; |
|
|
|
let start_y = 0; |
|
|
|
|
|
|
|
let input_in_focus = false; |
|
|
|
|
|
|
|
let vertical = false; |
|
|
|
let horizontal = false; |
|
|
|
|
|
|
|
// prevent random layout shifts caused by widgets and on click position elements inside view (UX). |
|
|
|
function on_input_focus(el) { |
|
|
|
input_in_focus = true; |
|
|
|
|
|
|
|
let container_width = grid_container.getBoundingClientRect().width; |
|
|
|
let container_left = grid_container.getBoundingClientRect().left; |
|
|
|
let grid_left = parseFloat(grid.style.left); |
|
|
|
let element_left = el.offset().left; |
|
|
|
let fieldtype = el.data("fieldtype"); |
|
|
|
|
|
|
|
let offset_right = container_width - (element_left + el.width()); |
|
|
|
let offset_left = 0; |
|
|
|
let element_screen_x = element_left - container_left; |
|
|
|
let element_position_x = container_width - (element_left - container_left); |
|
|
|
|
|
|
|
if (["Date", "Time", "Datetime"].includes(fieldtype)) { |
|
|
|
offset_left = element_position_x - 220; |
|
|
|
} |
|
|
|
if (["Link", "Dynamic Link"].includes(fieldtype)) { |
|
|
|
offset_left = element_position_x - 250; |
|
|
|
} |
|
|
|
if (element_screen_x < 0) { |
|
|
|
grid.style.left = `${grid_left - element_screen_x}px`; |
|
|
|
} else if (offset_left < 0) { |
|
|
|
grid.style.left = `${grid_left + offset_left}px`; |
|
|
|
} else if (offset_right < 0) { |
|
|
|
grid.style.left = `${grid_left + offset_right}px`; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Delay date_picker widget to prevent temparary layout shift (UX). |
|
|
|
function handle_date_picker() { |
|
|
|
let date_time_picker = document.querySelectorAll(".datepicker.active")[0]; |
|
|
|
|
|
|
|
date_time_picker.classList.remove("active"); |
|
|
|
date_time_picker.style.width = "220px"; |
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
|
date_time_picker.classList.add("active"); |
|
|
|
}, 600); |
|
|
|
} |
|
|
|
|
|
|
|
var $col = $( |
|
|
|
'<div class="col grid-static-col col-xs-' + colsize + " " + add_class + '"></div>' |
|
|
|
) |
|
|
@@ -842,15 +896,68 @@ export default class GridRow { |
|
|
|
.attr("data-fieldtype", df.fieldtype) |
|
|
|
.data("df", df) |
|
|
|
.appendTo(this.row) |
|
|
|
// initialize grid for horizontal scroll on mobile devices. |
|
|
|
.on("touchstart", function (event) { |
|
|
|
grid_container = $(event.currentTarget).closest(".form-grid-container")[0]; |
|
|
|
grid = $(event.currentTarget).closest(".form-grid")[0]; |
|
|
|
|
|
|
|
grid.style.position != "relative" && $(grid).css("position", "relative"); |
|
|
|
!grid.style.left && $(grid).css("left", 0); |
|
|
|
|
|
|
|
start_x = event.touches[0].clientX; |
|
|
|
start_y = event.touches[0].clientY; |
|
|
|
|
|
|
|
inital_position_x = -parseFloat(grid.style.left || 0) + start_x; |
|
|
|
}) |
|
|
|
// calculate X and Y movement based on touch events. |
|
|
|
.on("touchmove", function (event) { |
|
|
|
if (input_in_focus) return; |
|
|
|
|
|
|
|
let moved_x; |
|
|
|
let moved_y; |
|
|
|
|
|
|
|
if (!horizontal && !vertical) { |
|
|
|
moved_x = Math.abs(start_x - event.touches[0].clientX); |
|
|
|
moved_y = Math.abs(start_y - event.touches[0].clientY); |
|
|
|
} |
|
|
|
|
|
|
|
if (!vertical && moved_x > 16) { |
|
|
|
horizontal = true; |
|
|
|
} else if (!horizontal && moved_y > 16) { |
|
|
|
vertical = true; |
|
|
|
} |
|
|
|
if (horizontal) { |
|
|
|
event.preventDefault(); |
|
|
|
|
|
|
|
let grid_start = inital_position_x - event.touches[0].clientX; |
|
|
|
let grid_end = grid.clientWidth - grid_container.clientWidth + 2; |
|
|
|
|
|
|
|
if (grid_start < 0) { |
|
|
|
grid_start = 0; |
|
|
|
} else if (grid_start > grid_end) { |
|
|
|
grid_start = grid_end; |
|
|
|
} |
|
|
|
grid.style.left = `-${grid_start}px`; |
|
|
|
} |
|
|
|
}) |
|
|
|
.on("touchend", function () { |
|
|
|
vertical = false; |
|
|
|
horizontal = false; |
|
|
|
}) |
|
|
|
.on("click", function () { |
|
|
|
if (frappe.ui.form.editable_row === me) { |
|
|
|
return; |
|
|
|
if (frappe.ui.form.editable_row !== me) { |
|
|
|
var out = me.toggle_editable_row(); |
|
|
|
} |
|
|
|
var out = me.toggle_editable_row(); |
|
|
|
var col = this; |
|
|
|
setTimeout(function () { |
|
|
|
$(col).find('input[type="Text"]:first').focus(); |
|
|
|
}, 500); |
|
|
|
let first_input_field = $(col).find('input[type="Text"]:first'); |
|
|
|
|
|
|
|
first_input_field.length && on_input_focus(first_input_field); |
|
|
|
|
|
|
|
first_input_field.trigger("focus"); |
|
|
|
first_input_field.one("blur", () => (input_in_focus = false)); |
|
|
|
|
|
|
|
first_input_field.data("fieldtype") == "Date" && handle_date_picker(); |
|
|
|
|
|
|
|
return out; |
|
|
|
}); |
|
|
|
|
|
|
@@ -1151,6 +1258,7 @@ export default class GridRow { |
|
|
|
show_form() { |
|
|
|
if (frappe.utils.is_xs()) { |
|
|
|
$(this.grid.form_grid).css("min-width", "0"); |
|
|
|
$(this.grid.form_grid).css("position", "unset"); |
|
|
|
} |
|
|
|
if (!this.grid_form) { |
|
|
|
this.grid_form = new GridRowForm({ |
|
|
@@ -1191,7 +1299,8 @@ export default class GridRow { |
|
|
|
} |
|
|
|
hide_form() { |
|
|
|
if (frappe.utils.is_xs()) { |
|
|
|
$(this.grid.form_grid).css("min-width", "1000px"); |
|
|
|
$(this.grid.form_grid).css("min-width", "738px"); |
|
|
|
$(this.grid.form_grid).css("position", "relative"); |
|
|
|
} |
|
|
|
frappe.dom.unfreeze(); |
|
|
|
this.row.toggle(true); |
|
|
|