frappe_docker/frappe-bench/sites/assets/js/dialog.min.js
2017-07-31 15:51:51 +05:30

3701 lines
No EOL
104 KiB
JavaScript

frappe.provide('frappe.dom');
frappe.dom = {
id_count: 0,
freeze_count: 0,
by_id: function by_id(id) {
return document.getElementById(id);
},
set_unique_id: function set_unique_id(ele) {
var $ele = $(ele);
if ($ele.attr('id')) {
return $ele.attr('id');
}
var id = 'unique-' + frappe.dom.id_count;
$ele.attr('id', id);
frappe.dom.id_count++;
return id;
},
eval: function _eval(txt) {
if (!txt) return;
var el = document.createElement('script');
el.appendChild(document.createTextNode(txt));
document.getElementsByTagName('head')[0].appendChild(el);
},
remove_script_and_style: function remove_script_and_style(txt) {
var div = document.createElement('div');
div.innerHTML = txt;
var found = false;
["script", "style", "noscript", "title", "meta", "base", "head"].forEach(function (e, i) {
var elements = div.getElementsByTagName(e);
var i = elements.length;
while (i--) {
found = true;
elements[i].parentNode.removeChild(elements[i]);
}
});
var elements = div.getElementsByTagName('link');
var i = elements.length;
while (i--) {
if (elements[i].getAttribute("rel") == "stylesheet") {
found = true;
elements[i].parentNode.removeChild(elements[i]);
}
}
if (found) {
return div.innerHTML;
} else {
return txt;
}
},
is_element_in_viewport: function is_element_in_viewport(el) {
if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0];
}
var rect = el.getBoundingClientRect();
return rect.top >= 0 && rect.left >= 0;
},
set_style: function set_style(txt, id) {
if (!txt) return;
var se = document.createElement('style');
se.type = "text/css";
if (id) {
var element = document.getElementById(id);
if (element) {
element.parentNode.removeChild(element);
}
se.id = id;
}
if (se.styleSheet) {
se.styleSheet.cssText = txt;
} else {
se.appendChild(document.createTextNode(txt));
}
document.getElementsByTagName('head')[0].appendChild(se);
},
add: function add(parent, newtag, className, cs, innerHTML, onclick) {
if (parent && parent.substr) parent = frappe.dom.by_id(parent);
var c = document.createElement(newtag);
if (parent) parent.appendChild(c);
if (className) {
if (newtag.toLowerCase() == 'img') c.src = className;else c.className = className;
}
if (cs) frappe.dom.css(c, cs);
if (innerHTML) c.innerHTML = innerHTML;
if (onclick) c.onclick = onclick;
return c;
},
css: function css(ele, s) {
if (ele && s) {
$.extend(ele.style, s);
}
return ele;
},
freeze: function freeze(msg, css_class) {
if (!$('#freeze').length) {
var freeze = $('<div id="freeze" class="modal-backdrop fade"></div>').on("click", function () {
if (cur_frm && cur_frm.cur_grid) {
cur_frm.cur_grid.toggle_view();
return false;
}
}).appendTo("#body_div");
freeze.html(repl('<div class="freeze-message-container"><div class="freeze-message"><p class="lead">%(msg)s</p></div></div>', { msg: msg || "" }));
setTimeout(function () {
freeze.addClass("in");
}, 1);
} else {
$("#freeze").addClass("in");
}
if (css_class) {
$("#freeze").addClass(css_class);
}
frappe.dom.freeze_count++;
},
unfreeze: function unfreeze() {
if (!frappe.dom.freeze_count) return;
frappe.dom.freeze_count--;
if (!frappe.dom.freeze_count) {
var freeze = $('#freeze').removeClass("in").remove();
}
},
save_selection: function save_selection() {
if (window.getSelection) {
var sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
var ranges = [];
for (var i = 0, len = sel.rangeCount; i < len; ++i) {
ranges.push(sel.getRangeAt(i));
}
return ranges;
}
} else if (document.selection && document.selection.createRange) {
return document.selection.createRange();
}
return null;
},
restore_selection: function restore_selection(savedSel) {
if (savedSel) {
if (window.getSelection) {
var sel = window.getSelection();
sel.removeAllRanges();
for (var i = 0, len = savedSel.length; i < len; ++i) {
sel.addRange(savedSel[i]);
}
} else if (document.selection && savedSel.select) {
savedSel.select();
}
}
},
is_touchscreen: function is_touchscreen() {
return 'ontouchstart' in window;
}
};
frappe.ellipsis = function (text, max) {
if (!max) max = 20;
text = cstr(text);
if (text.length > max) {
text = text.substr(0, max) + '...';
}
return text;
};
frappe.run_serially = function (tasks) {
var result = Promise.resolve();
tasks.forEach(function (task) {
if (task) {
result = result.then ? result.then(task) : Promise.resolve();
}
});
return result;
};
frappe.timeout = function (seconds) {
return new Promise(function (resolve) {
setTimeout(function () {
return resolve();
}, seconds * 1000);
});
};
frappe.scrub = function (text) {
return text.replace(/ /g, "_").toLowerCase();
};
frappe.get_modal = function (title, content) {
return $(frappe.render_template("modal", { title: title, content: content })).appendTo(document.body);
};
(function ($) {
$.fn.add_options = function (options_list) {
for (var i = 0; i < options_list.length; i++) {
var v = options_list[i];
if (is_null(v)) {
var value = null;
var label = null;
} else {
var is_value_null = is_null(v.value);
var is_label_null = is_null(v.label);
if (is_value_null && is_label_null) {
var value = v;
var label = __(v);
} else {
var value = is_value_null ? "" : v.value;
var label = is_label_null ? __(value) : __(v.label);
}
}
$('<option>').html(cstr(label)).attr('value', value).appendTo(this);
}
this.selectedIndex = 0;
return $(this);
};
$.fn.set_working = function () {
this.prop('disabled', true);
};
$.fn.done_working = function () {
this.prop('disabled', false);
};
})(jQuery);
(function ($) {
function pasteIntoInput(el, text) {
el.focus();
if (typeof el.selectionStart == "number") {
var val = el.value;
var selStart = el.selectionStart;
el.value = val.slice(0, selStart) + text + val.slice(el.selectionEnd);
el.selectionEnd = el.selectionStart = selStart + text.length;
} else if (typeof document.selection != "undefined") {
var textRange = document.selection.createRange();
textRange.text = text;
textRange.collapse(false);
textRange.select();
}
}
function allowTabChar(el) {
$(el).keydown(function (e) {
if (e.which == 9) {
pasteIntoInput(this, "\t");
return false;
}
});
$(el).keypress(function (e) {
if (e.which == 9) {
return false;
}
});
}
$.fn.allowTabs = function () {
if (this.jquery) {
this.each(function () {
if (this.nodeType == 1) {
var nodeName = this.nodeName.toLowerCase();
if (nodeName == "textarea" || nodeName == "input" && this.type == "text") {
allowTabChar(this);
}
}
});
}
return this;
};
})(jQuery);frappe.templates['modal'] = '<div class="modal fade" style="overflow: auto;" tabindex="-1"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <div class="row"> <div class="col-xs-7"> <span class="indicator hidden"></span> <h4 class="modal-title" style="font-weight: bold;">{%= title %}</h4> </div> <div class="col-xs-5"> <div class="text-right buttons"> <button type="button" class="btn btn-default btn-sm btn-modal-close" data-dismiss="modal"> <i class="octicon octicon-x visible-xs" style="padding: 1px 0px;"></i> <span class="hidden-xs">{%= __("Close") %}</span></button> <button type="button" class="btn btn-primary btn-sm hide"> {%= __("Confirm") %}</button> </div> </div> </div> </div> <div class="modal-body ui-front">{%= content %} </div> </div> </div> </div> ';
frappe.provide("frappe.form.formatters");
frappe.form.link_formatters = {};
frappe.form.formatters = {
_right: function _right(value, options) {
if (options && options.inline) {
return value;
} else {
return "<div style='text-align: right'>" + value + "</div>";
}
},
Data: function Data(value) {
return value == null ? "" : value;
},
Select: function Select(value) {
return __(frappe.form.formatters["Data"](value));
},
Float: function Float(value, docfield, options, doc) {
var precision = docfield.precision || cint(frappe.boot.sysdefaults.float_precision) || null;
if (docfield.options && docfield.options.trim()) {
docfield.precision = precision;
return frappe.form.formatters.Currency(value, docfield, options, doc);
} else {
if (!(options || {}).always_show_decimals && !is_null(value)) {
var temp = cstr(value).split(".");
if (temp[1] == undefined || cint(temp[1]) === 0) {
precision = 0;
}
}
return frappe.form.formatters._right(value == null || value === "" ? "" : format_number(value, null, precision), options);
}
},
Int: function Int(value, docfield, options) {
return frappe.form.formatters._right(value == null ? "" : cint(value), options);
},
Percent: function Percent(value, docfield, options) {
return frappe.form.formatters._right(flt(value, 2) + "%", options);
},
Currency: function Currency(value, docfield, options, doc) {
var currency = frappe.meta.get_field_currency(docfield, doc);
var precision = docfield.precision || cint(frappe.boot.sysdefaults.currency_precision) || 2;
if (precision > 2) {
var parts = cstr(value).split('.');
var decimals = parts.length > 1 ? parts[1] : '';
if (decimals.length < 3) {
precision = 2;
} else if (decimals.length < precision) {
precision = decimals.length;
}
}
value = value == null || value === "" ? "" : format_currency(value, currency, precision);
if (options && options.only_value) {
return value;
} else {
return frappe.form.formatters._right(value, options);
}
},
Check: function Check(value) {
if (value) {
return '<i class="octicon octicon-check" style="margin-right: 3px;"></i>';
} else {
return '<i class="fa fa-square disabled-check"></i>';
}
},
Link: function Link(value, docfield, options, doc) {
var doctype = docfield._options || docfield.options;
var original_value = value;
if (value && value.match(/^['"].*['"]$/)) {
value.replace(/^.(.*).$/, "$1");
}
if (options && (options.for_print || options.only_value)) {
return value;
}
if (frappe.form.link_formatters[doctype]) {
value = frappe.form.link_formatters[doctype](value, doc);
}
if (!value) {
return "";
}
if (value[0] == "'" && value[value.length - 1] == "'") {
return value.substring(1, value.length - 1);
}
if (docfield && docfield.link_onclick) {
return repl('<a onclick="%(onclick)s">%(value)s</a>', { onclick: docfield.link_onclick.replace(/"/g, '&quot;'), value: value });
} else if (docfield && doctype) {
return repl('<a class="grey" href="#Form/%(doctype)s/%(name)s" data-doctype="%(doctype)s">%(label)s</a>', {
doctype: encodeURIComponent(doctype),
name: encodeURIComponent(original_value),
label: __(options && options.label || value)
});
} else {
return value;
}
},
Date: function Date(value) {
if (value) {
value = frappe.datetime.str_to_user(value);
if (value === "Invalid date") {
value = null;
}
}
return value || "";
},
DateRange: function DateRange(value) {
if ($.isArray(value)) {
return __("{0} to {1}").format([frappe.datetime.str_to_user(value[0]), frappe.datetime.str_to_user(value[1])]);
} else {
return value || "";
}
},
Datetime: function Datetime(value) {
if (value) {
var m = moment(frappe.datetime.convert_to_user_tz(value));
if (frappe.boot.sysdefaults.time_zone) {
m = m.tz(frappe.boot.sysdefaults.time_zone);
}
return m.format(frappe.boot.sysdefaults.date_format.toUpperCase() + ', h:mm a z');
} else {
return "";
}
},
Text: function Text(value) {
if (value) {
var tags = ["<p", "<div", "<br", "<table"];
var match = false;
for (var i = 0; i < tags.length; i++) {
if (value.match(tags[i])) {
match = true;
break;
}
}
if (!match) {
value = replace_newlines(value);
}
}
return frappe.form.formatters.Data(value);
},
LikedBy: function LikedBy(value) {
var html = "";
$.each(JSON.parse(value || "[]"), function (i, v) {
if (v) html += frappe.avatar(v);
});
return html;
},
Tag: function Tag(value) {
var html = "";
$.each((value || "").split(","), function (i, v) {
if (v) html += '<span class="label label-info" \
style="margin-right: 7px; cursor: pointer;"\
data-field="_user_tags" data-label="' + v + '">' + v + '</span>';
});
return html;
},
Comment: function Comment(value) {
var html = "";
$.each(JSON.parse(value || "[]"), function (i, v) {
if (v) html += '<span class="label label-warning" \
style="margin-right: 7px;"\
data-field="_comments" data-label="' + v.name + '">' + v.comment + '</span>';
});
return html;
},
Assign: function Assign(value) {
var html = "";
$.each(JSON.parse(value || "[]"), function (i, v) {
if (v) html += '<span class="label label-warning" \
style="margin-right: 7px;"\
data-field="_assign">' + v + '</span>';
});
return html;
},
SmallText: function SmallText(value) {
return frappe.form.formatters.Text(value);
},
TextEditor: function TextEditor(value) {
return frappe.form.formatters.Text(value);
},
Code: function Code(value) {
return "<pre>" + (value == null ? "" : $("<div>").text(value).html()) + "</pre>";
},
WorkflowState: function WorkflowState(value) {
var workflow_state = frappe.get_doc("Workflow State", value);
if (workflow_state) {
return repl("<span class='label label-%(style)s' \
data-workflow-state='%(value)s'\
style='padding-bottom: 4px; cursor: pointer;'>\
<i class='fa fa-small fa-white fa-%(icon)s'></i> %(value)s</span>", {
value: value,
style: workflow_state.style.toLowerCase(),
icon: workflow_state.icon
});
} else {
return "<span class='label'>" + value + "</span>";
}
},
Email: function Email(value) {
return $("<div></div>").text(value).html();
}
};
frappe.form.get_formatter = function (fieldtype) {
if (!fieldtype) fieldtype = "Data";
return frappe.form.formatters[fieldtype.replace(/ /g, "")] || frappe.form.formatters.Data;
};
frappe.format = function (value, df, options, doc) {
if (!df) df = { "fieldtype": "Data" };
var fieldtype = df.fieldtype || "Data";
if (fieldtype === "Dynamic Link") {
fieldtype = "Link";
df._options = doc ? doc[df.options] : null;
}
var formatter = df.formatter || frappe.form.get_formatter(fieldtype);
var formatted = formatter(value, df, options, doc);
if (typeof formatted == "string") formatted = frappe.dom.remove_script_and_style(formatted);
return formatted;
};
frappe.get_format_helper = function (doc) {
var helper = {
get_formatted: function get_formatted(fieldname) {
var df = frappe.meta.get_docfield(doc.doctype, fieldname);
if (!df) {
console.log("fieldname not found: " + fieldname);
}
return frappe.format(doc[fieldname], df, { inline: 1 }, doc);
}
};
$.extend(helper, doc);
return helper;
};
frappe.provide("frappe.ui.form");
frappe.ui.form.Layout = Class.extend({
init: function init(opts) {
this.views = {};
this.pages = [];
this.sections = [];
this.fields_list = [];
this.fields_dict = {};
$.extend(this, opts);
},
make: function make() {
if (!this.parent && this.body) {
this.parent = this.body;
}
this.wrapper = $('<div class="form-layout">').appendTo(this.parent);
this.message = $('<div class="form-message text-muted small hidden"></div>').appendTo(this.wrapper);
if (!this.fields) {
this.fields = frappe.meta.sort_docfields(frappe.meta.docfield_map[this.doctype]);
}
this.setup_tabbing();
this.render();
},
show_empty_form_message: function show_empty_form_message() {
if (!(this.wrapper.find(".frappe-control:visible").length || this.wrapper.find(".section-head.collapsed").length)) {
this.show_message(__("This form does not have any input"));
}
},
show_message: function show_message(html) {
if (html) {
if (html.substr(0, 1) !== '<') {
html = '<div>' + html + '</div>';
}
$(html).appendTo(this.message.removeClass('hidden'));
} else {
this.message.empty().addClass('hidden');
}
},
render: function render(new_fields) {
var me = this;
var fields = new_fields || this.fields;
this.section = null;
this.column = null;
if (this.with_dashboard) {
this.setup_dashboard_section();
}
if (this.no_opening_section()) {
this.make_section();
}
$.each(fields, function (i, df) {
switch (df.fieldtype) {
case "Fold":
me.make_page(df);
break;
case "Section Break":
me.make_section(df);
break;
case "Column Break":
me.make_column(df);
break;
default:
me.make_field(df);
}
});
},
no_opening_section: function no_opening_section() {
return this.fields[0] && this.fields[0].fieldtype != "Section Break" || !this.fields.length;
},
setup_dashboard_section: function setup_dashboard_section() {
if (this.no_opening_section()) {
this.fields.unshift({ fieldtype: 'Section Break' });
}
this.fields.unshift({
fieldtype: 'Section Break',
fieldname: '_form_dashboard',
label: __('Dashboard'),
cssClass: 'form-dashboard',
collapsible: 1
});
},
make_field: function make_field(df, colspan) {
var render = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
!this.section && this.make_section();
!this.column && this.make_column();
var fieldobj = frappe.ui.form.make_control({
df: df,
doctype: this.doctype,
parent: this.column.wrapper.get(0),
frm: this.frm,
render_input: render
});
fieldobj.layout = this;
this.fields_list.push(fieldobj);
this.fields_dict[df.fieldname] = fieldobj;
if (this.frm) {
fieldobj.perm = this.frm.perm;
}
this.section.fields_list.push(fieldobj);
this.section.fields_dict[df.fieldname] = fieldobj;
},
make_page: function make_page(df) {
var me = this,
head = $('<div class="form-clickable-section text-center">\
<a class="btn-fold h6 text-muted">' + __("Show more details") + '</a>\
</div>').appendTo(this.wrapper);
this.page = $('<div class="form-page second-page hide"></div>').appendTo(this.wrapper);
this.fold_btn = head.find(".btn-fold").on("click", function () {
var page = $(this).parent().next();
if (page.hasClass("hide")) {
$(this).removeClass("btn-fold").html(__("Hide details"));
page.removeClass("hide");
frappe.utils.scroll_to($(this), true, 30);
me.folded = false;
} else {
$(this).addClass("btn-fold").html(__("Show more details"));
page.addClass("hide");
me.folded = true;
}
});
this.section = null;
this.folded = true;
},
unfold: function unfold() {
this.fold_btn.trigger('click');
},
make_section: function make_section(df) {
this.section = new frappe.ui.form.Section(this, df);
if (df) {
this.fields_dict[df.fieldname] = this.section;
this.fields_list.push(this.section);
}
this.column = null;
},
make_column: function make_column(df) {
this.column = new frappe.ui.form.Column(this.section, df);
if (df && df.fieldname) {
this.fields_list.push(this.column);
}
},
refresh: function refresh(doc) {
var me = this;
if (doc) this.doc = doc;
if (this.frm) {
this.wrapper.find(".empty-form-alert").remove();
}
me.attach_doc_and_docfields(true);
if (this.frm && this.frm.wrapper) {
$(this.frm.wrapper).trigger("refresh-fields");
}
this.refresh_dependency();
this.refresh_sections();
if (this.frm) {
this.refresh_section_collapse();
}
},
refresh_sections: function refresh_sections() {
var cnt = 0;
this.wrapper.find(".form-section:not(.hide-control)").each(function () {
var $this = $(this).removeClass("empty-section").removeClass("visible-section").removeClass("shaded-section");
if (!$this.find(".frappe-control:not(.hide-control)").length && !$this.hasClass('form-dashboard')) {
$this.addClass("empty-section");
} else {
$this.addClass("visible-section");
if (cnt % 2) {
$this.addClass("shaded-section");
}
cnt++;
}
});
},
refresh_section_collapse: function refresh_section_collapse() {
if (!this.doc) return;
for (var i = 0; i < this.sections.length; i++) {
var section = this.sections[i];
var df = section.df;
if (df && df.collapsible) {
var collapse = true;
if (df.collapsible_depends_on) {
collapse = !this.evaluate_depends_on_value(df.collapsible_depends_on);
}
if (collapse && section.has_missing_mandatory()) {
collapse = false;
}
if (df.fieldname === '_form_dashboard') {
collapse = false;
}
section.collapse(collapse);
}
}
},
attach_doc_and_docfields: function attach_doc_and_docfields(refresh) {
var me = this;
for (var i = 0, l = this.fields_list.length; i < l; i++) {
var fieldobj = this.fields_list[i];
if (me.doc) {
fieldobj.doc = me.doc;
fieldobj.doctype = me.doc.doctype;
fieldobj.docname = me.doc.name;
fieldobj.df = frappe.meta.get_docfield(me.doc.doctype, fieldobj.df.fieldname, me.frm ? me.frm.doc.name : me.doc.name) || fieldobj.df;
if (me.frm) {
fieldobj.perm = me.frm.perm;
}
}
refresh && fieldobj.refresh && fieldobj.refresh();
}
},
refresh_section_count: function refresh_section_count() {
this.wrapper.find(".section-count-label:visible").each(function (i) {
$(this).html(i + 1);
});
},
setup_tabbing: function setup_tabbing() {
var me = this;
this.wrapper.on("keydown", function (ev) {
if (ev.which == 9) {
var current = $(ev.target),
doctype = current.attr("data-doctype"),
fieldname = current.attr("data-fieldname");
if (doctype) return me.handle_tab(doctype, fieldname, ev.shiftKey);
}
});
},
handle_tab: function handle_tab(doctype, fieldname, shift) {
var me = this,
grid_row = null,
prev = null,
fields = me.fields_list,
in_grid = false,
focused = false;
if (doctype != me.doctype) {
grid_row = me.get_open_grid_row();
if (!grid_row || !grid_row.layout) {
return;
}
fields = grid_row.layout.fields_list;
}
for (var i = 0, len = fields.length; i < len; i++) {
if (fields[i].df.fieldname == fieldname) {
if (shift) {
if (prev) {
this.set_focus(prev);
} else {
$(this.primary_button).focus();
}
break;
}
if (i < len - 1) {
focused = me.focus_on_next_field(i, fields);
}
if (focused) {
break;
}
}
if (this.is_visible(fields[i])) prev = fields[i];
}
if (!focused) {
if (grid_row) {
if (grid_row.doc.idx == grid_row.grid.grid_rows.length) {
grid_row.toggle_view(false, function () {
grid_row.grid.frm.layout.handle_tab(grid_row.grid.df.parent, grid_row.grid.df.fieldname);
});
} else {
grid_row.grid.grid_rows[grid_row.doc.idx].toggle_view(true);
}
} else {
$(this.primary_button).focus();
}
}
return false;
},
focus_on_next_field: function focus_on_next_field(start_idx, fields) {
for (var i = start_idx + 1, len = fields.length; i < len; i++) {
var field = fields[i];
if (this.is_visible(field)) {
if (field.df.fieldtype === "Table") {
if (!(field.grid.grid_rows && field.grid.grid_rows.length)) {
field.grid.add_new_row();
}
field.grid.grid_rows[0].show_form();
return true;
} else if (!in_list(frappe.model.no_value_type, field.df.fieldtype)) {
this.set_focus(field);
return true;
}
}
}
},
is_visible: function is_visible(field) {
return field.disp_status === "Write" && field.$wrapper && field.$wrapper.is(":visible");
},
set_focus: function set_focus(field) {
if (field.df.fieldtype == "Table") {
if (!field.grid.grid_rows.length) {
field.grid.add_new_row(1);
} else {
field.grid.grid_rows[0].toggle_view(true);
}
} else if (field.editor) {
field.editor.set_focus();
} else if (field.$input) {
field.$input.focus();
}
},
get_open_grid_row: function get_open_grid_row() {
return $(".grid-row-open").data("grid_row");
},
refresh_dependency: function refresh_dependency() {
var me = this;
var has_dep = false;
for (var fkey in this.fields_list) {
var f = this.fields_list[fkey];
f.dependencies_clear = true;
if (f.df.depends_on) {
has_dep = true;
}
}
if (!has_dep) return;
for (var i = me.fields_list.length - 1; i >= 0; i--) {
var f = me.fields_list[i];
f.guardian_has_value = true;
if (f.df.depends_on) {
f.guardian_has_value = this.evaluate_depends_on_value(f.df.depends_on);
if (f.guardian_has_value) {
if (f.df.hidden_due_to_dependency) {
f.df.hidden_due_to_dependency = false;
f.refresh();
}
} else {
if (!f.df.hidden_due_to_dependency) {
f.df.hidden_due_to_dependency = true;
f.refresh();
}
}
}
}
this.refresh_section_count();
},
evaluate_depends_on_value: function evaluate_depends_on_value(expression) {
var out = null;
var doc = this.doc;
if (!doc && this.get_values) {
var doc = this.get_values(true);
}
if (!doc) {
return;
}
var parent = this.frm ? this.frm.doc : null;
if (expression.substr(0, 5) == 'eval:') {
out = eval(expression.substr(5));
} else if (expression.substr(0, 3) == 'fn:' && this.frm) {
out = this.frm.script_manager.trigger(expression.substr(3), this.doctype, this.docname);
} else {
var value = doc[expression];
if ($.isArray(value)) {
out = !!value.length;
} else {
out = !!value;
}
}
return out;
}
});
frappe.ui.form.Section = Class.extend({
init: function init(layout, df) {
var me = this;
this.layout = layout;
this.df = df || {};
this.fields_list = [];
this.fields_dict = {};
this.make();
this.row = {
wrapper: this.wrapper
};
if (this.df.collapsible) {
this.collapse(true);
}
this.refresh();
},
make: function make() {
if (!this.layout.page) {
this.layout.page = $('<div class="form-page"></div>').appendTo(this.layout.wrapper);
}
this.wrapper = $('<div class="row form-section">').appendTo(this.layout.page);
this.layout.sections.push(this);
if (this.df) {
if (this.df.label) {
this.make_head();
}
if (this.df.description) {
$('<div class="col-sm-12 small text-muted form-section-description">' + __(this.df.description) + '</div>').appendTo(this.wrapper);
}
if (this.df.cssClass) {
this.wrapper.addClass(this.df.cssClass);
}
}
this.body = $('<div class="section-body">').appendTo(this.wrapper);
},
make_head: function make_head() {
var me = this;
if (!this.df.collapsible) {
$('<div class="col-sm-12"><h6 class="form-section-heading uppercase">' + __(this.df.label) + '</h6></div>').appendTo(this.wrapper);
} else {
this.head = $('<div class="section-head"><a class="h6 uppercase">' + __(this.df.label) + '</a><span class="octicon octicon-chevron-down collapse-indicator"></span></div>').appendTo(this.wrapper);
this.collapse_link = this.head.on("click", function () {
me.collapse();
});
this.indicator = this.head.find(".collapse-indicator");
}
},
refresh: function refresh() {
if (!this.df) return;
var hide = this.df.hidden || this.df.hidden_due_to_dependency;
if (!hide && this.layout && this.layout.frm && !this.layout.frm.get_perm(this.df.permlevel || 0, "read")) {
hide = true;
}
this.wrapper.toggleClass("hide-control", !!hide);
},
collapse: function collapse(hide) {
if (!(this.head && this.body)) {
return;
}
if (hide === undefined) {
hide = !this.body.hasClass("hide");
}
this.body.toggleClass("hide", hide);
this.head.toggleClass("collapsed", hide);
this.indicator.toggleClass("octicon-chevron-down", hide);
this.indicator.toggleClass("octicon-chevron-up", !hide);
},
has_missing_mandatory: function has_missing_mandatory() {
var missing_mandatory = false;
for (var j = 0, l = this.fields_list.length; j < l; j++) {
var section_df = this.fields_list[j].df;
if (section_df.reqd && this.layout.doc[section_df.fieldname] == null) {
missing_mandatory = true;
break;
}
}
return missing_mandatory;
}
});
frappe.ui.form.Column = Class.extend({
init: function init(section, df) {
if (!df) df = {};
this.df = df;
this.section = section;
this.make();
this.resize_all_columns();
},
make: function make() {
this.wrapper = $('<div class="form-column">\
<form>\
</form>\
</div>').appendTo(this.section.body).find("form").on("submit", function () {
return false;
});
if (this.df.label) {
$('<label class="control-label">' + __(this.df.label) + '</label>').appendTo(this.wrapper);
}
},
resize_all_columns: function resize_all_columns() {
var colspan = cint(12 / this.section.wrapper.find(".form-column").length);
this.section.wrapper.find(".form-column").removeClass().addClass("form-column").addClass("col-sm-" + colspan);
},
refresh: function refresh() {
this.section.refresh();
}
});
frappe.provide('frappe.ui');
frappe.ui.FieldGroup = frappe.ui.form.Layout.extend({
init: function init(opts) {
$.extend(this, opts);
this._super();
$.each(this.fields || [], function (i, f) {
if (!f.fieldname && f.label) {
f.fieldname = f.label.replace(/ /g, "_").toLowerCase();
}
});
if (this.values) {
this.set_values(this.values);
}
},
make: function make() {
var me = this;
if (this.fields) {
this._super();
this.refresh();
$.each(this.fields_list, function (i, field) {
if (field.df["default"]) {
field.set_input(field.df["default"]);
}
});
if (!this.no_submit_on_enter) {
this.catch_enter_as_submit();
}
$(this.body).find('input').on('change', function () {
me.refresh_dependency();
});
$(this.body).find('select').on("change", function () {
me.refresh_dependency();
});
}
},
add_fields: function add_fields(fields) {
this.render(fields);
this.refresh_fields(fields);
},
refresh_fields: function refresh_fields(fields) {
var fieldnames = fields.map(function (field) {
if (field.fieldname) return field.fieldname;
});
this.fields_list.map(function (fieldobj) {
if (fieldnames.includes(fieldobj.df.fieldname)) {
fieldobj.refresh();
if (fieldobj.df["default"]) {
fieldobj.set_input(fieldobj.df["default"]);
}
}
});
},
first_button: false,
catch_enter_as_submit: function catch_enter_as_submit() {
var me = this;
$(this.body).find('input[type="text"], input[type="password"]').keypress(function (e) {
if (e.which == 13) {
if (me.has_primary_action) {
e.preventDefault();
me.get_primary_btn().trigger("click");
}
}
});
},
get_input: function get_input(fieldname) {
var field = this.fields_dict[fieldname];
return $(field.txt ? field.txt : field.input);
},
get_field: function get_field(fieldname) {
return this.fields_dict[fieldname];
},
get_values: function get_values(ignore_errors) {
var ret = {};
var errors = [];
for (var key in this.fields_dict) {
var f = this.fields_dict[key];
if (f.get_value) {
var v = f.get_value();
if (f.df.reqd && is_null(v)) errors.push(__(f.df.label));
if (!is_null(v)) ret[f.df.fieldname] = v;
}
}
if (errors.length && !ignore_errors) {
frappe.msgprint({
title: __('Missing Values Required'),
message: __('Following fields have missing values:') + '<br><br><ul><li>' + errors.join('<li>') + '</ul>',
indicator: 'orange'
});
return null;
}
return ret;
},
get_value: function get_value(key) {
var f = this.fields_dict[key];
return f && (f.get_value ? f.get_value() : null);
},
set_value: function set_value(key, val) {
var _this = this;
return new Promise(function (resolve) {
var f = _this.fields_dict[key];
if (f) {
f.set_value(val).then(function () {
f.set_input(val);
_this.refresh_dependency();
resolve();
});
} else {
resolve();
}
});
},
set_input: function set_input(key, val) {
return this.set_value(key, val);
},
set_values: function set_values(dict) {
for (var key in dict) {
if (this.fields_dict[key]) {
this.set_value(key, dict[key]);
}
}
},
clear: function clear() {
for (var key in this.fields_dict) {
var f = this.fields_dict[key];
if (f && f.set_input) {
f.set_input(f.df['default'] || '');
}
}
}
});
frappe.ui.form.make_control = function (opts) {
var control_class_name = "Control" + opts.df.fieldtype.replace(/ /g, "");
if (frappe.ui.form[control_class_name]) {
return new frappe.ui.form[control_class_name](opts);
} else {
console.log("Invalid Control Name: " + opts.df.fieldtype);
}
};
frappe.ui.form.Control = Class.extend({
init: function init(opts) {
$.extend(this, opts);
this.make();
if (frappe.boot.user && frappe.boot.user.name === "Administrator" && frappe.boot.developer_mode === 1 && this.$wrapper) {
this.$wrapper.attr("title", __(this.df.fieldname));
}
if (this.render_input) {
this.refresh();
}
},
make: function make() {
this.make_wrapper();
this.$wrapper.attr("data-fieldtype", this.df.fieldtype).attr("data-fieldname", this.df.fieldname);
this.wrapper = this.$wrapper.get(0);
this.wrapper.fieldobj = this;
},
make_wrapper: function make_wrapper() {
this.$wrapper = $("<div class='frappe-control'></div>").appendTo(this.parent);
this.wrapper = this.$wrapper;
},
toggle: function toggle(show) {
this.df.hidden = show ? 0 : 1;
this.refresh();
},
get_status: function get_status(explain) {
if (!this.doctype && !this.docname) {
if (cint(this.df.hidden)) {
if (explain) console.log("By Hidden: None");
return "None";
} else if (cint(this.df.hidden_due_to_dependency)) {
if (explain) console.log("By Hidden Dependency: None");
return "None";
} else if (cint(this.df.read_only)) {
if (explain) console.log("By Read Only: Read");
return "Read";
}
return "Write";
}
var status = frappe.perm.get_field_display_status(this.df, frappe.model.get_doc(this.doctype, this.docname), this.perm || this.frm && this.frm.perm, explain);
if (this.doctype && status === "Read" && !this.only_input && is_null(frappe.model.get_value(this.doctype, this.docname, this.df.fieldname)) && !in_list(["HTML", "Image"], this.df.fieldtype)) {
if (explain) console.log("By Hide Read-only, null fields: None");
status = "None";
}
return status;
},
refresh: function refresh() {
this.disp_status = this.get_status();
this.$wrapper && this.$wrapper.toggleClass("hide-control", this.disp_status == "None") && this.refresh_input && this.refresh_input();
},
get_doc: function get_doc() {
return this.doctype && this.docname && locals[this.doctype] && locals[this.doctype][this.docname] || {};
},
get_model_value: function get_model_value() {
if (this.doc) {
return this.doc[this.df.fieldname];
}
},
set_value: function set_value(value) {
return this.validate_and_set_in_model(value);
},
parse_validate_and_set_in_model: function parse_validate_and_set_in_model(value, e) {
if (this.parse) {
value = this.parse(value);
}
return this.validate_and_set_in_model(value, e);
},
validate_and_set_in_model: function validate_and_set_in_model(value, e) {
var me = this;
if (this.inside_change_event) {
return new Promise.resolve();
}
this.inside_change_event = true;
var set = function set(value) {
me.inside_change_event = false;
return frappe.run_serially([function () {
return me.set_model_value(value);
}, function () {
me.set_mandatory && me.set_mandatory(value);
if (me.df.change || me.df.onchange) {
return (me.df.change || me.df.onchange).apply(me, [e]);
}
}]);
};
value = this.validate(value);
if (value && value.then) {
return value.then(function (value) {
return set(value);
});
} else {
return set(value);
}
},
get_value: function get_value() {
if (this.get_status() === 'Write') {
return this.get_input_value ? this.parse ? this.parse(this.get_input_value()) : this.get_input_value() : undefined;
} else if (this.get_status() === 'Read') {
return this.value || undefined;
} else {
return undefined;
}
},
set_model_value: function set_model_value(value) {
if (this.doctype && this.docname) {
this.last_value = value;
return frappe.model.set_value(this.doctype, this.docname, this.df.fieldname, value, this.df.fieldtype);
} else {
if (this.doc) {
this.doc[this.df.fieldname] = value;
}
this.set_input(value);
return Promise.resolve();
}
},
set_focus: function set_focus() {
if (this.$input) {
this.$input.get(0).focus();
return true;
}
}
});
frappe.ui.form.ControlHTML = frappe.ui.form.Control.extend({
make: function make() {
this._super();
this.disp_area = this.wrapper;
},
refresh_input: function refresh_input() {
var content = this.get_content();
if (content) this.$wrapper.html(content);
},
get_content: function get_content() {
return this.df.options || "";
},
html: function html(_html) {
this.$wrapper.html(_html || this.get_content());
},
set_value: function set_value(html) {
if (html.appendTo) {
html.appendTo(this.$wrapper.empty());
} else {
this.df.options = html;
this.html(html);
}
}
});
frappe.ui.form.ControlHeading = frappe.ui.form.ControlHTML.extend({
get_content: function get_content() {
return "<h4>" + __(this.df.label) + "</h4>";
}
});
frappe.ui.form.ControlImage = frappe.ui.form.Control.extend({
make: function make() {
this._super();
var me = this;
this.$wrapper.css({ "margin": "0px" });
this.$body = $("<div></div>").appendTo(this.$wrapper).css({ "margin-bottom": "10px" });
$('<div class="clearfix"></div>').appendTo(this.$wrapper);
},
refresh_input: function refresh_input() {
this.$body.empty();
var doc = this.get_doc();
if (doc && this.df.options && doc[this.df.options]) {
this.$img = $("<img src='" + doc[this.df.options] + "' class='img-responsive'>").appendTo(this.$body);
} else {
this.$buffer = $("<div class='missing-image'><i class='octicon octicon-circle-slash'></i></div>").appendTo(this.$body);
}
return false;
}
});
frappe.ui.form.ControlInput = frappe.ui.form.Control.extend({
horizontal: true,
make: function make() {
this._super();
this.set_input_areas();
this.set_max_width();
},
make_wrapper: function make_wrapper() {
if (this.only_input) {
this.$wrapper = $('<div class="form-group frappe-control">').appendTo(this.parent);
} else {
this.$wrapper = $('<div class="frappe-control">\
<div class="form-group">\
<div class="clearfix">\
<label class="control-label" style="padding-right: 0px;"></label>\
</div>\
<div class="control-input-wrapper">\
<div class="control-input"></div>\
<div class="control-value like-disabled-input" style="display: none;"></div>\
<p class="help-box small text-muted hidden-xs"></p>\
</div>\
</div>\
</div>').appendTo(this.parent);
}
},
toggle_label: function toggle_label(show) {
this.$wrapper.find(".control-label").toggleClass("hide", !show);
},
toggle_description: function toggle_description(show) {
this.$wrapper.find(".help-box").toggleClass("hide", !show);
},
set_input_areas: function set_input_areas() {
if (this.only_input) {
this.input_area = this.wrapper;
} else {
this.label_area = this.label_span = this.$wrapper.find("label").get(0);
this.input_area = this.$wrapper.find(".control-input").get(0);
this.disp_area = this.$wrapper.find(".control-value").get(0);
}
},
set_max_width: function set_max_width() {
if (this.horizontal) {
this.$wrapper.addClass("input-max-width");
}
},
refresh_input: function refresh_input() {
var me = this;
var make_input = function make_input() {
if (!me.has_input) {
me.make_input();
if (me.df.on_make) {
me.df.on_make(me);
}
}
};
var update_input = function update_input() {
if (me.doctype && me.docname) {
me.set_input(me.value);
} else {
me.set_input(me.value || null);
}
};
if (me.disp_status != "None") {
if (me.doctype && me.docname) {
me.value = frappe.model.get_value(me.doctype, me.docname, me.df.fieldname);
}
if (me.disp_status == "Write") {
me.disp_area && $(me.disp_area).toggle(false);
$(me.input_area).toggle(true);
me.$input && me.$input.prop("disabled", false);
make_input();
update_input();
} else {
if (me.only_input) {
make_input();
update_input();
} else {
$(me.input_area).toggle(false);
if (me.disp_area) {
me.set_disp_area(me.value);
$(me.disp_area).toggle(true);
}
}
me.$input && me.$input.prop("disabled", true);
}
me.set_description();
me.set_label();
me.set_mandatory(me.value);
me.set_bold();
}
},
set_disp_area: function set_disp_area(value) {
if (in_list(["Currency", "Int", "Float"], this.df.fieldtype) && (this.value === 0 || value === 0)) {
value = 0;
} else {
value = this.value || value;
}
this.disp_area && $(this.disp_area).html(frappe.format(value, this.df, { no_icon: true, inline: true }, this.doc || this.frm && this.frm.doc));
},
bind_change_event: function bind_change_event() {
var me = this;
this.$input && this.$input.on("change", this.change || function (e) {
me.parse_validate_and_set_in_model(me.get_input_value(), e);
});
},
bind_focusout: function bind_focusout() {
if (frappe.dom.is_touchscreen()) {
var me = this;
this.$input && this.$input.on("focusout", function () {
if (frappe.dom.is_touchscreen()) {
frappe.utils.scroll_to(me.$wrapper);
}
});
}
},
set_label: function set_label(label) {
if (label) this.df.label = label;
if (this.only_input || this.df.label == this._label) return;
var icon = "";
this.label_span.innerHTML = (icon ? '<i class="' + icon + '"></i> ' : "") + __(this.df.label) || "&nbsp;";
this._label = this.df.label;
},
set_description: function set_description() {
if (this.only_input || this.df.description === this._description) return;
if (this.df.description) {
this.$wrapper.find(".help-box").html(__(this.df.description));
} else {
this.set_empty_description();
}
this._description = this.df.description;
},
set_new_description: function set_new_description(description) {
this.$wrapper.find(".help-box").html(description);
},
set_empty_description: function set_empty_description() {
this.$wrapper.find(".help-box").html("");
},
set_mandatory: function set_mandatory(value) {
this.$wrapper.toggleClass("has-error", this.df.reqd && is_null(value) ? true : false);
},
set_bold: function set_bold() {
if (this.$input) {
this.$input.toggleClass("bold", !!(this.df.bold || this.df.reqd));
}
if (this.disp_area) {
$(this.disp_area).toggleClass("bold", !!(this.df.bold || this.df.reqd));
}
}
});
frappe.ui.form.ControlData = frappe.ui.form.ControlInput.extend({
html_element: "input",
input_type: "text",
make_input: function make_input() {
if (this.$input) return;
this.$input = $("<" + this.html_element + ">").attr("type", this.input_type).attr("autocomplete", "off").addClass("input-with-feedback form-control").prependTo(this.input_area);
if (in_list(['Data', 'Link', 'Dynamic Link', 'Password', 'Select', 'Read Only', 'Attach', 'Attach Image'], this.df.fieldtype)) {
this.$input.attr("maxlength", this.df.length || 140);
}
this.set_input_attributes();
this.input = this.$input.get(0);
this.has_input = true;
this.bind_change_event();
this.bind_focusout();
},
set_input_attributes: function set_input_attributes() {
this.$input.attr("data-fieldtype", this.df.fieldtype).attr("data-fieldname", this.df.fieldname).attr("placeholder", this.df.placeholder || "");
if (this.doctype) {
this.$input.attr("data-doctype", this.doctype);
}
if (this.df.input_css) {
this.$input.css(this.df.input_css);
}
if (this.df.input_class) {
this.$input.addClass(this.df.input_class);
}
},
set_input: function set_input(value) {
this.last_value = this.value;
this.value = value;
this.set_formatted_input(value);
this.set_disp_area(value);
this.set_mandatory && this.set_mandatory(value);
},
set_formatted_input: function set_formatted_input(value) {
this.$input && this.$input.val(this.format_for_input(value));
},
get_input_value: function get_input_value() {
return this.$input ? this.$input.val() : undefined;
},
format_for_input: function format_for_input(val) {
return val == null ? "" : val;
},
validate: function validate(v) {
if (this.df.options == 'Phone') {
if (v + '' == '') {
return '';
}
var v1 = '';
v = v.replace(/ /g, '').replace(/-/g, '').replace(/\(/g, '').replace(/\)/g, '');
if (v && v.substr(0, 1) == '+') {
v1 = '+';v = v.substr(1);
}
if (v && v.substr(0, 2) == '00') {
v1 += '00';v = v.substr(2);
}
if (v && v.substr(0, 1) == '0') {
v1 += '0';v = v.substr(1);
}
v1 += cint(v) + '';
return v1;
} else if (this.df.options == 'Email') {
if (v + '' == '') {
return '';
}
var email_list = frappe.utils.split_emails(v);
if (!email_list) {
return '';
} else {
var invalid_email = false;
email_list.forEach(function (email) {
if (!validate_email(email)) {
frappe.msgprint(__("Invalid Email: {0}", [email]));
invalid_email = true;
}
});
if (invalid_email) {
return '';
} else {
return v;
}
}
} else {
return v;
}
}
});
frappe.ui.form.ControlReadOnly = frappe.ui.form.ControlData.extend({
get_status: function get_status(explain) {
var status = this._super(explain);
if (status === "Write") status = "Read";
return;
}
});
frappe.ui.form.ControlPassword = frappe.ui.form.ControlData.extend({
input_type: "password",
make: function make() {
this._super();
},
make_input: function make_input() {
var _this = this;
var me = this;
this._super();
this.$input.parent().append($('<span class="password-strength-indicator indicator"></span>'));
this.$wrapper.find('.control-input-wrapper').append($('<p class="password-strength-message text-muted small hidden"></p>'));
this.indicator = this.$wrapper.find('.password-strength-indicator');
this.message = this.$wrapper.find('.help-box');
this.$input.on('input', function () {
var $this = $(_this);
clearTimeout($this.data('timeout'));
$this.data('timeout', setTimeout(function () {
var txt = me.$input.val();
me.get_password_strength(txt);
}), 300);
});
},
get_password_strength: function get_password_strength(value) {
var me = this;
frappe.call({
type: 'GET',
method: 'frappe.core.doctype.user.user.test_password_strength',
args: {
new_password: value || ''
},
callback: function callback(r) {
if (r.message && r.message.entropy) {
var score = r.message.score,
feedback = r.message.feedback;
feedback.crack_time_display = r.message.crack_time_display;
var indicators = ['grey', 'red', 'orange', 'yellow', 'green'];
me.set_strength_indicator(indicators[score]);
}
}
});
},
set_strength_indicator: function set_strength_indicator(color) {
var message = __("Include symbols, numbers and capital letters in the password");
this.indicator.removeClass().addClass('password-strength-indicator indicator ' + color);
this.message.html(message).removeClass('hidden');
}
});
frappe.ui.form.ControlInt = frappe.ui.form.ControlData.extend({
make: function make() {
this._super();
},
make_input: function make_input() {
var me = this;
this._super();
this.$input.on("focus", function () {
setTimeout(function () {
if (!document.activeElement) return;
document.activeElement.value = me.validate(document.activeElement.value);
document.activeElement.select();
}, 100);
return false;
});
},
parse: function parse(value) {
return cint(value, null);
}
});
frappe.ui.form.ControlFloat = frappe.ui.form.ControlInt.extend({
parse: function parse(value) {
return isNaN(parseFloat(value)) ? null : flt(value, this.get_precision());
},
format_for_input: function format_for_input(value) {
var number_format;
if (this.df.fieldtype === "Float" && this.df.options && this.df.options.trim()) {
number_format = this.get_number_format();
}
var formatted_value = format_number(parseFloat(value), number_format, this.get_precision());
return isNaN(parseFloat(value)) ? "" : formatted_value;
},
get_number_format: function (_get_number_format) {
function get_number_format() {
return _get_number_format.apply(this, arguments);
}
get_number_format.toString = function () {
return _get_number_format.toString();
};
return get_number_format;
}(function () {
var currency = frappe.meta.get_field_currency(this.df, this.get_doc());
return get_number_format(currency);
}),
get_precision: function get_precision() {
return this.df.precision || cint(frappe.boot.sysdefaults.float_precision, null);
}
});
frappe.ui.form.ControlCurrency = frappe.ui.form.ControlFloat.extend({
format_for_input: function format_for_input(value) {
var formatted_value = format_number(parseFloat(value), this.get_number_format(), this.get_precision());
return isNaN(parseFloat(value)) ? "" : formatted_value;
},
get_precision: function get_precision() {
if (!this.df.precision) {
if (frappe.boot.sysdefaults.currency_precision) {
this.df.precision = frappe.boot.sysdefaults.currency_precision;
} else {
this.df.precision = get_number_format_info(this.get_number_format()).precision;
}
}
return this.df.precision;
}
});
frappe.ui.form.ControlPercent = frappe.ui.form.ControlFloat;
frappe.ui.form.ControlColor = frappe.ui.form.ControlData.extend({
make_input: function make_input() {
this._super();
this.colors = ["#ffc4c4", "#ff8989", "#ff4d4d", "#a83333", "#ffe8cd", "#ffd19c", "#ffb868", "#a87945", "#ffd2c2", "#ffa685", "#ff7846", "#a85b5b", "#ffd7d7", "#ffb1b1", "#ff8989", "#a84f2e", "#fffacd", "#fff168", "#fff69c", "#a89f45", "#ebf8cc", "#d9f399", "#c5ec63", "#7b933d", "#cef6d1", "#9deca2", "#6be273", "#428b46", "#d2f8ed", "#a4f3dd", "#77ecca", "#49937e", "#d2f1ff", "#a6e4ff", "#78d6ff", "#4f8ea8", "#d2d2ff", "#a3a3ff", "#7575ff", "#4d4da8", "#dac7ff", "#b592ff", "#8e58ff", "#5e3aa8", "#f8d4f8", "#f3aaf0", "#ec7dea", "#934f92"];
this.make_color_input();
},
make_color_input: function make_color_input() {
this.$wrapper.find('.control-input-wrapper').append("<div class=\"color-picker\">\n\t\t\t\t<div class=\"color-picker-pallete\"></div>\n\t\t\t</div>");
this.$color_pallete = this.$wrapper.find('.color-picker-pallete');
var color_html = this.colors.map(this.get_color_box).join("");
this.$color_pallete.append(color_html);
this.$color_pallete.hide();
this.bind_events();
},
get_color_box: function get_color_box(hex) {
return "<div class=\"color-box\" data-color=\"" + hex + "\" style=\"background-color: " + hex + "\"></div>";
},
set_formatted_input: function set_formatted_input(value) {
this._super(value);
this.$input.css({
"background-color": value
});
},
bind_events: function bind_events() {
var _this2 = this;
var mousedown_happened = false;
this.$wrapper.on("click", ".color-box", function (e) {
mousedown_happened = false;
var color_val = $(e.target).data("color");
_this2.set_value(color_val);
_this2.set_focus();
});
this.$wrapper.find(".color-box").mousedown(function () {
mousedown_happened = true;
});
this.$input.on("focus", function () {
_this2.$color_pallete.show();
});
this.$input.on("blur", function () {
if (mousedown_happened) {
mousedown_happened = false;
} else {
$(_this2.$color_pallete).hide();
}
});
},
validate: function validate(value) {
var is_valid = /^#[0-9A-F]{6}$/i.test(value);
if (is_valid) {
return value;
}
frappe.msgprint(__("{0} is not a valid hex color", [value]));
return null;
}
});
frappe.ui.form.ControlDate = frappe.ui.form.ControlData.extend({
make_input: function make_input() {
this._super();
this.set_date_options();
this.set_datepicker();
this.set_t_for_today();
},
set_formatted_input: function set_formatted_input(value) {
this._super(value);
if (value && (this.last_value && this.last_value !== value || !this.datepicker.selectedDates.length)) {
this.datepicker.selectDate(frappe.datetime.str_to_obj(value));
}
},
set_date_options: function set_date_options() {
var _this3 = this;
var me = this;
var lang = frappe.boot.user.language;
if (!$.fn.datepicker.language[lang]) {
lang = 'en';
}
this.today_text = __("Today");
this.datepicker_options = {
language: lang,
autoClose: true,
todayButton: frappe.datetime.now_date(true),
dateFormat: frappe.boot.sysdefaults.date_format || 'yyyy-mm-dd',
startDate: frappe.datetime.now_date(true),
onSelect: function onSelect() {
_this3.$input.trigger('change');
},
onShow: function onShow() {
_this3.datepicker.$datepicker.find('.datepicker--button:visible').text(me.today_text);
_this3.update_datepicker_position();
}
};
},
update_datepicker_position: function update_datepicker_position() {
if (!this.frm) return;
var window_height = $(window).height();
var window_scroll_top = $(window).scrollTop();
var el_offset_top = this.$input.offset().top + 280;
var position = 'top left';
if (window_height + window_scroll_top >= el_offset_top) {
position = 'bottom left';
}
this.datepicker.update('position', position);
},
set_datepicker: function set_datepicker() {
this.$input.datepicker(this.datepicker_options);
this.datepicker = this.$input.data('datepicker');
},
set_t_for_today: function set_t_for_today() {
var me = this;
this.$input.on("keydown", function (e) {
if (e.which === 84) {
if (me.df.fieldtype == 'Date') {
me.set_value(frappe.datetime.nowdate());
}if (me.df.fieldtype == 'Datetime') {
me.set_value(frappe.datetime.now_datetime());
}if (me.df.fieldtype == 'Time') {
me.set_value(frappe.datetime.now_time());
}
return false;
}
});
},
parse: function parse(value) {
if (value) {
return frappe.datetime.user_to_str(value);
}
},
format_for_input: function format_for_input(value) {
if (value) {
return frappe.datetime.str_to_user(value);
}
return "";
},
validate: function validate(value) {
if (value && !frappe.datetime.validate(value)) {
frappe.msgprint(__("Date must be in format: {0}", [frappe.sys_defaults.date_format || "yyyy-mm-dd"]));
return '';
}
return value;
}
});
frappe.ui.form.ControlDatetime = frappe.ui.form.ControlDate.extend({
set_date_options: function set_date_options() {
this._super();
this.today_text = __("Now");
$.extend(this.datepicker_options, {
timepicker: true,
timeFormat: "hh:ii:ss",
todayButton: frappe.datetime.now_datetime(true)
});
},
set_description: function set_description() {
var description = this.df.description;
var time_zone = frappe.sys_defaults.time_zone;
if (!frappe.datetime.is_timezone_same()) {
if (!description) {
this.df.description = time_zone;
} else if (!description.includes(time_zone)) {
this.df.description += '<br>' + time_zone;
}
}
this._super();
}
});
frappe.ui.form.ControlTime = frappe.ui.form.ControlData.extend({
make_input: function make_input() {
var me = this;
this._super();
this.$input.datepicker({
language: "en",
timepicker: true,
onlyTimepicker: true,
timeFormat: "hh:ii:ss",
startDate: frappe.datetime.now_time(true),
onSelect: function onSelect() {
me.$input.trigger('change');
},
onShow: function onShow() {
$('.datepicker--button:visible').text(__('Now'));
},
todayButton: frappe.datetime.now_time(true)
});
this.datepicker = this.$input.data('datepicker');
this.refresh();
},
set_input: function set_input(value) {
this._super(value);
if (value && (this.last_value && this.last_value !== this.value || !this.datepicker.selectedDates.length)) {
var date_obj = frappe.datetime.moment_to_date_obj(moment(value, 'hh:mm:ss'));
this.datepicker.selectDate(date_obj);
}
},
set_description: function set_description() {
var description = this.df.description;
var time_zone = frappe.sys_defaults.time_zone;
if (!frappe.datetime.is_timezone_same()) {
if (!description) {
this.df.description = time_zone;
} else if (!description.includes(time_zone)) {
this.df.description += '<br>' + time_zone;
}
}
this._super();
}
});
frappe.ui.form.ControlDateRange = frappe.ui.form.ControlData.extend({
make_input: function make_input() {
this._super();
this.set_date_options();
this.set_datepicker();
this.refresh();
},
set_date_options: function set_date_options() {
var me = this;
this.datepicker_options = {
language: "en",
range: true,
autoClose: true,
toggleSelected: false
};
this.datepicker_options.dateFormat = frappe.boot.sysdefaults.date_format || 'yyyy-mm-dd';
this.datepicker_options.onSelect = function () {
me.$input.trigger('change');
};
},
set_datepicker: function set_datepicker() {
this.$input.datepicker(this.datepicker_options);
this.datepicker = this.$input.data('datepicker');
},
set_input: function set_input(value, value2) {
this.last_value = this.value;
if (value && value2) {
this.value = [value, value2];
} else {
this.value = value;
}
if (this.value) {
var formatted = this.format_for_input(this.value[0], this.value[1]);
this.$input && this.$input.val(formatted);
} else {
this.$input && this.$input.val("");
}
this.set_disp_area(value || '');
this.set_mandatory && this.set_mandatory(value);
},
parse: function parse(value) {
if (value && (value.indexOf(',') !== -1 || value.indexOf('to') !== -1)) {
var vals = value.split(/[( to )(,)]/);
var from_date = moment(frappe.datetime.user_to_obj(vals[0])).format('YYYY-MM-DD');
var to_date = moment(frappe.datetime.user_to_obj(vals[vals.length - 1])).format('YYYY-MM-DD');
return [from_date, to_date];
}
},
format_for_input: function format_for_input(value1, value2) {
if (value1 && value2) {
value1 = frappe.datetime.str_to_user(value1);
value2 = frappe.datetime.str_to_user(value2);
return __("{0} to {1}").format([value1, value2]);
}
return "";
}
});
frappe.ui.form.ControlText = frappe.ui.form.ControlData.extend({
html_element: "textarea",
horizontal: false,
make_wrapper: function make_wrapper() {
this._super();
this.$wrapper.find(".like-disabled-input").addClass("for-description");
},
make_input: function make_input() {
this._super();
this.$input.css({ 'height': '300px' });
}
});
frappe.ui.form.ControlLongText = frappe.ui.form.ControlText;
frappe.ui.form.ControlSmallText = frappe.ui.form.ControlText.extend({
make_input: function make_input() {
this._super();
this.$input.css({ 'height': '150px' });
}
});
frappe.ui.form.ControlCheck = frappe.ui.form.ControlData.extend({
input_type: "checkbox",
make_wrapper: function make_wrapper() {
this.$wrapper = $('<div class="form-group frappe-control">\
<div class="checkbox">\
<label>\
<span class="input-area"></span>\
<span class="disp-area" style="display:none; margin-left: -20px;"></span>\
<span class="label-area small"></span>\
</label>\
<p class="help-box small text-muted"></p>\
</div>\
</div>').appendTo(this.parent);
},
set_input_areas: function set_input_areas() {
this.label_area = this.label_span = this.$wrapper.find(".label-area").get(0);
this.input_area = this.$wrapper.find(".input-area").get(0);
this.disp_area = this.$wrapper.find(".disp-area").get(0);
},
make_input: function make_input() {
this._super();
this.$input.removeClass("form-control");
},
get_input_value: function get_input_value() {
return this.input && this.input.checked ? 1 : 0;
},
validate: function validate(value) {
return cint(value);
},
set_input: function set_input(value) {
if (this.input) {
this.input.checked = value ? 1 : 0;
}
this.last_value = value;
this.set_mandatory(value);
this.set_disp_area(value);
}
});
frappe.ui.form.ControlButton = frappe.ui.form.ControlData.extend({
make_input: function make_input() {
var me = this;
this.$input = $('<button class="btn btn-default btn-xs">').prependTo(me.input_area).on("click", function () {
me.onclick();
});
this.input = this.$input.get(0);
this.set_input_attributes();
this.has_input = true;
this.toggle_label(false);
},
onclick: function onclick() {
if (this.frm && this.frm.doc) {
if (this.frm.script_manager.has_handlers(this.df.fieldname, this.doctype)) {
this.frm.script_manager.trigger(this.df.fieldname, this.doctype, this.docname);
} else {
this.frm.runscript(this.df.options, this);
}
} else if (this.df.click) {
this.df.click();
}
},
set_input_areas: function set_input_areas() {
this._super();
$(this.disp_area).removeClass().addClass("hide");
},
set_empty_description: function set_empty_description() {
this.$wrapper.find(".help-box").empty().toggle(false);
},
set_label: function set_label() {
$(this.label_span).html("&nbsp;");
this.$input && this.$input.html((this.df.icon ? '<i class="' + this.df.icon + ' fa-fw"></i> ' : "") + __(this.df.label));
}
});
frappe.ui.form.ControlAttach = frappe.ui.form.ControlData.extend({
make_input: function make_input() {
var me = this;
this.$input = $('<button class="btn btn-default btn-sm btn-attach">').html(__("Attach")).prependTo(me.input_area).on("click", function () {
me.onclick();
});
this.$value = $('<div style="margin-top: 5px;">\
<div class="ellipsis" style="display: inline-block; width: 90%;">\
<i class="fa fa-paper-clip"></i> \
<a class="attached-file" target="_blank"></a>\
</div>\
<a class="close">&times;</a></div>').prependTo(me.input_area).toggle(false);
this.input = this.$input.get(0);
this.set_input_attributes();
this.has_input = true;
this.$value.find(".close").on("click", function () {
me.clear_attachment();
});
},
clear_attachment: function clear_attachment() {
var me = this;
if (this.frm) {
me.frm.attachments.remove_attachment_by_filename(me.value, function () {
me.parse_validate_and_set_in_model(null);
me.refresh();
me.frm.save();
});
} else {
this.dataurl = null;
this.fileobj = null;
this.set_input(null);
this.refresh();
}
},
onclick: function onclick() {
var me = this;
if (this.doc) {
var doc = this.doc.parent && frappe.model.get_doc(this.doc.parenttype, this.doc.parent) || this.doc;
if (doc.__islocal) {
frappe.msgprint(__("Please save the document before uploading."));
return;
}
}
if (!this.dialog) {
this.dialog = new frappe.ui.Dialog({
title: __(this.df.label || __("Upload")),
fields: [{ fieldtype: "HTML", fieldname: "upload_area" }, { fieldtype: "HTML", fieldname: "or_attach", options: __("Or") }, { fieldtype: "Select", fieldname: "select", label: __("Select from existing attachments") }, { fieldtype: "Button", fieldname: "clear",
label: __("Clear Attachment"), click: function click() {
me.clear_attachment();
me.dialog.hide();
}
}]
});
}
this.dialog.show();
this.dialog.get_field("upload_area").$wrapper.empty();
var attachments = this.frm && this.frm.attachments.get_attachments() || [];
var select = this.dialog.get_field("select");
if (attachments.length) {
attachments = $.map(attachments, function (o) {
return o.file_url;
});
select.df.options = [""].concat(attachments);
select.toggle(true);
this.dialog.get_field("or_attach").toggle(true);
select.refresh();
} else {
this.dialog.get_field("or_attach").toggle(false);
select.toggle(false);
}
select.$input.val("");
this.dialog.get_field('clear').$wrapper.toggle(this.get_model_value() ? true : false);
this.set_upload_options();
frappe.upload.make(this.upload_options);
},
set_upload_options: function set_upload_options() {
var me = this;
this.upload_options = {
parent: this.dialog.get_field("upload_area").$wrapper,
args: {},
allow_multiple: 0,
max_width: this.df.max_width,
max_height: this.df.max_height,
options: this.df.options,
btn: this.dialog.set_primary_action(__("Upload")),
on_no_attach: function on_no_attach() {
var selected = me.dialog.get_field("select").get_value();
if (selected) {
me.parse_validate_and_set_in_model(selected);
me.dialog.hide();
me.frm.save();
} else {
frappe.msgprint(__("Please attach a file or set a URL"));
}
},
callback: function callback(attachment, r) {
me.on_upload_complete(attachment);
me.dialog.hide();
},
onerror: function onerror() {
me.dialog.hide();
}
};
if ("is_private" in this.df) {
this.upload_options.is_private = this.df.is_private;
}
if (this.frm) {
this.upload_options.args = {
from_form: 1,
doctype: this.frm.doctype,
docname: this.frm.docname
};
} else {
this.upload_options.on_attach = function (fileobj, dataurl) {
me.dialog.hide();
me.fileobj = fileobj;
me.dataurl = dataurl;
if (me.on_attach) {
me.on_attach();
}
if (me.df.on_attach) {
me.df.on_attach(fileobj, dataurl);
}
me.on_upload_complete();
};
}
},
set_input: function set_input(value, dataurl) {
this.value = value;
if (this.value) {
this.$input.toggle(false);
if (this.value.indexOf(",") !== -1) {
var parts = this.value.split(",");
var filename = parts[0];
var dataurl = parts[1];
}
this.$value.toggle(true).find(".attached-file").html(filename || this.value).attr("href", dataurl || this.value);
} else {
this.$input.toggle(true);
this.$value.toggle(false);
}
},
get_value: function get_value() {
if (this.frm) {
return this.value;
} else {
return this.fileobj ? this.fileobj.filename + "," + this.dataurl : null;
}
},
on_upload_complete: function on_upload_complete(attachment) {
if (this.frm) {
this.parse_validate_and_set_in_model(attachment.file_url);
this.refresh();
this.frm.attachments.update_attachment(attachment);
this.frm.save();
} else {
this.value = this.get_value();
this.refresh();
}
}
});
frappe.ui.form.ControlAttachImage = frappe.ui.form.ControlAttach.extend({
make: function make() {
var me = this;
this._super();
this.container = $('<div class="control-container">').insertAfter($(this.wrapper));
$(this.wrapper).detach();
this.container.attr('data-fieldtype', this.df.fieldtype).append(this.wrapper);
if (this.df.align === 'center') {
this.container.addClass("flex-justify-center");
} else if (this.df.align === 'right') {
this.container.addClass("flex-justify-end");
}
this.img_wrapper = $('<div style="width: 100%; height: calc(100% - 40px); position: relative;">\
<div class="missing-image attach-missing-image"><i class="octicon octicon-device-camera"></i></div></div>').appendTo(this.wrapper);
this.img_container = $("<div class='img-container'></div>");
this.img = $("<img class='img-responsive attach-image-display'>").appendTo(this.img_container);
this.img_overlay = $("<div class='img-overlay'>\n\t\t\t\t<span class=\"overlay-text\">Change</span>\n\t\t\t</div>").appendTo(this.img_container);
this.remove_image_link = $('<a style="font-size: 12px;color: #8D99A6;">Remove</a>');
this.img_wrapper.append(this.img_container).append(this.remove_image_link);
this.img_container.toggle(false);
this.remove_image_link.toggle(false);
this.img_wrapper.find(".missing-image").on("click", function () {
me.$input.click();
});
this.img_container.on("click", function () {
me.$input.click();
});
this.remove_image_link.on("click", function () {
me.$value.find(".close").click();
});
this.set_image();
},
refresh_input: function refresh_input() {
this._super();
$(this.wrapper).find('.btn-attach').addClass('hidden');
this.set_image();
if (this.get_status() == "Read") {
$(this.disp_area).toggle(false);
}
},
set_image: function set_image() {
if (this.get_value()) {
$(this.img_wrapper).find(".missing-image").toggle(false);
this.img.attr("src", this.dataurl ? this.dataurl : this.value);
this.img_container.toggle(true);
this.remove_image_link.toggle(true);
} else {
$(this.img_wrapper).find(".missing-image").toggle(true);
this.img_container.toggle(false);
this.remove_image_link.toggle(false);
}
}
});
frappe.ui.form.ControlSelect = frappe.ui.form.ControlData.extend({
html_element: "select",
make_input: function make_input() {
this._super();
this.set_options();
},
set_formatted_input: function set_formatted_input(value) {
if (value == null) value = '';
this.set_options(value);
this._super(value);
var input_value = '';
if (this.$input) {
input_value = this.$input.val();
}
if (value && input_value && value !== input_value) {
this.set_model_value(input_value);
}
},
set_options: function set_options(value) {
var options = this.df.options || [];
if (typeof this.df.options === "string") {
options = this.df.options.split("\n");
}
if (options.toString() === this.last_options) {
return;
}
this.last_options = options.toString();
if (this.$input) {
var selected = this.$input.find(":selected").val();
this.$input.empty().add_options(options || []);
if (value === undefined && selected) {
this.$input.val(selected);
}
}
},
get_file_attachment_list: function get_file_attachment_list() {
if (!this.frm) return;
var fl = frappe.model.docinfo[this.frm.doctype][this.frm.docname];
if (fl && fl.attachments) {
this.set_description("");
var options = [""];
$.each(fl.attachments, function (i, f) {
options.push(f.file_url);
});
return options;
} else {
this.set_description(__("Please attach a file first."));
return [""];
}
}
});
frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({
make_input: function make_input() {
var me = this;
$('<div class="link-field ui-front" style="position: relative; line-height: 1;">\
<input type="text" class="input-with-feedback form-control">\
<span class="link-btn">\
<a class="btn-open no-decoration" title="' + __("Open Link") + '">\
<i class="octicon octicon-arrow-right"></i></a>\
</span>\
</div>').prependTo(this.input_area);
this.$input_area = $(this.input_area);
this.$input = this.$input_area.find('input');
this.$link = this.$input_area.find('.link-btn');
this.$link_open = this.$link.find('.btn-open');
this.set_input_attributes();
this.$input.on("focus", function () {
setTimeout(function () {
if (me.$input.val() && me.get_options()) {
me.$link.toggle(true);
me.$link_open.attr('href', '#Form/' + me.get_options() + '/' + me.$input.val());
}
if (!me.$input.val()) {
me.$input.val("").trigger("input");
}
}, 500);
});
this.$input.on("blur", function () {
setTimeout(function () {
me.$link.toggle(false);
}, 500);
});
this.input = this.$input.get(0);
this.has_input = true;
this.translate_values = true;
var me = this;
this.setup_buttons();
this.setup_awesomeplete();
if (this.df.change) {
this.$input.on("change", function () {
me.df.change.apply(this);
});
}
},
get_options: function get_options() {
return this.df.options;
},
setup_buttons: function setup_buttons() {
var me = this;
if (this.only_input && !this.with_link_btn) {
this.$input_area.find(".link-btn").remove();
}
},
open_advanced_search: function open_advanced_search() {
var doctype = this.get_options();
if (!doctype) return;
new frappe.ui.form.LinkSelector({
doctype: doctype,
target: this,
txt: this.get_input_value()
});
return false;
},
new_doc: function new_doc() {
var doctype = this.get_options();
var me = this;
if (!doctype) return;
if (this.df.get_route_options_for_new_doc) {
frappe.route_options = this.df.get_route_options_for_new_doc(this);
} else {
frappe.route_options = {};
}
frappe.route_options.name_field = this.get_value();
frappe._from_link = this;
frappe._from_link_scrollY = $(document).scrollTop();
frappe.ui.form.make_quick_entry(doctype, function (doc) {
return me.set_value(doc.name);
});
return false;
},
setup_awesomeplete: function setup_awesomeplete() {
var me = this;
this.$input.cache = {};
this.awesomplete = new Awesomplete(me.input, {
minChars: 0,
maxItems: 99,
autoFirst: true,
list: [],
data: function data(item, input) {
return {
label: item.label || item.value,
value: item.value
};
},
filter: function filter(item, input) {
return true;
},
item: function item(_item, input) {
var d = this.get_item(_item.value);
if (!d.label) {
d.label = d.value;
}
var _label = me.translate_values ? __(d.label) : d.label;
var html = "<strong>" + _label + "</strong>";
if (d.description && d.value !== d.description) {
html += '<br><span class="small">' + __(d.description) + '</span>';
}
return $('<li></li>').data('item.autocomplete', d).prop('aria-selected', 'false').html('<a><p>' + html + '</p></a>').get(0);
},
sort: function sort(a, b) {
return 0;
}
});
this.$input.on("input", function (e) {
var doctype = me.get_options();
if (!doctype) return;
if (!me.$input.cache[doctype]) {
me.$input.cache[doctype] = {};
}
var term = e.target.value;
if (me.$input.cache[doctype][term] != null) {
me.awesomplete.list = me.$input.cache[doctype][term];
}
var args = {
'txt': term,
'doctype': doctype
};
me.set_custom_query(args);
frappe.call({
type: "GET",
method: 'frappe.desk.search.search_link',
no_spinner: true,
args: args,
callback: function callback(r) {
if (!me.$input.is(":focus")) {
return;
}
if (!me.df.only_select) {
if (frappe.model.can_create(doctype) && me.df.fieldtype !== "Dynamic Link") {
r.results.push({
label: "<span class='text-primary link-option'>" + "<i class='fa fa-plus' style='margin-right: 5px;'></i> " + __("Create a new {0}", [__(me.df.options)]) + "</span>",
value: "create_new__link_option",
action: me.new_doc
});
}
r.results.push({
label: "<span class='text-primary link-option'>" + "<i class='fa fa-search' style='margin-right: 5px;'></i> " + __("Advanced Search") + "</span>",
value: "advanced_search__link_option",
action: me.open_advanced_search
});
}
me.$input.cache[doctype][term] = r.results;
me.awesomplete.list = me.$input.cache[doctype][term];
}
});
});
this.$input.on("blur", function () {
if (me.selected) {
me.selected = false;
return;
}
var value = me.get_input_value();
if (value !== me.last_value) {
me.parse_validate_and_set_in_model(value);
}
});
this.$input.on("awesomplete-open", function (e) {
me.$wrapper.css({ "z-index": 100 });
me.$wrapper.find('ul').css({ "z-index": 100 });
me.autocomplete_open = true;
});
this.$input.on("awesomplete-close", function (e) {
me.$wrapper.css({ "z-index": 1 });
me.autocomplete_open = false;
});
this.$input.on("awesomplete-select", function (e) {
var o = e.originalEvent;
var item = me.awesomplete.get_item(o.text.value);
me.autocomplete_open = false;
var TABKEY = 9;
if (e.keyCode === TABKEY) {
e.preventDefault();
me.awesomplete.close();
return false;
}
if (item.action) {
item.value = "";
item.action.apply(me);
}
if (me.df.remember_last_selected_value) {
frappe.boot.user.last_selected_values[me.df.options] = item.value;
}
me.parse_validate_and_set_in_model(item.value);
});
this.$input.on("awesomplete-selectcomplete", function (e) {
var o = e.originalEvent;
if (o.text.value.indexOf("__link_option") !== -1) {
me.$input.val("");
}
});
},
set_custom_query: function set_custom_query(args) {
var set_nulls = function set_nulls(obj) {
$.each(obj, function (key, value) {
if (value !== undefined) {
obj[key] = value;
}
});
return obj;
};
if (this.get_query || this.df.get_query) {
var get_query = this.get_query || this.df.get_query;
if ($.isPlainObject(get_query)) {
var filters = null;
if (get_query.filters) {
filters = get_query.filters;
} else if (get_query.query) {
args.query = get_query;
} else {
filters = get_query;
}
if (filters) {
var filters = set_nulls(filters);
$.extend(args, filters);
args.filters = filters;
}
} else if (typeof get_query === "string") {
args.query = get_query;
} else {
var q = get_query(this.frm && this.frm.doc || this.doc, this.doctype, this.docname);
if (typeof q === "string") {
args.query = q;
} else if ($.isPlainObject(q)) {
if (q.filters) {
set_nulls(q.filters);
}
if (q.translate_values !== undefined) {
this.translate_values = q.translate_values;
}
$.extend(args, q);
args.filters = q.filters;
}
}
}
if (this.df.filters) {
set_nulls(this.df.filters);
if (!args.filters) args.filters = {};
$.extend(args.filters, this.df.filters);
}
},
validate: function validate(value) {
if (this.df.options == "[Select]" || this.df.ignore_link_validation) {
return value;
}
return this.validate_link_and_fetch(this.df, this.get_options(), this.docname, value);
},
validate_link_and_fetch: function validate_link_and_fetch(df, doctype, docname, value) {
var _this4 = this;
var me = this;
if (value) {
return new Promise(function (resolve) {
var fetch = '';
if (_this4.frm && _this4.frm.fetch_dict[df.fieldname]) {
fetch = _this4.frm.fetch_dict[df.fieldname].columns.join(', ');
}
return frappe.call({
method: 'frappe.desk.form.utils.validate_link',
type: "GET",
args: {
'value': value,
'options': doctype,
'fetch': fetch
},
no_spinner: true,
callback: function callback(r) {
if (r.message == 'Ok') {
if (r.fetch_values && docname) {
me.set_fetch_values(df, docname, r.fetch_values);
}
resolve(r.valid_value);
} else {
resolve("");
}
}
});
});
}
},
set_fetch_values: function set_fetch_values(df, docname, fetch_values) {
var fl = this.frm.fetch_dict[df.fieldname].fields;
for (var i = 0; i < fl.length; i++) {
frappe.model.set_value(df.parent, docname, fl[i], fetch_values[i], df.fieldtype);
}
}
});
if (Awesomplete) {
Awesomplete.prototype.get_item = function (value) {
return this._list.find(function (item) {
return item.value === value;
});
};
}
frappe.ui.form.ControlDynamicLink = frappe.ui.form.ControlLink.extend({
get_options: function get_options() {
if (this.df.get_options) {
return this.df.get_options();
}
if (this.docname == null && cur_dialog) {
return cur_dialog.get_value(this.df.options);
}
if (cur_frm == null && cur_list) {
return cur_list.wrapper.find("input[data-fieldname*=" + this.df.options + "]").val();
}
var options = frappe.model.get_value(this.df.parent, this.docname, this.df.options);
return options;
}
});
frappe.ui.form.ControlCode = frappe.ui.form.ControlText.extend({
make_input: function make_input() {
this._super();
$(this.input_area).find("textarea").allowTabs().css({ "height": "400px", "font-family": "Monaco, \"Courier New\", monospace" });
}
});
frappe.ui.form.ControlTextEditor = frappe.ui.form.ControlCode.extend({
make_input: function make_input() {
this.has_input = true;
this.make_editor();
this.hide_elements_on_mobile();
this.setup_drag_drop();
this.setup_image_dialog();
this.setting_count = 0;
},
make_editor: function make_editor() {
var me = this;
this.editor = $("<div>").appendTo(this.input_area);
this.editor.summernote({
minHeight: 400,
toolbar: [['magic', ['style']], ['style', ['bold', 'italic', 'underline', 'clear']], ['fontsize', ['fontsize']], ['color', ['color']], ['para', ['ul', 'ol', 'paragraph', 'hr']], ['media', ['link', 'picture', 'video', 'table']], ['misc', ['fullscreen', 'codeview']]],
keyMap: {
pc: {
'CTRL+ENTER': ''
},
mac: {
'CMD+ENTER': ''
}
},
prettifyHtml: true,
dialogsInBody: true,
callbacks: {
onInit: function onInit() {
$(".note-editable[contenteditable='true']").one('focus', function () {
var $this = $(this);
$this.html($this.html() + '<br>');
});
},
onChange: function onChange(value) {
me.parse_validate_and_set_in_model(value);
},
onKeydown: function onKeydown(e) {
me._last_change_on = new Date();
var key = frappe.ui.keys.get_key(e);
if (['ctrl+b', 'meta+b'].indexOf(key) !== -1) {
e.stopPropagation();
}
if (key.indexOf('escape') !== -1) {
if (me.note_editor.hasClass('fullscreen')) {
me.note_editor.find('.note-btn.btn-fullscreen').trigger('click');
}
}
}
},
icons: {
'align': 'fa fa-align',
'alignCenter': 'fa fa-align-center',
'alignJustify': 'fa fa-align-justify',
'alignLeft': 'fa fa-align-left',
'alignRight': 'fa fa-align-right',
'indent': 'fa fa-indent',
'outdent': 'fa fa-outdent',
'arrowsAlt': 'fa fa-arrows-alt',
'bold': 'fa fa-bold',
'caret': 'caret',
'circle': 'fa fa-circle',
'close': 'fa fa-close',
'code': 'fa fa-code',
'eraser': 'fa fa-eraser',
'font': 'fa fa-font',
'frame': 'fa fa-frame',
'italic': 'fa fa-italic',
'link': 'fa fa-link',
'unlink': 'fa fa-chain-broken',
'magic': 'fa fa-magic',
'menuCheck': 'fa fa-check',
'minus': 'fa fa-minus',
'orderedlist': 'fa fa-list-ol',
'pencil': 'fa fa-pencil',
'picture': 'fa fa-image',
'question': 'fa fa-question',
'redo': 'fa fa-redo',
'square': 'fa fa-square',
'strikethrough': 'fa fa-strikethrough',
'subscript': 'fa fa-subscript',
'superscript': 'fa fa-superscript',
'table': 'fa fa-table',
'textHeight': 'fa fa-text-height',
'trash': 'fa fa-trash',
'underline': 'fa fa-underline',
'undo': 'fa fa-undo',
'unorderedlist': 'fa fa-list-ul',
'video': 'fa fa-video-camera'
}
});
this.note_editor = $(this.input_area).find('.note-editor');
},
setup_drag_drop: function setup_drag_drop() {
var me = this;
this.note_editor.on('dragenter dragover', false).on('drop', function (e) {
var dataTransfer = e.originalEvent.dataTransfer;
if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
me.note_editor.focus();
var files = [].slice.call(dataTransfer.files);
files.forEach(function (file) {
me.get_image(file, function (url) {
me.editor.summernote('insertImage', url, file.name);
});
});
}
e.preventDefault();
e.stopPropagation();
});
},
get_image: function get_image(fileobj, callback) {
var freader = new FileReader(),
me = this;
freader.onload = function () {
var dataurl = freader.result;
var parts = dataurl.split(",");
parts[0] += ";filename=" + fileobj.name;
dataurl = parts[0] + ',' + parts[1];
callback(dataurl);
};
freader.readAsDataURL(fileobj);
},
hide_elements_on_mobile: function hide_elements_on_mobile() {
this.note_editor.find('.note-btn-underline,\
.note-btn-italic, .note-fontsize,\
.note-color, .note-height, .btn-codeview').addClass('hidden-xs');
if ($('.toggle-sidebar').is(':visible')) {
this.note_editor.find('.note-btn').attr('data-original-title', '');
}
},
get_input_value: function get_input_value() {
return this.editor ? this.editor.summernote('code') : '';
},
parse: function parse(value) {
if (value == null) value = "";
return frappe.dom.remove_script_and_style(value);
},
set_formatted_input: function set_formatted_input(value) {
if (value !== this.get_input_value()) {
this.set_in_editor(value);
}
},
set_in_editor: function set_in_editor(value) {
var _this5 = this;
if (this.setting_count > 2) {
return;
}
this.setting_count += 1;
var time_since_last_keystroke = moment() - moment(this._last_change_on);
if (!this._last_change_on || time_since_last_keystroke > 3000) {
setTimeout(function () {
return _this5.setting_count = 0;
}, 500);
this.editor.summernote('code', value || '');
} else {
this._setting_value = setInterval(function () {
if (time_since_last_keystroke > 3000) {
if (_this5.last_value !== _this5.get_input_value()) {
_this5.editor.summernote('code', _this5.last_value || '');
}
clearInterval(_this5._setting_value);
_this5._setting_value = null;
_this5.setting_count = 0;
}
}, 1000);
}
},
set_focus: function set_focus() {
return this.editor.summernote('focus');
},
set_upload_options: function set_upload_options() {
var me = this;
this.upload_options = {
parent: this.image_dialog.get_field("upload_area").$wrapper,
args: {},
max_width: this.df.max_width,
max_height: this.df.max_height,
options: "Image",
btn: this.image_dialog.set_primary_action(__("Insert")),
on_no_attach: function on_no_attach() {
var selected = me.image_dialog.get_field("select").get_value();
if (selected) {
me.editor.summernote('insertImage', selected);
me.image_dialog.hide();
} else {
frappe.msgprint(__("Please attach a file or set a URL"));
}
},
callback: function callback(attachment, r) {
me.editor.summernote('insertImage', attachment.file_url, attachment.file_name);
me.image_dialog.hide();
},
onerror: function onerror() {
me.image_dialog.hide();
}
};
if ("is_private" in this.df) {
this.upload_options.is_private = this.df.is_private;
}
if (this.frm) {
this.upload_options.args = {
from_form: 1,
doctype: this.frm.doctype,
docname: this.frm.docname
};
} else {
this.upload_options.on_attach = function (fileobj, dataurl) {
me.editor.summernote('insertImage', dataurl);
me.image_dialog.hide();
frappe.hide_progress();
};
}
},
setup_image_dialog: function setup_image_dialog() {
var _this6 = this;
this.note_editor.find('[data-original-title="Image"]').on('click', function (e) {
if (!_this6.image_dialog) {
_this6.image_dialog = new frappe.ui.Dialog({
title: __("Image"),
fields: [{ fieldtype: "HTML", fieldname: "upload_area" }, { fieldtype: "HTML", fieldname: "or_attach", options: __("Or") }, { fieldtype: "Select", fieldname: "select", label: __("Select from existing attachments") }]
});
}
_this6.image_dialog.show();
_this6.image_dialog.get_field("upload_area").$wrapper.empty();
var attachments = _this6.frm && _this6.frm.attachments.get_attachments() || [];
var select = _this6.image_dialog.get_field("select");
if (attachments.length) {
attachments = $.map(attachments, function (o) {
return o.file_url;
});
select.df.options = [""].concat(attachments);
select.toggle(true);
_this6.image_dialog.get_field("or_attach").toggle(true);
select.refresh();
} else {
_this6.image_dialog.get_field("or_attach").toggle(false);
select.toggle(false);
}
select.$input.val("");
_this6.set_upload_options();
frappe.upload.make(_this6.upload_options);
});
}
});
frappe.ui.form.ControlTable = frappe.ui.form.Control.extend({
make: function make() {
this._super();
this.grid = new frappe.ui.form.Grid({
frm: this.frm,
df: this.df,
perm: this.perm || this.frm && this.frm.perm || this.df.perm,
parent: this.wrapper
});
if (this.frm) {
this.frm.grids[this.frm.grids.length] = this;
}
if (this.df.description) {
$('<p class="text-muted small">' + __(this.df.description) + '</p>').appendTo(this.wrapper);
}
},
refresh_input: function refresh_input() {
this.grid.refresh();
},
get_value: function get_value() {
if (this.grid) {
return this.grid.get_data();
}
}
});
frappe.ui.form.ControlSignature = frappe.ui.form.ControlData.extend({
saving: false,
loading: false,
make: function make() {
var me = this;
this._super();
this.$pad = $('<div class="signature-field"></div>').appendTo(me.wrapper).jSignature({ height: 300, width: "100%", "lineWidth": 0.8 }).on('change', this.on_save_sign.bind(this));
this.img_wrapper = $("<div class=\"signature-display\">\n\t\t\t<div class=\"missing-image attach-missing-image\">\n\t\t\t\t<i class=\"octicon octicon-circle-slash\"></i>\n\t\t\t</div></div>").appendTo(this.wrapper);
this.img = $("<img class='img-responsive attach-image-display'>").appendTo(this.img_wrapper).toggle(false);
this.$btnWrapper = $("<div class=\"signature-btn-row\">\n\t\t\t<a href=\"#\" type=\"button\" class=\"signature-reset btn btn-default\">\n\t\t\t<i class=\"glyphicon glyphicon-repeat\"></i></a>").appendTo(this.$pad).on("click", '.signature-reset', function () {
me.on_reset_sign();
return false;
});
},
refresh_input: function refresh_input(e) {
this.$wrapper.find(".control-input").toggle(false);
this.set_editable(this.get_status() == "Write");
this.load_pad();
if (this.get_status() == "Read") {
$(this.disp_area).toggle(false);
}
},
set_image: function set_image(value) {
if (value) {
$(this.img_wrapper).find(".missing-image").toggle(false);
this.img.attr("src", value).toggle(true);
} else {
$(this.img_wrapper).find(".missing-image").toggle(true);
this.img.toggle(false);
}
},
load_pad: function load_pad() {
if (this.saving) return;
var value = this.get_value();
if (this.$pad) {
this.loading = true;
this.$pad.jSignature('reset');
if (value) {
try {
this.$pad.jSignature('setData', value);
this.set_image(value);
} catch (e) {
console.log("Cannot set data for signature", value, e);
}
}
this.loading = false;
}
},
set_editable: function set_editable(editable) {
this.$pad.toggle(editable);
this.img_wrapper.toggle(!editable);
this.$btnWrapper.toggle(editable);
if (editable) {
this.$btnWrapper.addClass('editing');
} else {
this.$btnWrapper.removeClass('editing');
}
},
set_my_value: function set_my_value(value) {
if (this.saving || this.loading) return;
this.saving = true;
this.set_value(value);
this.value = value;
this.saving = false;
},
get_value: function get_value() {
return this.value ? this.value : this.get_model_value();
},
on_reset_sign: function on_reset_sign() {
this.$pad.jSignature("reset");
this.set_my_value("");
},
on_save_sign: function on_save_sign() {
if (this.saving || this.loading) return;
var base64_img = this.$pad.jSignature("getData");
this.set_my_value(base64_img);
this.set_image(this.get_value());
}
});
frappe.ui.form.fieldtype_icons = {
"Date": "fa fa-calendar",
"Time": "fa fa-time",
"Datetime": "fa fa-time",
"Code": "fa fa-code",
"Select": "fa fa-flag"
};
frappe.ui.form.LinkSelector = Class.extend({
init: function init(opts) {
$.extend(this, opts);
var me = this;
if (this.doctype != "[Select]") {
frappe.model.with_doctype(this.doctype, function (r) {
me.make();
});
} else {
this.make();
}
},
make: function make() {
var me = this;
this.dialog = new frappe.ui.Dialog({
title: __("Select {0}", [this.doctype == '[Select]' ? __("value") : __(this.doctype)]),
fields: [{
fieldtype: "Data", fieldname: "txt", label: __("Beginning with"),
description: __("You can use wildcard %")
}, {
fieldtype: "HTML", fieldname: "results"
}],
primary_action_label: __("Search"),
primary_action: function primary_action() {
me.search();
}
});
if (this.txt) this.dialog.fields_dict.txt.set_input(this.txt);
this.dialog.get_input("txt").on("keypress", function (e) {
if (e.which === 13) {
me.search();
}
});
this.dialog.show();
this.search();
},
search: function search() {
var args = {
txt: this.dialog.fields_dict.txt.get_value(),
searchfield: "name"
};
var me = this;
if (this.target.set_custom_query) {
this.target.set_custom_query(args);
}
if (this.target.is_grid && this.target.fieldinfo[this.fieldname] && this.target.fieldinfo[this.fieldname].get_query) {
$.extend(args, this.target.fieldinfo[this.fieldname].get_query(cur_frm.doc));
}
frappe.link_search(this.doctype, args, function (r) {
var parent = me.dialog.fields_dict.results.$wrapper;
parent.empty();
if (r.values.length) {
$.each(r.values, function (i, v) {
var row = $(repl('<div class="row link-select-row">\
<div class="col-xs-4">\
<b><a href="#">%(name)s</a></b></div>\
<div class="col-xs-8">\
<span class="text-muted">%(values)s</span></div>\
</div>', {
name: v[0],
values: v.splice(1).join(", ")
})).appendTo(parent);
row.find("a").attr('data-value', v[0]).click(function () {
var value = $(this).attr("data-value");
var $link = this;
if (me.target.is_grid) {
me.set_in_grid(value);
} else {
if (me.target.doctype) me.target.parse_validate_and_set_in_model(value);else {
me.target.set_input(value);
me.target.$input.trigger("change");
}
me.dialog.hide();
}
return false;
});
});
} else {
$('<p><br><span class="text-muted">' + __("No Results") + '</span>' + (frappe.model.can_create(me.doctype) ? '<br><br><a class="new-doc btn btn-default btn-sm">' + __("Make a new {0}", [__(me.doctype)]) + "</a>" : '') + '</p>').appendTo(parent).find(".new-doc").click(function () {
me.target.new_doc();
});
}
}, this.dialog.get_primary_btn());
},
set_in_grid: function set_in_grid(value) {
var me = this,
updated = false;
if (this.qty_fieldname) {
frappe.prompt({
fieldname: "qty", fieldtype: "Float", label: "Qty",
"default": 1, reqd: 1
}, function (data) {
$.each(me.target.frm.doc[me.target.df.fieldname] || [], function (i, d) {
if (d[me.fieldname] === value) {
frappe.model.set_value(d.doctype, d.name, me.qty_fieldname, data.qty);
frappe.show_alert(__("Added {0} ({1})", [value, d[me.qty_fieldname]]));
updated = true;
return false;
}
});
if (!updated) {
var d = me.target.add_new_row();
frappe.model.set_value(d.doctype, d.name, me.fieldname, value);
frappe.after_ajax(function () {
setTimeout(function () {
frappe.model.set_value(d.doctype, d.name, me.qty_fieldname, data.qty);
frappe.show_alert(__("Added {0} ({1})", [value, data.qty]));
}, 100);
});
}
}, __("Set Quantity"), __("Set"));
} else {
var d = me.target.add_new_row();
frappe.model.set_value(d.doctype, d.name, me.fieldname, value);
frappe.show_alert(__("{0} added", [value]));
}
}
});
frappe.link_search = function (doctype, args, _callback, btn) {
if (!args) {
args = {
txt: ''
};
}
args.doctype = doctype;
if (!args.searchfield) {
args.searchfield = 'name';
}
frappe.call({
method: "frappe.desk.search.search_widget",
type: "GET",
args: args,
callback: function callback(r) {
_callback && _callback(r);
},
btn: btn
});
};
frappe.ui.form.MultiSelectDialog = Class.extend({
init: function init(opts) {
$.extend(this, opts);
var me = this;
if (this.doctype != "[Select]") {
frappe.model.with_doctype(this.doctype, function (r) {
me.make();
});
} else {
this.make();
}
},
make: function make() {
var me = this;
this.page_length = 20;
var fields = [{
fieldtype: "Data",
label: __("Search Term"),
fieldname: "search_term"
}, {
fieldtype: "Column Break"
}];
var count = 0;
if (!this.date_field) {
this.date_field = "transaction_date";
}
Object.keys(this.setters).forEach(function (setter) {
fields.push({
fieldtype: me.target.fields_dict[setter].df.fieldtype,
label: me.target.fields_dict[setter].df.label,
fieldname: setter,
options: me.target.fields_dict[setter].df.options,
default: me.setters[setter]
});
if (count++ < Object.keys(me.setters).length) {
fields.push({ fieldtype: "Column Break" });
}
});
fields = fields.concat([{
"fieldname": "date_range",
"label": __("Date Range"),
"fieldtype": "DateRange"
}, { fieldtype: "Section Break" }, { fieldtype: "HTML", fieldname: "results_area" }, { fieldtype: "Button", fieldname: "make_new", label: __("Make a new " + me.doctype) }]);
var doctype_plural = !this.doctype.endsWith('y') ? this.doctype + 's' : this.doctype.slice(0, -1) + 'ies';
this.dialog = new frappe.ui.Dialog({
title: __("Select {0}", [this.doctype == '[Select]' ? __("value") : __(doctype_plural)]),
fields: fields,
primary_action_label: __("Get Items"),
primary_action: function primary_action() {
me.action(me.get_checked_values(), me.args);
}
});
this.$parent = $(this.dialog.body);
this.$wrapper = this.dialog.fields_dict.results_area.$wrapper.append("<div class=\"results\"\n\t\t\tstyle=\"border: 1px solid #d1d8dd; border-radius: 3px; height: 300px; overflow: auto;\"></div>");
this.$results = this.$wrapper.find('.results');
this.$make_new_btn = this.dialog.fields_dict.make_new.$wrapper;
this.$placeholder = $("<div class=\"multiselect-empty-state\">\n\t\t\t\t\t<span class=\"text-center\" style=\"margin-top: -40px;\">\n\t\t\t\t\t\t<i class=\"fa fa-2x fa-tags text-extra-muted\"></i>\n\t\t\t\t\t\t<p class=\"text-extra-muted\">No " + this.doctype + " found</p>\n\t\t\t\t\t\t<button class=\"btn btn-default btn-xs text-muted\" data-fieldtype=\"Button\"\n\t\t\t\t\t\t\tdata-fieldname=\"make_new\" placeholder=\"\" value=\"\">Make a new " + this.doctype + "</button>\n\t\t\t\t\t</span>\n\t\t\t\t</div>");
this.args = {};
this.bind_events();
this.get_results();
this.dialog.show();
},
bind_events: function bind_events() {
var _this = this;
var me = this;
this.$results.on('click', '.list-item-container', function (e) {
if (!$(e.target).is(':checkbox') && !$(e.target).is('a')) {
$(this).find(':checkbox').trigger('click');
}
});
this.$results.on('click', '.list-item--head :checkbox', function (e) {
_this.$results.find('.list-item-container .list-row-check').prop("checked", $(e.target).is(':checked'));
});
this.$parent.find('.input-with-feedback').on('change', function (e) {
_this.get_results();
});
this.$parent.find('[data-fieldname="date_range"]').on('blur', function (e) {
_this.get_results();
});
this.$parent.find('[data-fieldname="search_term"]').on('input', function (e) {
var $this = $(_this);
clearTimeout($this.data('timeout'));
$this.data('timeout', setTimeout(function () {
me.get_results();
}, 300));
});
this.$parent.on('click', '.btn[data-fieldname="make_new"]', function (e) {
frappe.route_options = {};
Object.keys(_this.setters).forEach(function (setter) {
frappe.route_options[setter] = me.dialog.fields_dict[setter].get_value() || undefined;
});
frappe.new_doc(_this.doctype, true);
});
},
get_checked_values: function get_checked_values() {
return this.$results.find('.list-item-container').map(function () {
if ($(this).find('.list-row-check:checkbox:checked').length > 0) {
return $(this).attr('data-item-name');
}
}).get();
},
make_list_row: function make_list_row() {
var result = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var me = this;
var head = Object.keys(result).length === 0;
var contents = "";
var columns = ["name"].concat(Object.keys(this.setters)).concat("Date");
columns.forEach(function (column) {
contents += "<div class=\"list-item__content ellipsis\">\n\t\t\t\t" + (head ? "<span class=\"ellipsis\">" + __(frappe.model.unscrub(column)) + "</span>" : column !== "name" ? "<span class=\"ellipsis\">" + __(result[column]) + "</span>" : "<a href=\"" + ("#Form/" + me.doctype + "/" + result[column]) + "\" class=\"list-id ellipsis\">\n\t\t\t\t\t\t\t" + __(result[column]) + "</a>") + "\n\t\t\t</div>";
});
var $row = $("<div class=\"list-item\">\n\t\t\t<div class=\"list-item__content\" style=\"flex: 0 0 10px;\">\n\t\t\t\t<input type=\"checkbox\" class=\"list-row-check\" " + (result.checked ? 'checked' : '') + ">\n\t\t\t</div>\n\t\t\t" + contents + "\n\t\t</div>");
head ? $row.addClass('list-item--head') : $row = $("<div class=\"list-item-container\" data-item-name=\"" + result.name + "\"></div>").append($row);
return $row;
},
render_result_list: function render_result_list(results) {
var more = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var me = this;
this.$results.empty();
if (results.length === 0) {
this.$make_new_btn.addClass('hide');
this.$results.append(me.$placeholder);
return;
}
this.$make_new_btn.removeClass('hide');
this.$results.append(this.make_list_row());
results.forEach(function (result) {
me.$results.append(me.make_list_row(result));
});
if (more) {
var message = __("Only {0} entries shown. Please filter for more specific results.", [this.page_length]);
me.$results.append($("<div class=\"text-muted small\" style=\"text-align: center;\n\t\t\t\tmargin: 10px;\">" + message + "</div>"));
}
},
get_results: function get_results() {
var me = this;
var filters = this.get_query().filters;
Object.keys(this.setters).forEach(function (setter) {
filters[setter] = me.dialog.fields_dict[setter].get_value() || undefined;
me.args[setter] = filters[setter];
});
var date_val = this.dialog.fields_dict["date_range"].get_value();
if (date_val) {
filters[this.date_field] = ['Between', me.dialog.fields_dict["date_range"].parse(date_val)];
}
var args = {
doctype: me.doctype,
txt: me.dialog.fields_dict["search_term"].get_value(),
filters: filters,
filter_fields: Object.keys(me.setters).concat([me.date_field]),
page_length: this.page_length + 1,
query: this.get_query().query,
as_dict: 1
};
frappe.call({
type: "GET",
method: 'frappe.desk.search.search_widget',
no_spinner: true,
args: args,
callback: function callback(r) {
var results = [],
more = 0;
if (r.values.length) {
if (r.values.length > me.page_length) {
r.values.pop();
more = 1;
}
r.values.forEach(function (result) {
if (me.date_field in result) {
result["Date"] = result[me.date_field];
}
result.checked = 0;
result.parsed_date = Date.parse(result["Date"]);
results.push(result);
});
results.map(function (result) {
result["Date"] = frappe.format(result["Date"], { "fieldtype": "Date" });
});
results.sort(function (a, b) {
return a.parsed_date - b.parsed_date;
});
results[0].checked = 1;
}
me.render_result_list(results, more);
}
});
}
});
frappe.provide('frappe.ui');
var cur_dialog;
frappe.ui.open_dialogs = [];
frappe.ui.Dialog = frappe.ui.FieldGroup.extend({
init: function init(opts) {
this.display = false;
this.is_dialog = true;
$.extend(this, opts);
this._super();
this.make();
},
make: function make() {
this.$wrapper = frappe.get_modal("", "");
this.wrapper = this.$wrapper.find('.modal-dialog').get(0);
this.make_head();
this.body = this.$wrapper.find(".modal-body").get(0);
this.header = this.$wrapper.find(".modal-header");
this._super();
if (this.primary_action) {
this.set_primary_action(this.primary_action_label || __("Submit"), this.primary_action);
}
if (this.secondary_action_label) {
this.get_close_btn().html(this.secondary_action_label);
}
var me = this;
this.$wrapper.on("hide.bs.modal", function () {
me.display = false;
if (frappe.ui.open_dialogs[frappe.ui.open_dialogs.length - 1] === me) {
frappe.ui.open_dialogs.pop();
if (frappe.ui.open_dialogs.length) {
cur_dialog = frappe.ui.open_dialogs[frappe.ui.open_dialogs.length - 1];
} else {
cur_dialog = null;
}
}
me.onhide && me.onhide();
me.on_hide && me.on_hide();
}).on("shown.bs.modal", function () {
me.display = true;
cur_dialog = me;
frappe.ui.open_dialogs.push(me);
me.focus_on_first_input();
me.on_page_show && me.on_page_show();
}).on('scroll', function () {
var $input = $('input:focus');
if ($input.length && ['Date', 'Datetime', 'Time'].includes($input.attr('data-fieldtype'))) {
$input.blur();
}
});
},
focus_on_first_input: function focus_on_first_input() {
if (this.no_focus) return;
$.each(this.fields_list, function (i, f) {
if (!in_list(['Date', 'Datetime', 'Time'], f.df.fieldtype) && f.set_focus) {
f.set_focus();
return false;
}
});
},
get_primary_btn: function get_primary_btn() {
return this.$wrapper.find(".modal-header .btn-primary");
},
set_primary_action: function set_primary_action(label, click) {
this.has_primary_action = true;
var me = this;
return this.get_primary_btn().removeClass("hide").html(label).click(function () {
me.primary_action_fulfilled = true;
var values = me.get_values();
if (!values) return;
click.apply(me, [values]);
});
},
make_head: function make_head() {
var me = this;
this.set_title(this.title);
},
set_title: function set_title(t) {
this.$wrapper.find(".modal-title").html(t);
},
show: function show() {
this.$wrapper.modal("show");
this.primary_action_fulfilled = false;
},
hide: function hide(from_event) {
this.$wrapper.modal("hide");
},
get_close_btn: function get_close_btn() {
return this.$wrapper.find(".btn-modal-close");
},
no_cancel: function no_cancel() {
this.get_close_btn().toggle(false);
},
cancel: function cancel() {
this.get_close_btn().trigger("click");
}
});