diff --git a/frappe/public/js/frappe/ui/filters/filter.js b/frappe/public/js/frappe/ui/filters/filter.js
index 37eab50957..5e41ed645e 100644
--- a/frappe/public/js/frappe/ui/filters/filter.js
+++ b/frappe/public/js/frappe/ui/filters/filter.js
@@ -13,26 +13,26 @@ frappe.ui.Filter = class {
set_conditions() {
this.conditions = [
- ["=", __("Equals")],
- ["!=", __("Not Equals")],
- ["like", __("Like")],
- ["not like", __("Not Like")],
- ["in", __("In")],
- ["not in", __("Not In")],
- ["is", __("Is")],
- [">", ">"],
- ["<", "<"],
- [">=", ">="],
- ["<=", "<="],
- ["Between", __("Between")],
- ["Timespan", __("Timespan")],
+ ['=', __('Equals')],
+ ['!=', __('Not Equals')],
+ ['like', __('Like')],
+ ['not like', __('Not Like')],
+ ['in', __('In')],
+ ['not in', __('Not In')],
+ ['is', __('Is')],
+ ['>', '>'],
+ ['<', '<'],
+ ['>=', '>='],
+ ['<=', '<='],
+ ['Between', __('Between')],
+ ['Timespan', __('Timespan')],
];
this.nested_set_conditions = [
- ["descendants of", __("Descendants Of")],
- ["not descendants of", __("Not Descendants Of")],
- ["ancestors of", __("Ancestors Of")],
- ["not ancestors of", __("Not Ancestors Of")],
+ ['descendants of', __('Descendants Of')],
+ ['not descendants of', __('Not Descendants Of')],
+ ['ancestors of', __('Ancestors Of')],
+ ['not ancestors of', __('Not Ancestors Of')],
];
this.conditions.push(...this.nested_set_conditions);
@@ -42,10 +42,10 @@ frappe.ui.Filter = class {
Datetime: ['like', 'not like'],
Data: ['Between', 'Timespan'],
Select: ['like', 'not like', 'Between', 'Timespan'],
- Link: ["Between", 'Timespan', '>', '<', '>=', '<='],
- Currency: ["Between", 'Timespan'],
- Color: ["Between", 'Timespan'],
- Check: this.conditions.map(c => c[0]).filter(c => c !== '=')
+ Link: ['Between', 'Timespan', '>', '<', '>=', '<='],
+ Currency: ['Between', 'Timespan'],
+ Color: ['Between', 'Timespan'],
+ Check: this.conditions.map((c) => c[0]).filter((c) => c !== '='),
};
}
@@ -65,10 +65,11 @@ frappe.ui.Filter = class {
}
make() {
- this.filter_edit_area = $(frappe.render_template("edit_filter", {
- conditions: this.conditions
- }))
- .appendTo(this.parent.find('.filter-edit-area'));
+ this.filter_edit_area = $(
+ frappe.render_template('edit_filter', {
+ conditions: this.conditions,
+ })
+ ).appendTo(this.parent.find('.filter-edit-area'));
this.make_select();
this.set_events();
@@ -82,41 +83,51 @@ frappe.ui.Filter = class {
filter_fields: this.filter_fields,
select: (doctype, fieldname) => {
this.set_field(doctype, fieldname);
- }
+ },
});
- if(this.fieldname) {
+ if (this.fieldname) {
this.fieldselect.set_value(this.doctype, this.fieldname);
}
}
set_events() {
- this.filter_edit_area.find("a.remove-filter").on("click", () => {
+ this.filter_edit_area.find('a.remove-filter').on('click', () => {
this.remove();
});
- this.filter_edit_area.find(".set-filter-and-run").on("click", () => {
- this.filter_edit_area.removeClass("new-filter");
+ this.filter_edit_area.find('.set-filter-and-run').on('click', () => {
+ this.filter_edit_area.removeClass('new-filter');
this.on_change();
this.update_filter_tag();
});
this.filter_edit_area.find('.condition').change(() => {
- if(!this.field) return;
+ if (!this.field) return;
let condition = this.get_condition();
let fieldtype = null;
- if(["in", "like", "not in", "not like"].includes(condition)) {
+ if (['in', 'like', 'not in', 'not like'].includes(condition)) {
fieldtype = 'Data';
this.add_condition_help(condition);
+ } else {
+ this.filter_edit_area.find('.filter-description').empty();
}
- if (['Select', 'MultiSelect'].includes(this.field.df.fieldtype) && ["in", "not in"].includes(condition)) {
+ if (
+ ['Select', 'MultiSelect'].includes(this.field.df.fieldtype) &&
+ ['in', 'not in'].includes(condition)
+ ) {
fieldtype = 'MultiSelect';
}
- this.set_field(this.field.df.parent, this.field.df.fieldname, fieldtype, condition);
+ this.set_field(
+ this.field.df.parent,
+ this.field.df.fieldname,
+ fieldtype,
+ condition
+ );
});
}
@@ -129,12 +140,12 @@ frappe.ui.Filter = class {
setup_state(is_new) {
let promise = Promise.resolve();
if (is_new) {
- this.filter_edit_area.addClass("new-filter");
+ this.filter_edit_area.addClass('new-filter');
} else {
promise = this.update_filter_tag();
}
- if(this.hidden) {
+ if (this.hidden) {
promise.then(() => this.$filter_tag.hide());
}
}
@@ -164,13 +175,13 @@ frappe.ui.Filter = class {
set_values(doctype, fieldname, condition, value) {
// presents given (could be via tags!)
if (this.set_field(doctype, fieldname) === false) {
- return
+ return;
}
- if(this.field.df.original_type==='Check') {
- value = (value==1) ? 'Yes' : 'No';
+ if (this.field.df.original_type === 'Check') {
+ value = value == 1 ? 'Yes' : 'No';
}
- if(condition) this.set_condition(condition, true);
+ if (condition) this.set_condition(condition, true);
// set value can be asynchronous, so update_filter_tag should happen after field is set
this._filter_value_set = Promise.resolve();
@@ -190,11 +201,13 @@ frappe.ui.Filter = class {
set_field(doctype, fieldname, fieldtype, condition) {
// set in fieldname (again)
let cur = {};
- if(this.field) for(let k in this.field.df) cur[k] = this.field.df[k];
+ if (this.field) for (let k in this.field.df) cur[k] = this.field.df[k];
- let original_docfield = (this.fieldselect.fields_by_name[doctype] || {})[fieldname];
+ let original_docfield = (this.fieldselect.fields_by_name[doctype] || {})[
+ fieldname
+ ];
- if(!original_docfield) {
+ if (!original_docfield) {
console.warn(`Field ${fieldname} is not selectable.`);
this.remove();
return false;
@@ -214,8 +227,13 @@ frappe.ui.Filter = class {
// called when condition is changed,
// don't change if all is well
- if(this.field && cur.fieldname == fieldname && df.fieldtype == cur.fieldtype &&
- df.parent == cur.parent && df.options == cur.options) {
+ if (
+ this.field &&
+ cur.fieldname == fieldname &&
+ df.fieldtype == cur.fieldtype &&
+ df.parent == cur.parent &&
+ df.options == cur.options
+ ) {
return;
}
@@ -223,20 +241,25 @@ frappe.ui.Filter = class {
this.fieldselect.selected_doctype = doctype;
this.fieldselect.selected_fieldname = fieldname;
- if (this.filters_config && this.filters_config[condition]
- && this.filters_config[condition].valid_for_fieldtypes.includes(df.fieldtype)) {
+ if (
+ this.filters_config &&
+ this.filters_config[condition] &&
+ this.filters_config[condition].valid_for_fieldtypes.includes(df.fieldtype)
+ ) {
let args = {};
if (this.filters_config[condition].depends_on) {
const field_name = this.filters_config[condition].depends_on;
const filter_value = this.base_list.get_filter_value(field_name);
args[field_name] = filter_value;
}
- frappe.xcall(this.filters_config[condition].get_field, args).then(field => {
- df.fieldtype = field.fieldtype;
- df.options = field.options;
- df.fieldname = fieldname;
- this.make_field(df, cur.fieldtype);
- });
+ frappe
+ .xcall(this.filters_config[condition].get_field, args)
+ .then(field => {
+ df.fieldtype = field.fieldtype;
+ df.options = field.options;
+ df.fieldname = fieldname;
+ this.make_field(df, cur.fieldtype);
+ });
} else {
this.make_field(df, cur.fieldtype);
}
@@ -255,16 +278,18 @@ frappe.ui.Filter = class {
f.refresh();
this.field = f;
- if(old_text && f.fieldtype===old_fieldtype) {
+ if (old_text && f.fieldtype === old_fieldtype) {
this.field.set_value(old_text);
}
// run on enter
- $(this.field.wrapper).find(':input').keydown(e => {
- if(e.which==13 && this.field.df.fieldtype !== 'MultiSelect') {
- this.on_change();
- }
- });
+ $(this.field.wrapper)
+ .find(':input')
+ .keydown(e => {
+ if (e.which == 13 && this.field.df.fieldtype !== 'MultiSelect') {
+ this.on_change();
+ }
+ });
}
get_value() {
@@ -273,7 +298,7 @@ frappe.ui.Filter = class {
this.field.df.fieldname,
this.get_condition(),
this.get_selected_value(),
- this.hidden
+ this.hidden,
];
}
get_selected_value() {
@@ -284,90 +309,101 @@ frappe.ui.Filter = class {
return this.filter_edit_area.find('.condition').val();
}
- set_condition(condition, trigger_change=false) {
+ set_condition(condition, trigger_change = false) {
let $condition_field = this.filter_edit_area.find('.condition');
$condition_field.val(condition);
- if(trigger_change) $condition_field.change();
-
+ if (trigger_change) $condition_field.change();
}
make_tag() {
if (!this.field) return;
- this.$filter_tag = this.get_filter_tag_element()
- .insertAfter(this.parent.find(".active-tag-filters .clear-filters"));
+ this.$filter_tag = this.get_filter_tag_element().insertAfter(
+ this.parent.find('.active-tag-filters .clear-filters')
+ );
this.set_filter_button_text();
this.bind_tag();
}
bind_tag() {
- this.$filter_tag.find(".remove-filter").on("click", this.remove.bind(this));
+ this.$filter_tag.find('.remove-filter').on('click', this.remove.bind(this));
- let filter_button = this.$filter_tag.find(".toggle-filter");
- filter_button.on("click", () => {
- filter_button.closest('.tag-filters-area').find('.filter-edit-area').show();
+ let filter_button = this.$filter_tag.find('.toggle-filter');
+ filter_button.on('click', () => {
+ filter_button
+ .closest('.tag-filters-area')
+ .find('.filter-edit-area')
+ .show();
this.filter_edit_area.toggle();
});
}
set_filter_button_text() {
- this.$filter_tag.find(".toggle-filter").html(this.get_filter_button_text());
+ this.$filter_tag.find('.toggle-filter').html(this.get_filter_button_text());
}
get_filter_button_text() {
- let value = this.utils.get_formatted_value(this.field, this.get_selected_value());
- return `${__(this.field.df.label)} ${__(this.get_condition())} ${__(value)}`;
+ let value = this.utils.get_formatted_value(
+ this.field,
+ this.get_selected_value()
+ );
+ return `${__(this.field.df.label)} ${__(this.get_condition())} ${__(
+ value
+ )}`;
}
get_filter_tag_element() {
return $(`
`);
}
add_condition_help(condition) {
- let $desc = this.field.desc_area;
- if(!$desc) {
- $desc = $('
').appendTo(this.field.wrapper);
- }
- // set description
- $desc.html((in_list(["in", "not in"], condition)==="in"
- ? __("values separated by commas")
- : __("use % as wildcard"))+'
');
+ const description = ['in', 'not in'].includes(condition)
+ ? __('values separated by commas')
+ : __('use % as wildcard');
+
+ this.filter_edit_area.find('.filter-description').html(description);
}
hide_invalid_conditions(fieldtype, original_type) {
- let invalid_conditions = this.invalid_condition_map[original_type]
- || this.invalid_condition_map[fieldtype] || [];
+ let invalid_conditions =
+ this.invalid_condition_map[original_type] ||
+ this.invalid_condition_map[fieldtype] ||
+ [];
for (let condition of this.conditions) {
- this.filter_edit_area.find(`.condition option[value="${condition[0]}"]`).toggle(
- !invalid_conditions.includes(condition[0])
- );
+ this.filter_edit_area
+ .find(`.condition option[value="${condition[0]}"]`)
+ .toggle(!invalid_conditions.includes(condition[0]));
}
}
toggle_nested_set_conditions(df) {
- let show_condition = df.fieldtype === "Link" && frappe.boot.nested_set_doctypes.includes(df.options);
- this.nested_set_conditions.forEach(condition => {
- this.filter_edit_area.find(`.condition option[value="${condition[0]}"]`).toggle(show_condition);
+ let show_condition =
+ df.fieldtype === 'Link' &&
+ frappe.boot.nested_set_doctypes.includes(df.options);
+ this.nested_set_conditions.forEach((condition) => {
+ this.filter_edit_area
+ .find(`.condition option[value="${condition[0]}"]`)
+ .toggle(show_condition);
});
}
};
frappe.ui.filter_utils = {
get_formatted_value(field, value) {
- if(field.df.fieldname==="docstatus") {
- value = {0:"Draft", 1:"Submitted", 2:"Cancelled"}[value] || value;
- } else if(field.df.original_type==="Check") {
- value = {0:"No", 1:"Yes"}[cint(value)];
+ if (field.df.fieldname === 'docstatus') {
+ value = { 0: 'Draft', 1: 'Submitted', 2: 'Cancelled' }[value] || value;
+ } else if (field.df.original_type === 'Check') {
+ value = { 0: 'No', 1: 'Yes' }[cint(value)];
}
- return frappe.format(value, field.df, {only_value: 1});
+ return frappe.format(value, field.df, { only_value: 1 });
},
get_selected_value(field, condition) {
@@ -382,7 +418,7 @@ frappe.ui.filter_utils = {
}
if (field.df.original_type == 'Check') {
- val = (val=='Yes' ? 1 :0);
+ val = val == 'Yes' ? 1 : 0;
}
if (condition.indexOf('like', 'not like') !== -1) {
@@ -390,12 +426,13 @@ frappe.ui.filter_utils = {
if (val && !(val.startsWith('%') || val.endsWith('%'))) {
val = '%' + val + '%';
}
- } else if (in_list(["in", "not in"], condition)) {
+ } else if (in_list(['in', 'not in'], condition)) {
if (val) {
- val = val.split(',').map(v => strip(v));
+ val = val.split(',').map((v) => strip(v));
}
- } if (val === '%') {
- val = "";
+ }
+ if (val === '%') {
+ val = '';
}
return val;
@@ -404,7 +441,7 @@ frappe.ui.filter_utils = {
get_default_condition(df) {
if (df.fieldtype == 'Data') {
return 'like';
- } else if (df.fieldtype == 'Date' || df.fieldtype == 'Datetime'){
+ } else if (df.fieldtype == 'Date' || df.fieldtype == 'Datetime') {
return 'Between';
} else {
return '=';
@@ -413,44 +450,73 @@ frappe.ui.filter_utils = {
set_fieldtype(df, fieldtype, condition) {
// reset
- if(df.original_type)
- df.fieldtype = df.original_type;
- else
- df.original_type = df.fieldtype;
+ if (df.original_type) df.fieldtype = df.original_type;
+ else df.original_type = df.fieldtype;
- df.description = ''; df.reqd = 0;
+ df.description = '';
+ df.reqd = 0;
df.ignore_link_validation = true;
// given
- if(fieldtype) {
+ if (fieldtype) {
df.fieldtype = fieldtype;
return;
}
// scrub
- if(df.fieldname=="docstatus") {
- df.fieldtype="Select",
- df.options=[
- {value:0, label:__("Draft")},
- {value:1, label:__("Submitted")},
- {value:2, label:__("Cancelled")}
+ if (df.fieldname == 'docstatus') {
+ df.fieldtype = 'Select',
+ df.options = [
+ { value: 0, label: __('Draft') },
+ { value: 1, label: __('Submitted') },
+ { value: 2, label: __('Cancelled') },
];
- } else if(df.fieldtype=='Check') {
- df.fieldtype='Select';
- df.options='No\nYes';
- } else if(['Text','Small Text','Text Editor','Code','Tag','Comments',
- 'Dynamic Link','Read Only','Assign'].indexOf(df.fieldtype)!=-1) {
+ } else if (df.fieldtype == 'Check') {
+ df.fieldtype = 'Select';
+ df.options = 'No\nYes';
+ } else if (
+ [
+ 'Text',
+ 'Small Text',
+ 'Text Editor',
+ 'Code',
+ 'Tag',
+ 'Comments',
+ 'Dynamic Link',
+ 'Read Only',
+ 'Assign',
+ ].indexOf(df.fieldtype) != -1
+ ) {
df.fieldtype = 'Data';
- } else if(df.fieldtype=='Link' && ['=', '!=', 'descendants of', 'ancestors of', 'not descendants of', 'not ancestors of'].indexOf(condition)==-1) {
+ } else if (
+ df.fieldtype == 'Link' &&
+ [
+ '=',
+ '!=',
+ 'descendants of',
+ 'ancestors of',
+ 'not descendants of',
+ 'not ancestors of',
+ ].indexOf(condition) == -1
+ ) {
df.fieldtype = 'Data';
}
- if(df.fieldtype==="Data" && (df.options || "").toLowerCase()==="email") {
+ if (
+ df.fieldtype === 'Data' &&
+ (df.options || '').toLowerCase() === 'email'
+ ) {
df.options = null;
}
- if(condition == "Between" && (df.fieldtype == 'Date' || df.fieldtype == 'Datetime')){
+ if (
+ condition == 'Between' &&
+ (df.fieldtype == 'Date' || df.fieldtype == 'Datetime')
+ ) {
df.fieldtype = 'DateRange';
}
- if (condition == 'Timespan' && ['Date', 'Datetime', 'DateRange', 'Select'].includes(df.fieldtype)) {
+ if (
+ condition == 'Timespan' &&
+ ['Date', 'Datetime', 'DateRange', 'Select'].includes(df.fieldtype)
+ ) {
df.fieldtype = 'Select';
df.options = this.get_timespan_options(['Last', 'Today', 'This', 'Next']);
}
@@ -466,15 +532,15 @@ frappe.ui.filter_utils = {
get_timespan_options(periods) {
const period_map = {
- 'Last': ['Week', 'Month', 'Quarter', '6 months', 'Year'],
- 'Today': null,
- 'This': ['Week', 'Month', 'Quarter', 'Year'],
- 'Next': ['Week', 'Month', 'Quarter', '6 months', 'Year']
+ Last: ['Week', 'Month', 'Quarter', '6 months', 'Year'],
+ Today: null,
+ This: ['Week', 'Month', 'Quarter', 'Year'],
+ Next: ['Week', 'Month', 'Quarter', '6 months', 'Year'],
};
let options = [];
- periods.forEach(period => {
+ periods.forEach((period) => {
if (period_map[period]) {
- period_map[period].forEach(p => {
+ period_map[period].forEach((p) => {
options.push({
label: __(`{0} {1}`, [period, p]),
value: `${period.toLowerCase()} ${p.toLowerCase()}`,
@@ -488,5 +554,5 @@ frappe.ui.filter_utils = {
}
});
return options;
- }
+ },
};