Merge pull request #16070 from shariquerik/grid-search-feat
feat: Grid Search
This commit is contained in:
commit
b176443792
9 changed files with 502 additions and 31 deletions
59
cypress/fixtures/child_table_doctype_1.js
Normal file
59
cypress/fixtures/child_table_doctype_1.js
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
export default {
|
||||
name: "Child Table Doctype 1",
|
||||
actions: [],
|
||||
custom: 1,
|
||||
autoname: "format: Test-{####}",
|
||||
creation: "2022-02-09 20:15:21.242213",
|
||||
doctype: "DocType",
|
||||
editable_grid: 1,
|
||||
engine: "InnoDB",
|
||||
fields: [
|
||||
{
|
||||
fieldname: "data",
|
||||
fieldtype: "Data",
|
||||
in_list_view: 1,
|
||||
label: "Data"
|
||||
},
|
||||
{
|
||||
fieldname: "barcode",
|
||||
fieldtype: "Barcode",
|
||||
in_list_view: 1,
|
||||
label: "Barcode"
|
||||
},
|
||||
{
|
||||
fieldname: "check",
|
||||
fieldtype: "Check",
|
||||
in_list_view: 1,
|
||||
label: "Check"
|
||||
},
|
||||
{
|
||||
fieldname: "rating",
|
||||
fieldtype: "Rating",
|
||||
in_list_view: 1,
|
||||
label: "Rating"
|
||||
},
|
||||
{
|
||||
fieldname: "duration",
|
||||
fieldtype: "Duration",
|
||||
in_list_view: 1,
|
||||
label: "Duration"
|
||||
},
|
||||
{
|
||||
fieldname: "date",
|
||||
fieldtype: "Date",
|
||||
in_list_view: 1,
|
||||
label: "Date"
|
||||
}
|
||||
],
|
||||
links: [],
|
||||
istable: 1,
|
||||
modified: "2022-02-10 12:03:12.603763",
|
||||
modified_by: "Administrator",
|
||||
module: "Custom",
|
||||
naming_rule: "By fieldname",
|
||||
owner: "Administrator",
|
||||
permissions: [],
|
||||
sort_field: 'modified',
|
||||
sort_order: 'ASC',
|
||||
track_changes: 1
|
||||
};
|
||||
|
|
@ -20,6 +20,12 @@ export default {
|
|||
label: "Child Table",
|
||||
options: "Child Table Doctype",
|
||||
reqd: 1
|
||||
},
|
||||
{
|
||||
fieldname: "child_table_1",
|
||||
fieldtype: "Table",
|
||||
label: "Child Table 1",
|
||||
options: "Child Table Doctype 1"
|
||||
}
|
||||
],
|
||||
links: [],
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import doctype_with_child_table from '../fixtures/doctype_with_child_table';
|
||||
import child_table_doctype from '../fixtures/child_table_doctype';
|
||||
import child_table_doctype_1 from '../fixtures/child_table_doctype_1';
|
||||
import doctype_to_link from '../fixtures/doctype_to_link';
|
||||
const doctype_to_link_name = doctype_to_link.name;
|
||||
const child_table_doctype_name = child_table_doctype.name;
|
||||
|
|
@ -9,6 +10,7 @@ context('Dashboard links', () => {
|
|||
cy.visit('/login');
|
||||
cy.login();
|
||||
cy.insert_doc('DocType', child_table_doctype, true);
|
||||
cy.insert_doc('DocType', child_table_doctype_1, true);
|
||||
cy.insert_doc('DocType', doctype_with_child_table, true);
|
||||
cy.insert_doc('DocType', doctype_to_link, true);
|
||||
return cy.window().its('frappe').then(frappe => {
|
||||
|
|
|
|||
107
cypress/integration/grid_search.js
Normal file
107
cypress/integration/grid_search.js
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
import doctype_with_child_table from '../fixtures/doctype_with_child_table';
|
||||
import child_table_doctype from '../fixtures/child_table_doctype';
|
||||
import child_table_doctype_1 from '../fixtures/child_table_doctype_1';
|
||||
const doctype_with_child_table_name = doctype_with_child_table.name;
|
||||
|
||||
context('Grid Search', () => {
|
||||
before(() => {
|
||||
cy.visit('/login');
|
||||
cy.login();
|
||||
cy.visit('/app/website');
|
||||
cy.insert_doc('DocType', child_table_doctype, true);
|
||||
cy.insert_doc('DocType', child_table_doctype_1, true);
|
||||
cy.insert_doc('DocType', doctype_with_child_table, true);
|
||||
return cy.window().its('frappe').then(frappe => {
|
||||
return frappe.xcall("frappe.tests.ui_test_helpers.insert_doctype_with_child_table_record", {
|
||||
name: doctype_with_child_table_name
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Test search row visibility', () => {
|
||||
cy.window().its('frappe').then(frappe => {
|
||||
frappe.model.user_settings.save('Doctype With Child Table', 'GridView', {
|
||||
'Child Table Doctype 1': [
|
||||
{'fieldname': 'data', 'columns': 2},
|
||||
{'fieldname': 'barcode', 'columns': 1},
|
||||
{'fieldname': 'check', 'columns': 1},
|
||||
{'fieldname': 'rating', 'columns': 2},
|
||||
{'fieldname': 'duration', 'columns': 2},
|
||||
{'fieldname': 'date', 'columns': 2}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
cy.visit(`/app/doctype-with-child-table/Test Grid Search`);
|
||||
|
||||
cy.get('.frappe-control[data-fieldname="child_table_1"]').as('table');
|
||||
cy.get('@table').find('.grid-row-check:last').click();
|
||||
cy.get('@table').find('.grid-footer').contains('Delete').click();
|
||||
cy.get('.grid-heading-row .grid-row .search').should('not.exist');
|
||||
});
|
||||
|
||||
it('test search field for different fieldtypes', () => {
|
||||
cy.visit(`/app/doctype-with-child-table/Test Grid Search`);
|
||||
|
||||
cy.get('.frappe-control[data-fieldname="child_table_1"]').as('table');
|
||||
|
||||
// Index Column
|
||||
cy.get('@table').find('.grid-heading-row .row-index.search input').type('3');
|
||||
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 2);
|
||||
cy.get('@table').find('.grid-heading-row .row-index.search input').clear();
|
||||
|
||||
// Data Column
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Data"]').type('Data');
|
||||
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 1);
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Data"]').clear();
|
||||
|
||||
// Barcode Column
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Barcode"]').type('092');
|
||||
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 4);
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Barcode"]').clear();
|
||||
|
||||
// Check Column
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Check"]').type('1');
|
||||
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 9);
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Check"]').clear();
|
||||
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Check"]').type('0');
|
||||
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 11);
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Check"]').clear();
|
||||
|
||||
// Rating Column
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Rating"]').type('3');
|
||||
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 3);
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Rating"]').clear();
|
||||
|
||||
// Duration Column
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Duration"]').type('3d');
|
||||
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 3);
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Duration"]').clear();
|
||||
|
||||
// Date Column
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Date"]').type('2022');
|
||||
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 4);
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Date"]').clear();
|
||||
});
|
||||
|
||||
it('test with multiple filter', () => {
|
||||
cy.get('.frappe-control[data-fieldname="child_table_1"]').as('table');
|
||||
|
||||
// Data Column
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Data"]').type('a');
|
||||
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 10);
|
||||
|
||||
// Barcode Column
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Barcode"]').type('0');
|
||||
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 8);
|
||||
|
||||
// Duration Column
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Duration"]').type('d');
|
||||
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 5);
|
||||
|
||||
// Date Column
|
||||
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Date"]').type('02-');
|
||||
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 2);
|
||||
});
|
||||
});
|
||||
|
|
@ -35,7 +35,7 @@ export default class Grid {
|
|||
&& this.frm.meta.__form_grid_templates[this.df.fieldname]) {
|
||||
this.template = this.frm.meta.__form_grid_templates[this.df.fieldname];
|
||||
}
|
||||
|
||||
this.filter = {};
|
||||
this.is_grid = true;
|
||||
this.debounced_refresh = this.refresh.bind(this);
|
||||
this.debounced_refresh = frappe.utils.debounce(this.debounced_refresh, 100);
|
||||
|
|
@ -274,6 +274,8 @@ export default class Grid {
|
|||
}
|
||||
|
||||
make_head() {
|
||||
if (this.prevent_build) return;
|
||||
|
||||
// labels
|
||||
if (this.header_row) {
|
||||
$(this.parent).find(".grid-heading-row .grid-row").remove();
|
||||
|
|
@ -286,12 +288,42 @@ export default class Grid {
|
|||
grid: this,
|
||||
configure_columns: true
|
||||
});
|
||||
|
||||
this.header_search = new GridRow({
|
||||
parent: $(this.parent).find(".grid-heading-row"),
|
||||
parent_df: this.df,
|
||||
docfields: this.docfields,
|
||||
frm: this.frm,
|
||||
grid: this,
|
||||
show_search: true
|
||||
});
|
||||
|
||||
Object.keys(this.filter).length !== 0 &&
|
||||
this.update_search_columns();
|
||||
}
|
||||
|
||||
refresh(force) {
|
||||
update_search_columns() {
|
||||
for (const field in this.filter) {
|
||||
if (this.filter[field] && !this.header_search.search_columns[field]) {
|
||||
delete this.filter[field];
|
||||
this.data = this.get_data(Object.keys(this.filter).length !== 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.filter[field] && this.filter[field].value) {
|
||||
let $input = this.header_search.row_index.find('input');
|
||||
if (field && field !== 'row-index') {
|
||||
$input = this.header_search.search_columns[field].find('input');
|
||||
}
|
||||
$input.val(this.filter[field].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
refresh() {
|
||||
if (this.frm && this.frm.setting_dependency) return;
|
||||
|
||||
this.data = this.get_data();
|
||||
this.data = this.get_data(Object.keys(this.filter).length !== 0);
|
||||
|
||||
!this.wrapper && this.make();
|
||||
let $rows = $(this.parent).find('.rows');
|
||||
|
|
@ -453,7 +485,7 @@ export default class Grid {
|
|||
}
|
||||
|
||||
make_sortable($rows) {
|
||||
new Sortable($rows.get(0), {
|
||||
this.grid_sortable = new Sortable($rows.get(0), {
|
||||
group: { name: this.df.fieldname },
|
||||
handle: '.sortable-handle',
|
||||
draggable: '.grid-row',
|
||||
|
|
@ -484,14 +516,78 @@ export default class Grid {
|
|||
$(this.frm.wrapper).trigger("grid-make-sortable", [this.frm]);
|
||||
}
|
||||
|
||||
get_data() {
|
||||
var data = this.frm ?
|
||||
this.frm.doc[this.df.fieldname] || []
|
||||
: this.df.data || this.get_modal_data();
|
||||
// data.sort(function(a, b) { return a.idx - b.idx});
|
||||
get_data(filter_field) {
|
||||
let data = [];
|
||||
if (filter_field) {
|
||||
data = this.get_filtered_data();
|
||||
} else {
|
||||
data = this.frm ?
|
||||
this.frm.doc[this.df.fieldname] || []
|
||||
: this.df.data || this.get_modal_data();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
get_filtered_data() {
|
||||
if (!this.frm) return;
|
||||
|
||||
let all_data = this.frm.doc[this.df.fieldname];
|
||||
|
||||
for (const field in this.filter) {
|
||||
all_data = all_data.filter(data => {
|
||||
let {df, value} = this.filter[field];
|
||||
return this.get_data_based_on_fieldtype(df, data, value.toLowerCase());
|
||||
});
|
||||
}
|
||||
|
||||
return all_data;
|
||||
}
|
||||
|
||||
get_data_based_on_fieldtype(df, data, value) {
|
||||
let fieldname = df.fieldname;
|
||||
let fieldtype = df.fieldtype;
|
||||
let fieldvalue = data[fieldname];
|
||||
|
||||
if (fieldtype === "Check") {
|
||||
value = frappe.utils.string_to_boolean(value);
|
||||
return (Boolean(fieldvalue) === value) && data;
|
||||
} else if (fieldtype === "Sr No" && data.idx.toString().includes(value)) {
|
||||
return data;
|
||||
} else if (fieldtype === "Duration" && fieldvalue) {
|
||||
let formatted_duration = frappe.utils.get_formatted_duration(fieldvalue);
|
||||
|
||||
if (formatted_duration.includes(value)) {
|
||||
return data;
|
||||
}
|
||||
} else if (fieldtype === "Barcode" && fieldvalue) {
|
||||
let barcode = fieldvalue.startsWith('<svg') ?
|
||||
$(fieldvalue).attr('data-barcode-value') : fieldvalue;
|
||||
|
||||
if (barcode.toLowerCase().includes(value)) {
|
||||
return data;
|
||||
}
|
||||
} else if (["Datetime", "Date"].includes(fieldtype) && fieldvalue) {
|
||||
let user_formatted_date = frappe.datetime.str_to_user(fieldvalue);
|
||||
|
||||
if (user_formatted_date.includes(value)) {
|
||||
return data;
|
||||
}
|
||||
} else if (["Currency", "Float", "Int", "Percent", "Rating"].includes(fieldtype)) {
|
||||
let num = fieldvalue || 0;
|
||||
|
||||
if (fieldtype === "Rating") {
|
||||
let out_of_rating = parseInt(df.options) || 5;
|
||||
num = num * out_of_rating;
|
||||
}
|
||||
|
||||
if (num.toString().indexOf(value) > -1) {
|
||||
return data;
|
||||
}
|
||||
} else if (fieldvalue && fieldvalue.toLowerCase().includes(value)) {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
get_modal_data() {
|
||||
return this.df.get_data ? this.df.get_data().filter(data => {
|
||||
if (!this.deleted_docs || !in_list(this.deleted_docs, data.name)) {
|
||||
|
|
@ -775,18 +871,19 @@ export default class Grid {
|
|||
}
|
||||
|
||||
setup_user_defined_columns() {
|
||||
if (this.frm) {
|
||||
let user_settings = frappe.get_user_settings(this.frm.doctype, 'GridView');
|
||||
if (user_settings && user_settings[this.doctype] && user_settings[this.doctype].length) {
|
||||
this.user_defined_columns = user_settings[this.doctype].map(row => {
|
||||
let column = frappe.meta.get_docfield(this.doctype, row.fieldname);
|
||||
if (column) {
|
||||
column.in_list_view = 1;
|
||||
column.columns = row.columns;
|
||||
return column;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!this.frm) return;
|
||||
|
||||
let user_settings = frappe.get_user_settings(this.frm.doctype, 'GridView');
|
||||
if (user_settings && user_settings[this.doctype] && user_settings[this.doctype].length) {
|
||||
this.user_defined_columns = user_settings[this.doctype].map(row => {
|
||||
let column = frappe.meta.get_docfield(this.doctype, row.fieldname);
|
||||
|
||||
if (column) {
|
||||
column.in_list_view = 1;
|
||||
column.columns = row.columns;
|
||||
return column;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ export default class GridRow {
|
|||
this.set_docfields();
|
||||
this.columns = {};
|
||||
this.columns_list = [];
|
||||
this.row_check_html = '<input type="checkbox" class="grid-row-check pull-left">';
|
||||
this.row_check_html = '<input type="checkbox" class="grid-row-check">';
|
||||
this.make();
|
||||
}
|
||||
make() {
|
||||
|
|
@ -204,23 +204,65 @@ export default class GridRow {
|
|||
}));
|
||||
}
|
||||
render_row(refresh) {
|
||||
var me = this;
|
||||
if (this.show_search && !this.show_search_row()) return;
|
||||
|
||||
let me = this;
|
||||
this.set_row_index();
|
||||
|
||||
// index (1, 2, 3 etc)
|
||||
if(!this.row_index) {
|
||||
if (!this.row_index && !this.show_search) {
|
||||
// REDESIGN-TODO: Make translation contextual, this No is Number
|
||||
var txt = (this.doc ? this.doc.idx : __("No."));
|
||||
this.row_index = $(
|
||||
`<div class="row-index sortable-handle col">
|
||||
|
||||
this.row_check = $(
|
||||
`<div class="row-check sortable-handle col">
|
||||
${this.row_check_html}
|
||||
<span class="hidden-xs">${txt}</span></div>`)
|
||||
</div>`)
|
||||
.appendTo(this.row);
|
||||
|
||||
this.row_index = $(
|
||||
`<div class="row-index sortable-handle col hidden-xs">
|
||||
<span>${txt}</span>
|
||||
</div>`)
|
||||
.appendTo(this.row)
|
||||
.on('click', function(e) {
|
||||
if(!$(e.target).hasClass('grid-row-check')) {
|
||||
me.toggle_view();
|
||||
}
|
||||
});
|
||||
} else if (this.show_search) {
|
||||
this.row_check = $(
|
||||
`<div class="row-check col search"></div>`
|
||||
).appendTo(this.row);
|
||||
|
||||
this.row_index = $(
|
||||
`<div class="row-index col search hidden-xs">
|
||||
<input type="text" class="form-control input-xs text-center" >
|
||||
</div>`
|
||||
).appendTo(this.row);
|
||||
|
||||
this.row_index.find('input').on('keyup', frappe.utils.debounce((e) => {
|
||||
let df = {
|
||||
fieldtype: "Sr No"
|
||||
};
|
||||
|
||||
this.grid.filter['row-index'] = {
|
||||
df: df,
|
||||
value: e.target.value
|
||||
};
|
||||
|
||||
if (e.target.value == "") {
|
||||
delete this.grid.filter['row-index'];
|
||||
}
|
||||
|
||||
this.grid.grid_sortable
|
||||
.option('disabled', Object.keys(this.grid.filter).length !== 0);
|
||||
|
||||
this.grid.prevent_build = true;
|
||||
me.grid.refresh();
|
||||
this.grid.prevent_build = false;
|
||||
}, 500));
|
||||
frappe.utils.only_allow_num_decimal(this.row_index.find('input'));
|
||||
} else {
|
||||
this.row_index.find('span').html(txt);
|
||||
}
|
||||
|
|
@ -546,6 +588,7 @@ export default class GridRow {
|
|||
|
||||
setup_columns() {
|
||||
this.focus_set = false;
|
||||
this.search_columns = {};
|
||||
|
||||
this.grid.setup_visible_columns();
|
||||
this.grid.visible_columns.forEach((col, ci) => {
|
||||
|
|
@ -561,8 +604,10 @@ export default class GridRow {
|
|||
txt = __(txt);
|
||||
}
|
||||
let column;
|
||||
if (!this.columns[df.fieldname]) {
|
||||
if (!this.columns[df.fieldname] && !this.show_search) {
|
||||
column = this.make_column(df, colsize, txt, ci);
|
||||
} else if (!this.columns[df.fieldname] && this.show_search) {
|
||||
column = this.make_search_column(df, colsize);
|
||||
} else {
|
||||
column = this.columns[df.fieldname];
|
||||
this.refresh_field(df.fieldname, txt);
|
||||
|
|
@ -580,6 +625,77 @@ export default class GridRow {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (this.show_search) {
|
||||
// last empty column
|
||||
$(`<div class="col grid-static-col col-xs-1"></div>`)
|
||||
.appendTo(this.row);
|
||||
}
|
||||
}
|
||||
|
||||
show_search_row() {
|
||||
// show or remove search columns based on grid rows
|
||||
this.show_search = this.frm && this.frm.doc &&
|
||||
this.frm.doc[this.grid.df.fieldname] &&
|
||||
this.frm.doc[this.grid.df.fieldname].length >= 20;
|
||||
!this.show_search && this.wrapper.remove();
|
||||
return this.show_search;
|
||||
}
|
||||
|
||||
make_search_column(df, colsize) {
|
||||
let title = "";
|
||||
let input_class = "";
|
||||
let is_disabled = "";
|
||||
|
||||
if (["Text", "Small Text"].includes(df.fieldtype)) {
|
||||
input_class = "grid-overflow-no-ellipsis";
|
||||
} else if (["Int", "Currency", "Float", "Percent"].includes(df.fieldtype)) {
|
||||
input_class = "text-right";
|
||||
} else if (df.fieldtype === "Check") {
|
||||
title = __("1 = True & 0 = False");
|
||||
input_class = "text-center";
|
||||
} else if (df.fieldtype === 'Password') {
|
||||
is_disabled = 'disabled';
|
||||
title = __('Password cannot be filtered');
|
||||
}
|
||||
|
||||
let $col = $('<div class="col grid-static-col col-xs-'+colsize+' search"></div>')
|
||||
.appendTo(this.row);
|
||||
|
||||
let $search_input = $(`
|
||||
<input
|
||||
type="text"
|
||||
class="form-control input-xs ${input_class}"
|
||||
title="${title}"
|
||||
data-fieldtype="${df.fieldtype}"
|
||||
${is_disabled}
|
||||
>
|
||||
`).appendTo($col);
|
||||
|
||||
this.search_columns[df.fieldname] = $col;
|
||||
|
||||
$search_input.on('keyup', frappe.utils.debounce((e) => {
|
||||
this.grid.filter[df.fieldname] = {
|
||||
df: df,
|
||||
value: e.target.value
|
||||
};
|
||||
|
||||
if (e.target.value == '') {
|
||||
delete this.grid.filter[df.fieldname];
|
||||
}
|
||||
|
||||
this.grid.grid_sortable
|
||||
.option('disabled', Object.keys(this.grid.filter).length !== 0);
|
||||
|
||||
this.grid.prevent_build = true;
|
||||
this.grid.refresh();
|
||||
this.grid.prevent_build = false;
|
||||
}, 500));
|
||||
|
||||
["Currency", "Float", "Int", "Percent", "Rating"].includes(df.fieldtype) &&
|
||||
frappe.utils.only_allow_num_decimal($search_input);
|
||||
|
||||
return $col;
|
||||
}
|
||||
|
||||
make_column(df, colsize, txt, ci) {
|
||||
|
|
|
|||
|
|
@ -1102,7 +1102,7 @@ Object.assign(frappe.utils, {
|
|||
seconds: round(seconds % 60)
|
||||
};
|
||||
|
||||
if (duration_options.hide_days) {
|
||||
if (duration_options && duration_options.hide_days) {
|
||||
total_duration.hours = round(seconds / 3600);
|
||||
total_duration.days = 0;
|
||||
}
|
||||
|
|
@ -1462,5 +1462,23 @@ Object.assign(frappe.utils, {
|
|||
console.log(error); // eslint-disable-line
|
||||
return Promise.resolve(name);
|
||||
}
|
||||
},
|
||||
|
||||
only_allow_num_decimal(input) {
|
||||
input.on('input', (e) => {
|
||||
let self = $(e.target);
|
||||
self.val(self.val().replace(/[^0-9.]/g, ''));
|
||||
if ((e.which != 46 || self.val().indexOf('.') != -1) && (e.which < 48 || e.which > 57)) {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
string_to_boolean(string) {
|
||||
switch (string.toLowerCase().trim()) {
|
||||
case "t": case "true": case "y": case "yes": case "1": return true;
|
||||
case "f": case "false": case "n": case "no": case "0": case null: return false;
|
||||
default: return string;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -89,6 +89,29 @@
|
|||
height: 34px;
|
||||
padding: 8px;
|
||||
max-height: 200px;
|
||||
|
||||
&.search {
|
||||
padding: 7px !important;
|
||||
|
||||
input {
|
||||
height: -webkit-fill-available;
|
||||
padding: 3px 7px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.row-check {
|
||||
height: 34px;
|
||||
padding: 8px 3px !important;
|
||||
text-align: center;
|
||||
|
||||
input {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
||||
&.search {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.grid-row-check {
|
||||
|
|
@ -124,7 +147,6 @@
|
|||
|
||||
.grid-row > .row {
|
||||
.col:last-child {
|
||||
margin-right: calc(-1 * var(--margin-sm));
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
|
|
@ -427,6 +449,7 @@
|
|||
}
|
||||
|
||||
.page-number {
|
||||
background-color: var(--fg-color);
|
||||
padding: 0 3px;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -272,4 +272,47 @@ def update_child_table(name):
|
|||
'options': 'Doctype to Link'
|
||||
})
|
||||
|
||||
doc.save()
|
||||
doc.save()
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def insert_doctype_with_child_table_record(name):
|
||||
if frappe.db.get_all(name, {'title': 'Test Grid Search'}):
|
||||
return
|
||||
|
||||
def insert_child(doc, data, barcode, check, rating, duration, date):
|
||||
doc.append('child_table_1', {
|
||||
'data': data,
|
||||
'barcode': barcode,
|
||||
'check': check,
|
||||
'rating': rating,
|
||||
'duration': duration,
|
||||
'date': date,
|
||||
})
|
||||
|
||||
doc = frappe.new_doc(name)
|
||||
doc.title = 'Test Grid Search'
|
||||
doc.append('child_table', {'title': 'Test Grid Search'})
|
||||
|
||||
insert_child(doc, 'Data', '09709KJKKH2432', 1, 0.5, 266851, "2022-02-21")
|
||||
insert_child(doc, 'Test', '09209KJHKH2432', 1, 0.8, 547877, "2021-05-27")
|
||||
insert_child(doc, 'New', '09709KJHYH1132', 0, 0.1, 3, "2019-03-02")
|
||||
insert_child(doc, 'Old', '09701KJHKH8750', 0, 0, 127455, "2022-01-11")
|
||||
insert_child(doc, 'Alpha', '09204KJHKH2432', 0, 0.6, 364, "2019-12-31")
|
||||
insert_child(doc, 'Delta', '09709KSPIO2432', 1, 0.9, 1242000, "2020-04-21")
|
||||
insert_child(doc, 'Update', '76989KJLVA2432', 0, 1, 183845, "2022-02-10")
|
||||
insert_child(doc, 'Delete', '29189KLHVA1432', 0, 0, 365647, "2021-05-07")
|
||||
insert_child(doc, 'Make', '09689KJHAA2431', 0, 0.3, 24, "2020-11-11")
|
||||
insert_child(doc, 'Create', '09709KLKKH2432', 1, 0.3, 264851, "2021-02-21")
|
||||
insert_child(doc, 'Group', '09209KJLKH2432', 1, 0.8, 537877, "2020-03-15")
|
||||
insert_child(doc, 'Slide', '01909KJHYH1132', 0, 0.5, 9, "2018-03-02")
|
||||
insert_child(doc, 'Drop', '09701KJHKH8750', 1, 0, 127255, "2018-01-01")
|
||||
insert_child(doc, 'Beta', '09204QJHKN2432', 0, 0.6, 354, "2017-12-30")
|
||||
insert_child(doc, 'Flag', '09709KXPIP2432', 1, 0, 1241000, "2021-04-21")
|
||||
insert_child(doc, 'Upgrade', '75989ZJLVA2432', 0.8, 1, 183645, "2020-08-13")
|
||||
insert_child(doc, 'Down', '28189KLHRA1432', 1, 0, 362647, "2020-06-17")
|
||||
insert_child(doc, 'Note', '09689DJHAA2431', 0, 0.1, 29, "2021-09-11")
|
||||
insert_child(doc, 'Click', '08189DJHAA2431', 1, 0.3, 209, "2020-07-04")
|
||||
insert_child(doc, 'Drag', '08189DIHAA2981', 0, 0.7, 342628, "2022-05-04")
|
||||
|
||||
doc.insert()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue