Skip to content

Commit

Permalink
Merge pull request frappe#29142 from iamejaaz/child-table-ui-29106
Browse files Browse the repository at this point in the history
  • Loading branch information
surajshetty3416 authored Jan 16, 2025
2 parents 430c0c7 + 98be3f4 commit 9a1eab7
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 44 deletions.
56 changes: 53 additions & 3 deletions frappe/public/js/frappe/form/grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ export default class Grid {
<div class="grid-empty text-center text-extra-muted">
${__("No rows")}
</div>
<div class="grid-scroll-bar">
<div class="grid-scroll-bar-rows"></div>
</div>
</div>
</div>
<div class="grid-scroll-bar">
<div class="grid-scroll-bar-rows"></div>
</div>
</div>
<div class="small form-clickable-section grid-footer">
<div class="flex justify-between">
Expand Down Expand Up @@ -123,6 +123,56 @@ export default class Grid {

this.form_grid = this.wrapper.find(".form-grid");

if (this.form_grid) {
this.form_grid.on("wheel", (e) => {
const isTrackpad = Math.abs(e.originalEvent.wheelDeltaY) < 50;
const delta = e.originalEvent.deltaX;
const scroll_bar = this.wrapper.find(".grid-scroll-bar");

if (isTrackpad) {
scroll_bar.scrollLeft(scroll_bar.scrollLeft() + delta);
} else {
scroll_bar.scrollLeft(scroll_bar.scrollLeft() + delta * 4);
}

// prevent default behaviour when it is scrolled horizontally
if (e.originalEvent.deltaX != 0) {
e.preventDefault();
}
});
let touchStartX = 0;
let touchMoveX = 0;
let isTouchScrolling = false;

// Handle touch start
this.form_grid.on("touchstart", (e) => {
const touch = e.originalEvent.touches[0];
touchStartX = touch.pageX;
isTouchScrolling = true;
});

// Handle touch move
this.form_grid.on("touchmove", (e) => {
if (!isTouchScrolling) return;

const touch = e.originalEvent.touches[0];
touchMoveX = touch.pageX;

const scrollBar = this.wrapper.find(".grid-scroll-bar");
const deltaX = touchStartX - touchMoveX;

scrollBar.scrollLeft(scrollBar.scrollLeft() + deltaX);

touchStartX = touchMoveX;

e.preventDefault();
});

// Handle touch end
this.form_grid.on("touchend", () => {
isTouchScrolling = false;
});
}
this.setup_add_row();

this.setup_grid_pagination();
Expand Down
71 changes: 49 additions & 22 deletions frappe/public/js/frappe/form/grid_row.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default class GridRow {
this.columns_list = [];
this.row_check_html = '<input type="checkbox" class="grid-row-check">';
this.make();
this.setup_tab_listeners();
}
make() {
let me = this;
Expand Down Expand Up @@ -269,11 +270,15 @@ export default class GridRow {
}
});
} else if (this.show_search) {
this.row_check = $(`<div class="row-check col search"></div>`).appendTo(this.row);
this.row_check = $(`
<div class="row-check col search">
<input type="text" class="form-control input-xs text-center invisible">
</div>`).appendTo(this.row);

this.row_index = $(
`<div class="row-index col search">
<input type="text" class="form-control input-xs text-center" >
<span style="width: 33px;" class="d-block"></span>
</div>`
).appendTo(this.row);

Expand Down Expand Up @@ -982,43 +987,65 @@ export default class GridRow {
$col.field_area = $('<div class="field-area"></div>').appendTo($col).toggle(false);
$col.static_area = $('<div class="static-area ellipsis"></div>').appendTo($col).html(txt);

this.handle_scroll_bar();

// set title attribute to see full label for columns in the heading row
if (!this.doc) {
$col.attr("title", txt);
}
df.fieldname && $col.static_area.toggleClass("reqd", Boolean(df.reqd));

$col.df = df;
$col.column_index = ci;

this.columns[df.fieldname] = $col;
this.columns_list.push($col);

return $col;
}

handle_scroll_bar() {
$(document).ready(function () {
let $scrollBar = $(".grid-scroll-bar");
let form_grid = $(".form-grid");
let grid_container = $(".form-grid-container");
let grid_scroll_bar_rows = $(".grid-scroll-bar-rows");
let parent_field_name = "";
let grid_width = 0;
let grid_body_width = 0;
form_grid.each((grid_index, grid) => {
parent_field_name = $(grid)
.closest("[data-fieldname][data-fieldtype]")
.attr("data-fieldname");
grid_width = $($(grid)[0]).width();
grid_body_width = $(
'div[data-fieldname="' + parent_field_name + '"] .grid-body'
).width();

$('div[data-fieldname="' + parent_field_name + '"] .grid-scroll-bar').width(
grid_width
);
$('div[data-fieldname="' + parent_field_name + '"] .grid-scroll-bar-rows').width(
grid_body_width
);
});

// Make sure the grid container is scrollable
$scrollBar.on("scroll", function (event) {
grid_container = $(event.currentTarget).closest(".form-grid-container");
form_grid = $(event.currentTarget).closest(".form-grid");
grid_scroll_bar_rows = $(event.currentTarget).closest(".grid-scroll-bar-rows");

var scroll_left = $(this).scrollLeft();

// Sync the form grid's left position with the scroll bar
form_grid.css("position", "relative");
form_grid.css("left", -scroll_left + "px");
$(this).css("margin-left", scroll_left + "px");
});

$scrollBar.css("width", grid_container.width());

grid_scroll_bar_rows.css("width", form_grid[0].scrollWidth);
});
}

// set title attribute to see full label for columns in the heading row
if (!this.doc) {
$col.attr("title", txt);
}
df.fieldname && $col.static_area.toggleClass("reqd", Boolean(df.reqd));

$col.df = df;
$col.column_index = ci;

this.columns[df.fieldname] = $col;
this.columns_list.push($col);

return $col;
setup_tab_listeners() {
$(".nav-link").on("shown.bs.tab", () => {
this.handle_scroll_bar();
});
}

activate() {
Expand Down
57 changes: 38 additions & 19 deletions frappe/public/scss/common/grid.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
border: 1px solid var(--table-border-color);
border-radius: var(--border-radius-md);
color: var(--text-color);
min-height: 150px;
background-color: var(--subtle-accent);
}

Expand All @@ -25,15 +26,14 @@
}

&.with-filter {
height: 64px;
height: 66px;
}
.filter-row {
background-color: var(--bg-color);

.search {
// TODO: Align with table grid without overwriting padding if possible
padding: 4px 7px 4px 7px !important;
border-bottom: 1px solid var(--table-border-color);
}
}

Expand Down Expand Up @@ -190,6 +190,7 @@

.row-index {
text-align: center;
flex-grow: 0;
}

.grid-row > .row {
Expand Down Expand Up @@ -230,7 +231,9 @@
--input-disabled-bg: var(--gray-50);
.grid-static-col {
padding: 0px !important;
height: 32px;
}
.grid-static-col.row-index {
padding: var(--grid-padding) !important;
}

.frappe-control[data-fieldtype="Select"].form-group .select-icon {
Expand Down Expand Up @@ -328,6 +331,9 @@
line-height: 1.3 !important;
}
}
.data-row div[data-fieldname="options"] {
height: 40px;
}
}

@media (max-width: 767px) {
Expand Down Expand Up @@ -600,44 +606,58 @@
background-color: var(--subtle-accent);
border-top-left-radius: var(--border-radius-md);
border-top-right-radius: var(--border-radius-md);
border: 1px solid var(--table-border-color);
.form-grid {
display: grid;
grid-auto-rows: min-content;
border: unset;
.grid-static-col.col-xs-1 {
flex: 1 0 60px;
width: 60px;
}
.grid-static-col.col-xs-2 {
flex: 1 0 90px;
flex: 1 0 100px;
width: 100px;
}
.grid-static-col.col-xs-3 {
flex: 1 0 120px;
flex: 1 0 140px;
width: 140px;
}
.grid-static-col.col-xs-4 {
flex: 1 0 150px;
flex: 1 0 200px;
width: 200;
}
.grid-static-col.col-xs-5 {
flex: 1 0 200px;
flex: 1 0 250px;
width: 250px;
}
.grid-static-col.col-xs-6 {
flex: 1 0 250px;
flex: 1 0 300px;
width: 300px;
}
.grid-static-col.col-xs-7 {
flex: 1 0 300px;
flex: 1 0 350px;
width: 350px;
}
.grid-static-col.col-xs-8 {
flex: 1 0 350px;
flex: 1 0 400px;
width: 400px;
}
.grid-static-col.col-xs-9 {
flex: 1 0 400px;
flex: 1 0 450px;
width: 450px;
}
.grid-static-col.col-xs-10 {
flex: 1 0 450px;
flex: 1 0 500px;
width: 500px;
}
.grid-static-col.col-xs-11 {
flex: 1 0 500px;
flex: 1 0 550px;
width: 550px;
}
.grid-static-col.col-xs-12 {
flex: 1 0 550px;
flex: 1 0 600px;
width: 600px;
}
.grid-row > .row .col:last-child,
.grid-row > .dialog-assignment-row .col:first-child,
Expand All @@ -650,10 +670,13 @@
max-width: 40px;
min-width: 40px;
}
.grid-heading-row .grid-row .data-row.row,
.grid-body .rows .grid-row .data-row.row {
justify-content: space-between;
}
}
}
.grid-scroll-bar {
display: none;
overflow-x: auto;
height: 12px;
position: relative;
Expand All @@ -670,10 +693,6 @@
}

@media (max-width: map-get($grid-breakpoints, "md")) {
.grid-scroll-bar {
display: block;
}

.form-column.col-sm-6 .form-grid {
.row-index {
display: block;
Expand Down

0 comments on commit 9a1eab7

Please sign in to comment.