refactor(form.js): remove very old API

This commit is contained in:
Rushabh Mehta 2019-05-22 16:53:28 +05:30
parent 83eb9c3acc
commit 81fa64d4bc
59 changed files with 391 additions and 1910 deletions

View file

@ -5,8 +5,6 @@ frappe.provide("frappe.customize_form");
frappe.ui.form.on("Customize Form", {
onload: function(frm) {
frappe.customize_form.add_fields_help(frm);
frm.set_query("doc_type", function() {
return {
translate_values: false,
@ -206,103 +204,3 @@ frappe.customize_form.clear_locals_and_refresh = function(frm) {
frm.refresh();
}
frappe.customize_form.add_fields_help = function(frm) {
$(frm.grids[0].parent).before(
'<div style="padding: 10px">\
<a id="fields_help" class="link_type">' + __("Help") + '</a>\
</div>');
$('#fields_help').click(function() {
var d = new frappe.ui.Dialog({
title: __('Help: Field Properties'),
width: 600
});
var help =
"<table cellspacing='25'>\
<tr>\
<td><b>" + __("Label") + "</b></td>\
<td>" + __("Set the display label for the field") + "</td>\
</tr>\
<tr>\
<td><b>" + __("Type") + "</b></td>\
<td>" + __("Change type of field. (Currently, Type change is \
allowed among 'Currency and Float')") + "</td>\
</tr>\
<tr>\
<td width='25%'><b>" + __("Options") + "</b></td>\
<td width='75%'>" + __("Specify the value of the field") + "</td>\
</tr>\
<tr>\
<td><b>" + __("Perm Level") + "</b></td>\
<td>\
" + __("Assign a permission level to the field.") + "<br />\
(" + __("Permissions can be managed via Setup &gt; Role Permissions Manager") + "\
</td>\
</tr>\
<tr>\
<td><b>" + __("Width") + "</b></td>\
<td>\
" + __("Width of the input box") + "<br />\
" + __("Example") + ": <i>120px</i>\
</td>\
</tr>\
<tr>\
<td><b>" + __("Reqd") + "</b></td>\
<td>" + __("Mark the field as Mandatory") + "</td>\
</tr>\
<tr>\
<td><b>" + __("In Filter") + "</b></td>\
<td>" + __("Use the field to filter records") + "</td>\
</tr>\
<tr>\
<td><b>" + __("Hidden") + "</b></td>\
<td>" + __("Hide field in form") + "</td>\
</tr>\
<tr>\
<td><b>" + __("Print Hide") + "</b></td>\
<td>" + __("Hide field in Standard Print Format") + "</td>\
</tr>\
<tr>\
<td><b>" + __("Report Hide") + "</b></td>\
<td>" + __("Hide field in Report Builder") + "</td>\
</tr>\
<tr>\
<td><b>" + __("Allow on Submit") + "</b></td>\
<td>" + __("Allow field to remain editable even after submission") + "</td>\
</tr>\
<tr>\
<td><b>" + __("Depends On") + "</b></td>\
<td>\
Show field if a condition is met<br />\
Example: <code>eval:doc.status=='Cancelled'</code>\
on a field like \"reason_for_cancellation\" will reveal \
\"Reason for Cancellation\" only if the record is Cancelled.\
</td>\
</tr>\
<tr>\
<td><b>" + __("Description") + "</b></td>\
<td>" + __("Show a description below the field") + "</td>\
</tr>\
<tr>\
<td><b>" + __("Default") + "</b></td>\
<td>" + __("Specify a default value") + "</td>\
</tr>\
<tr>\
<td></td>\
<td><a class='link_type' \
onclick='frappe.customize_form.fields_help_dialog.hide()'\
style='color:grey'>" + __("Press Esc to close") + "</a>\
</td>\
</tr>\
</table>"
$y(d.body, {padding: '32px', textAlign: 'center', lineHeight: '200%'});
$a(d.body, 'div', '', {textAlign: 'left'}, help);
d.show();
frappe.customize_form.fields_help_dialog = d;
});
}

View file

@ -1241,7 +1241,7 @@ class Document(BaseDocument):
file_lock.delete_lock(self.get_signature())
# validation helpers
def validate_from_to_dates(from_date_field, to_date_field):
def validate_from_to_dates(self, from_date_field, to_date_field):
'''
Generic validation to verify date sequence
'''

View file

@ -30,12 +30,12 @@
"public/js/lib/md5.min.js",
"public/js/frappe/provide.js",
"public/js/frappe/format.js",
"public/js/frappe/misc/number_format.js",
"public/js/frappe/misc/utils.js",
"public/js/frappe/misc/common.js",
"public/js/frappe/utils/number_format.js",
"public/js/frappe/utils/utils.js",
"public/js/frappe/utils/common.js",
"public/js/frappe/ui/messages.js",
"public/js/frappe/translate.js",
"public/js/frappe/misc/pretty_date.js",
"public/js/frappe/utils/pretty_date.js",
"public/js/lib/microtemplate.js",
"public/js/frappe/query_string.js",
@ -48,7 +48,7 @@
"public/js/frappe/model/perm.js",
"website/js/website.js",
"public/js/frappe/misc/rating_icons.html",
"public/js/frappe/utils/rating_icons.html",
"public/js/frappe/socketio_client.js"
],
"js/bootstrap-4-web.min.js": [
@ -56,45 +56,7 @@
],
"js/control.min.js": [
"public/js/frappe/ui/capture.js",
"public/js/frappe/form/controls/base_control.js",
"public/js/frappe/form/controls/base_input.js",
"public/js/frappe/form/controls/data.js",
"public/js/frappe/form/controls/int.js",
"public/js/frappe/form/controls/float.js",
"public/js/frappe/form/controls/currency.js",
"public/js/frappe/form/controls/date.js",
"public/js/frappe/form/controls/time.js",
"public/js/frappe/form/controls/datetime.js",
"public/js/frappe/form/controls/date_range.js",
"public/js/frappe/form/controls/select.js",
"public/js/frappe/form/controls/link.js",
"public/js/frappe/form/controls/dynamic_link.js",
"public/js/frappe/form/controls/text.js",
"public/js/frappe/form/controls/code.js",
"public/js/frappe/form/controls/text_editor.js",
"public/js/frappe/form/controls/comment.js",
"public/js/frappe/form/controls/check.js",
"public/js/frappe/form/controls/image.js",
"public/js/frappe/form/controls/attach.js",
"public/js/frappe/form/controls/attach_image.js",
"public/js/frappe/form/controls/table.js",
"public/js/frappe/form/controls/color.js",
"public/js/frappe/form/controls/signature.js",
"public/js/frappe/form/controls/password.js",
"public/js/frappe/form/controls/read_only.js",
"public/js/frappe/form/controls/button.js",
"public/js/frappe/form/controls/html.js",
"public/js/frappe/form/controls/markdown_editor.js",
"public/js/frappe/form/controls/html_editor.js",
"public/js/frappe/form/controls/heading.js",
"public/js/frappe/form/controls/autocomplete.js",
"public/js/frappe/form/controls/barcode.js",
"public/js/frappe/form/controls/geolocation.js",
"public/js/frappe/form/controls/multiselect.js",
"public/js/frappe/form/controls/multicheck.js",
"public/js/frappe/form/controls/table_multiselect.js",
"public/js/frappe/form/controls/multiselect_pills.js",
"public/js/frappe/form/controls/rating.js"
"public/js/frappe/form/controls/control.js"
],
"js/dialog.min.js": [
"public/js/frappe/dom.js",
@ -177,7 +139,7 @@
"public/js/frappe/request.js",
"public/js/frappe/socketio_client.js",
"public/js/frappe/misc/utils.js",
"public/js/frappe/utils/utils.js",
"public/js/frappe/event_emitter.js",
"public/js/frappe/router.js",
"public/js/frappe/router_history.js",
@ -185,9 +147,6 @@
"public/js/frappe/roles_editor.js",
"public/js/lib/microtemplate.js",
"public/js/legacy/globals.js",
"public/js/legacy/datatype.js",
"public/js/legacy/dom.js",
"public/js/legacy/handler.js",
"public/js/frappe/ui/page.html",
@ -214,18 +173,20 @@
"public/js/frappe/model/user_settings.js",
"public/js/lib/md5.min.js",
"public/js/frappe/misc/user.js",
"public/js/frappe/misc/common.js",
"public/js/frappe/misc/pretty_date.js",
"public/js/frappe/misc/test_utils.js",
"public/js/frappe/misc/tools.js",
"public/js/frappe/misc/datetime.js",
"public/js/frappe/misc/number_format.js",
"public/js/frappe/misc/help.js",
"public/js/frappe/misc/help_links.js",
"public/js/frappe/misc/address_and_contact.js",
"public/js/frappe/misc/preview_email.js",
"public/js/frappe/misc/file_manager.js",
"public/js/frappe/utils/user.js",
"public/js/frappe/utils/common.js",
"public/js/frappe/utils/urllib.js",
"public/js/frappe/utils/pretty_date.js",
"public/js/frappe/utils/test_utils.js",
"public/js/frappe/utils/tools.js",
"public/js/frappe/utils/jquery_plugins.js",
"public/js/frappe/utils/datetime.js",
"public/js/frappe/utils/number_format.js",
"public/js/frappe/utils/help.js",
"public/js/frappe/utils/help_links.js",
"public/js/frappe/utils/address_and_contact.js",
"public/js/frappe/utils/preview_email.js",
"public/js/frappe/utils/file_manager.js",
"public/js/frappe/ui/upload.html",
"public/js/frappe/upload.js",
@ -257,11 +218,11 @@
"public/js/frappe/query_string.js",
"public/js/frappe/ui/comment.js",
"public/js/frappe/misc/rating_icons.html",
"public/js/frappe/utils/rating_icons.html",
"public/js/frappe/chat.js",
"public/js/frappe/social/social_factory.js",
"public/js/frappe/misc/energy_point_utils.js"
"public/js/frappe/utils/energy_point_utils.js"
],
"css/module.min.css": [
"public/less/module.less"
@ -270,7 +231,6 @@
"public/less/form_grid.less"
],
"js/form.min.js": [
"public/js/frappe/form/document_follow.js",
"public/js/frappe/form/templates/print_layout.html",
"public/js/frappe/form/templates/users_in_sidebar.html",
"public/js/frappe/form/templates/set_sharing.html",
@ -278,31 +238,13 @@
"public/js/frappe/form/templates/form_dashboard.html",
"public/js/frappe/form/templates/form_document_flow.html",
"public/js/frappe/form/templates/form_links.html",
"public/js/frappe/form/templates/attachment.html",
"public/js/frappe/form/templates/form_footer.html",
"public/js/frappe/form/templates/timeline.html",
"public/js/frappe/form/templates/timeline_item.html",
"public/js/frappe/form/controls/control.js",
"public/js/frappe/views/formview.js",
"public/js/legacy/form.js",
"public/js/legacy/client_script_helpers.js",
"public/js/frappe/form/toolbar.js",
"public/js/frappe/form/dashboard.js",
"public/js/frappe/form/save.js",
"public/js/frappe/form/script_manager.js",
"public/js/frappe/form/linked_with.js",
"public/js/frappe/form/workflow.js",
"public/js/frappe/form/print.js",
"public/js/frappe/form/form_sidebar.js",
"public/js/frappe/form/user_image.js",
"public/js/frappe/form/share.js",
"public/js/frappe/form/review.js",
"public/js/frappe/form/form_viewers.js",
"public/js/frappe/form/footer/attachment.html",
"public/js/frappe/form/footer/form_footer.html",
"public/js/frappe/form/footer/timeline.html",
"public/js/frappe/form/footer/timeline_item.html",
"public/js/frappe/form/footer/footer.js",
"public/js/frappe/form/footer/attachments.js",
"public/js/frappe/form/footer/timeline.js",
"public/js/frappe/form/footer/assign_to.js",
"public/js/frappe/form/quick_entry.js",
"public/js/frappe/form/success_action.js",
"public/js/frappe/form/form.js",
"public/js/frappe/meta_tag.js"
],
"css/list.min.css": [
@ -369,7 +311,7 @@
"public/js/frappe/ui/group_by/group_by.js"
],
"js/web_form.min.js": [
"public/js/frappe/misc/datetime.js",
"public/js/frappe/utils/datetime.js",
"website/js/web_form.js",
"public/js/lib/datepicker/datepicker.min.js",
"public/js/lib/datepicker/datepicker.en.js"
@ -383,11 +325,6 @@
"public/less/form_grid.less",
"public/less/controls.less"
],
"js/print_format_v3.min.js": [
"public/js/legacy/layout.js",
"public/js/legacy/print_table.js",
"public/js/legacy/print_format.js"
],
"frappe/css/email.css": [
"public/less/email.less"
],

View file

@ -9,7 +9,7 @@ import './socketio_client'
import './ui/dialog'
import './ui/capture'
import './misc/user'
import './utils/user'
/* eslint semi: "never" */
// Fuck semicolons - https://mislav.net/2010/05/semicolons

View file

@ -339,90 +339,3 @@ $(window).on('offline', function() {
message: __('Connection lost. Some features might not work.')
});
});
// add <option> list to <select>
(function($) {
$.fn.add_options = function(options_list) {
// create options
for(var i=0, j=options_list.length; i<j; 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);
var is_disabled = Boolean(v.disabled);
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)
.prop('disabled', is_disabled)
.appendTo(this);
}
// select the first option
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;
}
});
// For Opera, which only allows suppression of keypress events, not keydown
$(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);

View file

@ -1,13 +1,3 @@
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 {
// eslint-disable-next-line
console.log("Invalid Control Name: " + opts.df.fieldtype);
}
};
frappe.ui.form.Control = Class.extend({
init: function(opts) {
$.extend(this, opts);

View file

@ -0,0 +1,50 @@
import './base_control';
import './base_input';
import './data';
import './int';
import './float';
import './currency';
import './date';
import './time';
import './datetime';
import './date_range';
import './select';
import './link';
import './dynamic_link';
import './text';
import './code';
import './text_editor';
import './comment';
import './check';
import './image';
import './attach';
import './attach_image';
import './table';
import './color';
import './signature';
import './password';
import './read_only';
import './button';
import './html';
import './markdown_editor';
import './html_editor';
import './heading';
import './autocomplete';
import './barcode';
import './geolocation';
import './multiselect';
import './multicheck';
import './table_multiselect';
import './multiselect_pills';
import './rating';
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 {
// eslint-disable-next-line
console.log("Invalid Control Name: " + opts.df.fieldtype);
}
};

View file

@ -1,6 +1,8 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
import './timeline.js';
frappe.ui.form.Footer = Class.extend({
init: function(opts) {
var me = this;

View file

@ -1,5 +1,17 @@
frappe.provide('frappe.ui.form');
import './quick_entry';
import './toolbar';
import './dashboard';
import './workflow';
import './save';
import './print';
import './success_action';
import './script_manager';
import './script_helpers';
import './sidebar/form_sidebar';
import './footer/footer';
frappe.ui.form.Controller = Class.extend({
init: function(opts) {
$.extend(this, opts);
@ -283,7 +295,9 @@ frappe.ui.form.Form = class FrappeForm {
// record switch
if(this.docname != docname && (!this.meta.in_dialog || this.in_form) && !this.meta.istable) {
frappe.utils.scroll_to(0);
this.print_preview.hide();
if (this.print_preview) {
this.print_preview.hide();
}
}
// reset visible columns, since column headings can change in different docs
this.grids.forEach(grid_obj => grid_obj.grid.visible_columns = null);
@ -425,8 +439,8 @@ frappe.ui.form.Form = class FrappeForm {
}
}
if(this.meta.autoname && this.meta.autonathis.substr(0,6)=='field:' && !this.doc.__islocal) {
var fn = this.meta.autonathis.substr(6);
if(this.meta.autoname && this.meta.autoname.substr(0,6)=='field:' && !this.doc.__islocal) {
var fn = this.meta.autoname.substr(6);
if (this.doc[fn]) {
this.toggle_display(fn, false);
@ -643,7 +657,7 @@ frappe.ui.form.Form = class FrappeForm {
// HELPERS
enable_save = function() {
enable_save() {
this.save_disabled = false;
this.toolbar.set_primary_action();
}
@ -1189,7 +1203,7 @@ frappe.ui.form.Form = class FrappeForm {
return frappe.ui.form.get_open_grid_form();
}
get_title = function() {
get_title() {
if(this.meta.title_field) {
return this.doc[this.meta.title_field];
} else {
@ -1215,7 +1229,7 @@ frappe.ui.form.Form = class FrappeForm {
return selected;
}
set_indicator_formatter = function(fieldname, get_color, get_text) {
set_indicator_formatter(fieldname, get_color, get_text) {
// get doctype from parent
var doctype;
if(frappe.meta.docfield_map[this.doctype][fieldname]) {

View file

@ -1,6 +1,5 @@
import '../class';
frappe.provide("frappe.ui.form");
frappe.ui.form.Layout = Class.extend({
init: function(opts) {
this.views = {};

View file

@ -1,7 +1,6 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
frappe.provide("frappe.ui.form");
frappe.ui.form.LinkedWith = class LinkedWith {

View file

@ -1,4 +1,4 @@
frappe.provide("frappe.ui.form");
frappe.ui.form.PrintPreview = Class.extend({
init: function (opts) {
@ -55,34 +55,24 @@ frappe.ui.form.PrintPreview = Class.extend({
});
this.wrapper.find(".btn-print-print").click(function () {
if (me.is_old_style()) {
me.print_old_style();
} else {
me.printit();
}
me.printit();
});
this.wrapper.find(".btn-print-preview").click(function () {
if (me.is_old_style()) {
me.new_page_preview_old_style();
} else {
me.new_page_preview();
}
me.new_page_preview();
});
this.wrapper.find(".btn-download-pdf").click(function () {
if (!me.is_old_style()) {
var w = window.open(
frappe.urllib.get_full_url("/api/method/frappe.utils.print_format.download_pdf?"
+ "doctype=" + encodeURIComponent(me.frm.doc.doctype)
+ "&name=" + encodeURIComponent(me.frm.doc.name)
+ "&format=" + me.selected_format()
+ "&no_letterhead=" + (me.with_letterhead() ? "0" : "1")
+ (me.lang_code ? ("&_lang=" + me.lang_code) : ""))
);
if (!w) {
frappe.msgprint(__("Please enable pop-ups")); return;
}
var w = window.open(
frappe.urllib.get_full_url("/api/method/frappe.utils.print_format.download_pdf?"
+ "doctype=" + encodeURIComponent(me.frm.doc.doctype)
+ "&name=" + encodeURIComponent(me.frm.doc.name)
+ "&format=" + me.selected_format()
+ "&no_letterhead=" + (me.with_letterhead() ? "0" : "1")
+ (me.lang_code ? ("&_lang=" + me.lang_code) : ""))
);
if (!w) {
frappe.msgprint(__("Please enable pop-ups")); return;
}
});
@ -149,12 +139,7 @@ frappe.ui.form.PrintPreview = Class.extend({
},
multilingual_preview: function () {
var me = this;
if (this.is_old_style()) {
me.wrapper.find(".btn-print-preview").toggle(true);
me.wrapper.find(".btn-download-pdf").toggle(false);
me.set_style();
me.preview_old_style();
} else if (this.is_raw_printing()) {
if (this.is_raw_printing()) {
me.wrapper.find(".btn-print-preview").toggle(false);
me.wrapper.find(".btn-download-pdf").toggle(false);
me.preview();
@ -345,51 +330,15 @@ frappe.ui.form.PrintPreview = Class.extend({
return {};
}
},
preview_old_style: function () {
var me = this;
this.with_old_style({
format: me.print_sel.val(),
callback: function (html) {
me.wrapper.find(".print-format").html('<div class="alert alert-warning">'
+ __("Warning: This Print Format is in old style and cannot be generated via the API.")
+ '</div>'
+ html);
},
no_letterhead: !this.with_letterhead(),
only_body: true,
no_heading: true
});
},
refresh_print_options: function () {
this.print_formats = frappe.meta.get_print_formats(this.frm.doctype);
return this.print_sel
.empty().add_options(this.print_formats);
},
with_old_style: function (opts) {
frappe.require("/assets/js/print_format_v3.min.js", function () {
_p.build(opts.format, opts.callback, opts.no_letterhead, opts.only_body, opts.no_heading);
});
},
print_old_style: function () {
var me = this;
frappe.require("/assets/js/print_format_v3.min.js", function () {
_p.build(me.print_sel.val(), _p.go,
!me.with_letterhead());
});
},
new_page_preview_old_style: function () {
var me = this;
frappe.require("/assets/js/print_format_v3.min.js", function () {
_p.build(me.print_sel.val(), _p.preview, !me.with_letterhead());
});
},
selected_format: function () {
return this.print_sel.val() || this.frm.meta.default_print_format || "Standard";
},
is_old_style: function (format) {
return this.get_print_format(format).print_format_type === "Client";
},
is_raw_printing: function (format) {
return this.get_print_format(format).raw_printing === 1;
},

View file

@ -1,7 +1,7 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
frappe.provide("frappe.ui.form");
frappe.ui.form.save = function (frm, action, callback, btn) {
$(btn).prop("disabled", true);

View file

@ -1,7 +1,7 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
frappe.provide("frappe.ui.form");
frappe.ui.form.AssignTo = Class.extend({
init: function(opts) {

View file

@ -1,7 +1,7 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
frappe.provide("frappe.ui.form");
frappe.ui.form.Attachments = Class.extend({
init: function(opts) {

View file

@ -1,4 +1,13 @@
frappe.provide("frappe.ui.form");
import './assign_to';
import './attachments';
import './share';
import './review';
import './document_follow';
import './user_image';
import './form_viewers';
frappe.ui.form.Sidebar = Class.extend({
init: function(opts) {
$.extend(this, opts);

View file

@ -1,4 +1,4 @@
frappe.provide("frappe.ui.form");
frappe.ui.form.Viewers = Class.extend({
init: function(opts) {

View file

@ -1,7 +1,7 @@
// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
frappe.provide("frappe.ui.form");
frappe.ui.form.Review = class Review {
constructor({parent, frm}) {

View file

@ -1,7 +1,7 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
frappe.provide("frappe.ui.form");
frappe.ui.form.Share = Class.extend({
init: function(opts) {

View file

@ -1,12 +0,0 @@
<div class="document-flow">
{% for dt in doctypes %}
<span class="document-flow-link-wrapper">
<a data-doctype="{{ dt }}"
class="document-flow-link {% if (dt===frm.doctype) { %} strong disabled {% } %} "
style="color: inherit;">
<span class="indicator {% if (dt===frm.doctype) { %} blue {% } else { %} darkgrey {% } %}"></span><br>
<span class="document-flow-link-label">{{ __(dt) }}</span>
</a>
</span>
{% endfor %}
</div>

View file

@ -1,7 +1,7 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
import './linked_with';
frappe.provide("frappe.ui.form");
frappe.ui.form.Toolbar = Class.extend({
init: function(opts) {
$.extend(this, opts);

View file

@ -1,152 +0,0 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
import showdown from 'showdown';
frappe.provide("frappe.tools");
frappe.tools.downloadify = function(data, roles, title) {
if(roles && roles.length && !has_common(roles, roles)) {
frappe.msgprint(__("Export not allowed. You need {0} role to export.", [frappe.utils.comma_or(roles)]));
return;
}
var filename = title + ".csv";
var csv_data = frappe.tools.to_csv(data);
var a = document.createElement('a');
if ("download" in a) {
// Used Blob object, because it can handle large files
var blob_object = new Blob([csv_data], { type: 'text/csv;charset=UTF-8' });
a.href = URL.createObjectURL(blob_object);
a.download = filename;
} else {
// use old method
a.href = 'data:attachment/csv,' + encodeURIComponent(csv_data);
a.download = filename;
a.target = "_blank";
}
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};
frappe.markdown = function(txt) {
if(!frappe.md2html) {
frappe.md2html = new showdown.Converter();
}
while(txt.substr(0,1)==="\n") {
txt = txt.substr(1);
}
// remove leading tab (if they exist in the first line)
var whitespace_len = 0,
first_line = txt.split("\n")[0];
while(["\n", "\t"].indexOf(first_line.substr(0,1))!== -1) {
whitespace_len++;
first_line = first_line.substr(1);
}
if(whitespace_len && whitespace_len != first_line.length) {
var txt1 = [];
$.each(txt.split("\n"), function(i, t) {
txt1.push(t.substr(whitespace_len));
})
txt = txt1.join("\n");
}
return frappe.md2html.makeHtml(txt);
}
frappe.tools.to_csv = function(data) {
var res = [];
$.each(data, function(i, row) {
row = $.map(row, function(col) {
if (col === null || col === undefined) col = '';
return typeof col === "string" ? ('"' + $('<i>').html(col.replace(/"/g, '""')).text() + '"') : col;
});
res.push(row.join(","));
});
return res.join("\n");
};
frappe.slickgrid_tools = {
get_filtered_items: function(dataView) {
var data = [];
for (var i=0, len=dataView.getLength(); i<len; i++) {
// remove single quotes at start and end of total labels when print/pdf
var obj = dataView.getItem(i);
for (var item in obj) {
if(obj.hasOwnProperty(item) && typeof(obj[item]) == "string"
&& obj[item].charAt(0) == "'" && obj[item].charAt(obj[item].length -1) == "'") {
dataView.getItem(i)[item] = obj[item].substr(1, obj[item].length-2);
}
}
data.push(dataView.getItem(i));
}
return data;
},
get_view_data: function(columns, dataView, filter) {
var col_row = $.map(columns, function(v) { return v.name; });
var res = [];
var col_map = $.map(columns, function(v) { return v.field; });
for (var i=0, len=dataView.length; i<len; i++) {
var d = dataView[i];
var row = [];
$.each(col_map, function(i, col) {
var val = d[col];
if(val===null || val===undefined) {
val = "";
}
if(typeof(val) == "string") {
// export to csv and get first or second column of the grid indented if it is. e.g: account_name
if((i<3) && d['indent'] > 0 && (isNaN((new Date(val)).valueOf()))) {
val = " ".repeat(d['indent'] * 8) + val;
}
// remove single quotes at start and end of total labels when export to csv
if(val.charAt(0) == "'" && val.charAt(val.length -1) == "'") {
val = val.substr(1, val.length-2);
}
}
row.push(val);
});
if(!filter || filter(row, d)) {
res.push(row);
}
}
return [col_row].concat(res);
},
add_property_setter_on_resize: function(grid) {
grid.onColumnsResized.subscribe(function(e, args) {
$.each(grid.getColumns(), function(i, col) {
if(col.docfield && col.previousWidth != col.width &&
!in_list(frappe.model.std_fields_list, col.docfield.fieldname) ) {
frappe.call({
method:"frappe.client.make_width_property_setter",
args: {
doc: {
doctype:'Property Setter',
doctype_or_field: 'DocField',
doc_type: col.docfield.parent,
field_name: col.docfield.fieldname,
property: 'width',
value: col.width,
"__islocal": 1
}
}
});
col.previousWidth = col.width;
col.docfield.width = col.width;
}
});
});
}
};

View file

@ -23,7 +23,29 @@ frappe.provide("locals");
frappe.provide("frappe.flags");
frappe.provide("frappe.settings");
frappe.provide("frappe.utils");
frappe.provide("frappe.ui");
frappe.provide("frappe.ui.form");
frappe.provide("frappe.modules");
frappe.provide("frappe.templates");
frappe.provide("frappe.test_data");
frappe.provide('frappe.desk.form');
frappe.provide('frappe.desk.report');
frappe.provide('frappe.utils');
frappe.provide('frappe.model');
frappe.provide('frappe.user');
frappe.provide('frappe.session');
frappe.provide('locals.DocType');
// for listviews
frappe.provide("frappe.listview_settings");
frappe.provide("frappe.listview_parent_route");
// constants
window.NEWLINE = '\n';
window.TAB = 9;
window.UP_ARROW = 38;
window.DOWN_ARROW = 40;
// proxy for user globals defined in desk.js
// API globals
window.cur_frm=null;

View file

@ -1,18 +1,25 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
frappe.utils.full_name = function(fn, ln) {
return fn + (ln ? ' ' : '') + (ln ? ln : '')
window.cstr = function(s) {
if(s==null)return '';
return s+'';
}
function fmt_money(v, format){
// deprecated!
// for backward compatibility
return format_currency(v, format);
window.cint = function(v, def) {
if (v === true)
return 1;
if (v === false)
return 0;
v = v + '';
if (v !== "0") v = lstrip(v, ['0']);
v = parseInt(v);
if (isNaN(v)) v = def === undefined ? 0 : def;
return v;
}
// to title case
function toTitle(str){
window.toTitle = function(str){
var word_in = str.split(" ");
var word_out = [];
@ -23,25 +30,21 @@ function toTitle(str){
return word_out.join(" ");
}
function is_null(v) {
window.is_null = function(v) {
if(v===null || v===undefined || cstr(v).trim()==="") return true;
}
function copy_dict(d) {
window.copy_dict = function(d) {
var n = {};
for(var k in d) n[k] = d[k];
return n;
}
function validate_email(txt) {
window.validate_email = function(txt) {
return frappe.utils.validate_type(txt, "email");
}
function cstr(s) {
if(s==null)return '';
return s+'';
}
function nth(number) {
window.nth = function(number) {
number = cint(number);
var s = 'th';
if((number+'').substr(-1)=='1') s = 'st';
@ -50,7 +53,7 @@ function nth(number) {
return number+s;
}
function has_words(list, item) {
window.has_words = function(list, item) {
if(!item) return true;
if(!list) return false;
for(var i=0, j=list.length; i<j; i++) {
@ -60,23 +63,10 @@ function has_words(list, item) {
return false;
}
function has_common(list1, list2) {
window.has_common = function(list1, list2) {
if(!list1 || !list2) return false;
for(var i=0, j=list1.length; i<j; i++) {
if(in_list(list2, list1[i]))return true;
}
return false;
}
Object.assign(window, {
fmt_money,
toTitle,
is_null,
copy_dict,
validate_email,
cstr,
nth,
has_words,
has_common,
});
}

View file

@ -0,0 +1,39 @@
// add <option> list to <select>
(function($) {
$.fn.add_options = function(options_list) {
// create options
for(var i=0, j=options_list.length; i<j; 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);
var is_disabled = Boolean(v.disabled);
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)
.prop('disabled', is_disabled)
.appendTo(this);
}
// select the first option
this.selectedIndex = 0;
return $(this);
}
$.fn.set_working = function() {
this.prop('disabled', true);
}
$.fn.done_working = function() {
this.prop('disabled', false);
}
})(jQuery);

View file

@ -1,6 +1,8 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
import './datatype';
if (!window.frappe) window.frappe = {};
function flt(v, decimals, number_format) {
@ -28,18 +30,6 @@ function flt(v, decimals, number_format) {
return v;
}
function cint(v, def) {
if (v === true)
return 1;
if (v === false)
return 0;
v = v + '';
if (v !== "0") v = lstrip(v, ['0']);
v = parseInt(v);
if (isNaN(v)) v = def === undefined ? 0 : def;
return v;
}
function strip_number_groups(v, number_format) {
if (!number_format) number_format = get_number_format();
var info = get_number_format_info(number_format);
@ -231,11 +221,19 @@ function round_based_on_smallest_currency_fraction(value, currency, precision) {
return value;
}
function fmt_money(v, format){
// deprecated!
// for backward compatibility
return format_currency(v, format);
}
Object.assign(window, {
flt,
cint,
strip_number_groups,
format_currency,
fmt_money,
get_currency_symbol,
get_number_format,
get_number_format_info,

View file

@ -0,0 +1,76 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
import showdown from 'showdown';
frappe.provide("frappe.tools");
frappe.tools.downloadify = function(data, roles, title) {
if(roles && roles.length && !has_common(roles, roles)) {
frappe.msgprint(__("Export not allowed. You need {0} role to export.", [frappe.utils.comma_or(roles)]));
return;
}
var filename = title + ".csv";
var csv_data = frappe.tools.to_csv(data);
var a = document.createElement('a');
if ("download" in a) {
// Used Blob object, because it can handle large files
var blob_object = new Blob([csv_data], { type: 'text/csv;charset=UTF-8' });
a.href = URL.createObjectURL(blob_object);
a.download = filename;
} else {
// use old method
a.href = 'data:attachment/csv,' + encodeURIComponent(csv_data);
a.download = filename;
a.target = "_blank";
}
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};
frappe.markdown = function(txt) {
if(!frappe.md2html) {
frappe.md2html = new showdown.Converter();
}
while(txt.substr(0,1)==="\n") {
txt = txt.substr(1);
}
// remove leading tab (if they exist in the first line)
var whitespace_len = 0,
first_line = txt.split("\n")[0];
while(["\n", "\t"].indexOf(first_line.substr(0,1))!== -1) {
whitespace_len++;
first_line = first_line.substr(1);
}
if(whitespace_len && whitespace_len != first_line.length) {
var txt1 = [];
$.each(txt.split("\n"), function(i, t) {
txt1.push(t.substr(whitespace_len));
})
txt = txt1.join("\n");
}
return frappe.md2html.makeHtml(txt);
};
frappe.tools.to_csv = function(data) {
var res = [];
$.each(data, function(i, row) {
row = $.map(row, function(col) {
if (col === null || col === undefined) col = '';
return typeof col === "string" ? ('"' + $('<i>').html(col.replace(/"/g, '""')).text() + '"') : col;
});
res.push(row.join(","));
});
return res.join("\n");
};

View file

@ -0,0 +1,80 @@
frappe.urllib = {
// get argument from url
get_arg: function(name) {
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if( results == null )
return "";
else
return decodeURIComponent(results[1]);
},
// returns url dictionary
get_dict: function() {
var d = {}
var t = window.location.href.split('?')[1];
if(!t) return d;
if(t.indexOf('#')!=-1) t = t.split('#')[0];
if(!t) return d;
t = t.split('&');
for(var i=0; i<t.length; i++) {
var a = t[i].split('=');
d[decodeURIComponent(a[0])] = decodeURIComponent(a[1]);
}
return d;
},
// returns the base url with http + domain + path (-index.cgi or # or ?)
get_base_url: function() {
// var url= (frappe.base_url || window.location.href).split('#')[0].split('?')[0].split('desk')[0];
var url = (frappe.base_url || window.location.origin)
if(url.substr(url.length-1, 1)=='/') url = url.substr(0, url.length-1)
return url
},
// returns absolute url
get_full_url: function(url) {
if(url.indexOf("http://")===0 || url.indexOf("https://")===0) {
return url;
}
return url.substr(0,1)==="/" ?
(frappe.urllib.get_base_url() + url) :
(frappe.urllib.get_base_url() + "/" + url);
}
};
window.open_url_post = function open_url_post(URL, PARAMS, new_window) {
if (window.cordova) {
let url = URL + 'api/method/' + PARAMS.cmd + frappe.utils.make_query_string(PARAMS, false);
window.location.href = url;
} else {
// call a url as POST
var temp=document.createElement("form");
temp.action=URL;
temp.method="POST";
temp.style.display="none";
if(new_window){
temp.target = '_blank';
}
PARAMS["csrf_token"] = frappe.csrf_token;
for(var x in PARAMS) {
var opt=document.createElement("textarea");
opt.name=x;
var val = PARAMS[x];
if(typeof val!='string')
val = JSON.stringify(val);
opt.value=val;
temp.appendChild(opt);
}
document.body.appendChild(temp);
temp.submit();
return temp;
}
};
window.get_url_arg = frappe.urllib.get_arg;
window.get_url_dict = frappe.urllib.get_dict;

View file

@ -1,168 +0,0 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
function empty_select(s) {
if(s.custom_select) { s.empty(); return; }
if(s.inp)s = s.inp;
if(s) {
var tmplen = s.length; for(var i=0;i<tmplen; i++) s.options[0] = null;
}
}
function sel_val(s) {
if(s.custom_select) {
return s.inp.value ? s.inp.value : '';
}
if(s.inp)s = s.inp;
try {
if(s.selectedIndex<s.options.length) return s.options[s.selectedIndex].value;
else return '';
} catch(err) { return ''; /* IE fix */ }
}
var $n = '\n';
function $a(parent, newtag, className, cs, innerHTML, onclick) {
if(parent && parent.substr)parent = $i(parent);
var c = document.createElement(newtag);
if(parent)
parent.appendChild(c);
// if image, 3rd parameter is source
if(className) {
if(newtag.toLowerCase()=='img')
c.src = className
else
c.className = className;
}
if(cs)$y(c,cs);
if(innerHTML) c.innerHTML = innerHTML;
if(onclick) c.onclick = onclick;
return c;
}
function $dh(d) {
if(d && d.substr)d=$i(d);
if(d && d.style.display.toLowerCase() != 'none') d.style.display = 'none';
}
function $ds(d) {
if(d && d.substr)d=$i(d);
var t = 'block';
if(d && in_list(['span','img','button'], d.tagName.toLowerCase()))
t = 'inline'
if(d && d.style.display.toLowerCase() != t)
d.style.display = t;
}
function $di(d) { if(d && d.substr)d=$i(d); if(d)d.style.display = 'inline'; }
function $i(id) {
if(!id) return null;
if(id && id.appendChild)return id; // already an element
return document.getElementById(id);
}
function $w(e,w) { if(e && e.style && w)e.style.width = w; }
function $h(e,h) { if(e && e.style && h)e.style.height = h; }
function $bg(e,w) { if(e && e.style && w)e.style.backgroundColor = w; }
function $y(ele, s) {
if(ele && s) {
for(var i in s) ele.style[i]=s[i];
}
return ele;
}
// Make table
function make_table(parent, nr, nc, table_width, widths, cell_style, table_style) {
var t = $a(parent, 'table');
t.style.borderCollapse = 'collapse';
if(table_width) t.style.width = table_width;
if(cell_style) t.cell_style=cell_style;
for(var ri=0;ri<nr;ri++) {
var r = t.insertRow(ri);
for(var ci=0;ci<nc;ci++) {
var c = r.insertCell(ci);
if(ri==0 && widths && widths[ci]) {
// set widths
c.style.width = widths[ci];
}
if(cell_style) {
for(var s in cell_style) c.style[s] = cell_style[s];
}
}
}
t.append_row = function() { return append_row(this); }
if(table_style) $y(t, table_style);
return t;
}
function append_row(t, at, style) {
var r = t.insertRow(at ? at : t.rows.length);
if(t.rows.length>1) {
for(var i=0;i<t.rows[0].cells.length;i++) {
var c = r.insertCell(i);
if(style) $y(c, style);
}
}
return r
}
function $td(t,r,c) {
if(r<0)r=t.rows.length+r;
if(c<0)c=t.rows[0].cells.length+c;
return t.rows[r].cells[c];
}
// URL utilities
frappe.urllib = {
// get argument from url
get_arg: function(name) {
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if( results == null )
return "";
else
return decodeURIComponent(results[1]);
},
// returns url dictionary
get_dict: function() {
var d = {}
var t = window.location.href.split('?')[1];
if(!t) return d;
if(t.indexOf('#')!=-1) t = t.split('#')[0];
if(!t) return d;
t = t.split('&');
for(var i=0; i<t.length; i++) {
var a = t[i].split('=');
d[decodeURIComponent(a[0])] = decodeURIComponent(a[1]);
}
return d;
},
// returns the base url with http + domain + path (-index.cgi or # or ?)
get_base_url: function() {
// var url= (frappe.base_url || window.location.href).split('#')[0].split('?')[0].split('desk')[0];
var url = (frappe.base_url || window.location.origin)
if(url.substr(url.length-1, 1)=='/') url = url.substr(0, url.length-1)
return url
},
// returns absolute url
get_full_url: function(url) {
if(url.indexOf("http://")===0 || url.indexOf("https://")===0) {
return url;
}
return url.substr(0,1)==="/" ?
(frappe.urllib.get_base_url() + url) :
(frappe.urllib.get_base_url() + "/" + url);
}
}
window.get_url_arg = frappe.urllib.get_arg;
window.get_url_dict = frappe.urllib.get_dict;

View file

@ -1,38 +0,0 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
frappe.provide('frappe.desk.form');
frappe.provide('frappe.desk.report');
frappe.provide('frappe.utils');
frappe.provide('frappe.model');
frappe.provide('frappe.user');
frappe.provide('frappe.session');
frappe.provide('locals');
frappe.provide('locals.DocType');
// for listviews
frappe.provide("frappe.listview_settings");
frappe.provide("frappe.listview_parent_route");
// setup custom binding for history
frappe.settings.no_history = 1;
// constants
window.NEWLINE = '\n';
window.TAB = 9;
window.UP_ARROW = 38;
window.DOWN_ARROW = 40;
// proxy for user globals defined in desk.js
// Name Spaces
// ============
// form
window._f = {};
window._p = {};
window._r = {};
// API globals
window.frms={};
window.cur_frm=null;

View file

@ -1,73 +0,0 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
/* eslint-disable no-console */
function $c(command, args, callback, error, no_spinner, freeze_msg, btn) {
console.warn("This function '$c' has been deprecated and will be removed soon.");
return frappe.request.call({
type: "POST",
args: $.extend(args, {cmd: command}),
success: callback,
error: error,
btn: btn,
freeze: freeze_msg,
show_spinner: !no_spinner
});
}
// For calling an for output as csv
function $c_obj_csv(doc, method, arg) {
console.warn("This function '$c_obj_csv' has been deprecated and will be removed soon.");
// single
var args = {};
args.cmd = 'runserverobj';
args.as_csv = 1;
args.method = method;
args.arg = arg;
if(doc.substr)
args.doctype = doc;
else
args.docs = doc;
// open
open_url_post(frappe.request.url, args);
}
window.open_url_post = function open_url_post(URL, PARAMS, new_window) {
if (window.cordova) {
let url = URL + 'api/method/' + PARAMS.cmd + frappe.utils.make_query_string(PARAMS, false);
window.location.href = url;
} else {
// call a url as POST
_open_url_post(URL, PARAMS, new_window);
}
};
function _open_url_post(URL, PARAMS, new_window) {
var temp=document.createElement("form");
temp.action=URL;
temp.method="POST";
temp.style.display="none";
if(new_window){
temp.target = '_blank';
}
PARAMS["csrf_token"] = frappe.csrf_token;
for(var x in PARAMS) {
var opt=document.createElement("textarea");
opt.name=x;
var val = PARAMS[x];
if(typeof val!='string')
val = JSON.stringify(val);
opt.value=val;
temp.appendChild(opt);
}
document.body.appendChild(temp);
temp.submit();
return temp;
}
Object.assign(window, {
$c, $c_obj, $c_obj_csv
});

View file

@ -1,143 +0,0 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
/*
+ Layout
+ wrapper
+ LayoutRow
+ main_head
+ main_body
+ header
+ body
..
..
+ subrows
*/
window.Layout = function Layout(parent, width) {
if(parent&&parent.substr) { parent = $i(parent); }
this.wrapper = $a(parent, 'div', '', {display:'none'});
if(width) {
this.width = this.wrapper.style.width;
}
this.myrows = [];
}
Layout.prototype.addrow = function() {
this.cur_row = new LayoutRow(this, this.wrapper);
this.myrows[this.myrows.length] = this.cur_row;
return this.cur_row
}
Layout.prototype.addsubrow = function() {
this.cur_row = new LayoutRow(this, this.cur_row.main_body);
this.myrows[this.myrows.length] = this.cur_row;
return this.cur_row
}
Layout.prototype.addcell = function(width) {
return this.cur_row.addCell(width);
}
// eslint-disable-next-line
Layout.prototype.setcolour = function(col) { $bg(cc,col); }
Layout.prototype.show = function() { $(this.wrapper).toggle(false); }
Layout.prototype.hide = function() { $(this.wrapper).toggle(false); }
Layout.prototype.close_borders = function() {
if(this.with_border) {
this.myrows[this.myrows.length-1].wrapper.style.borderBottom = '1px solid #000';
}
}
function LayoutRow(layout, parent) {
this.layout = layout;
this.wrapper = $a(parent,'div','form-layout-row');
// main head
this.main_head = $a(this.wrapper, 'div');
// main head
this.main_body = $a(this.wrapper, 'div');
if(layout.with_border) {
this.wrapper.style.border = '1px solid #000';
this.wrapper.style.borderBottom = '0px';
}
this.header = $a(this.main_body, 'div','',{padding:(layout.with_border ? '0px 8px' : '0px')});
this.body = $a(this.main_body,'div');
this.table = $a(this.body, 'table', '', {width:'100%', borderCollapse: 'collapse', tableLayout:'fixed'});
this.row = this.table.insertRow(0);
this.mycells = [];
}
LayoutRow.prototype.hide = function() { $(this.wrapper).toggle(false); }
LayoutRow.prototype.show = function() { $(this.wrapper).toggle(true); }
LayoutRow.prototype.addCell = function(wid) {
var lc = new LayoutCell(this.layout, this, wid);
this.mycells[this.mycells.length] = lc;
return lc;
}
function LayoutCell(layout, layoutRow, width) {
if(width) { // add '%' if user has forgotten
var w = width + '';
if(w.substr(w.length-2, 2) != 'px') {
if(w.substr(w.length-1, 1) != "%") {width = width + '%'}
}
}
this.width = width;
this.layout = layout;
var cidx = layoutRow.row.cells.length;
this.cell = layoutRow.row.insertCell(cidx);
this.cell.style.verticalAlign = 'top';
this.set_width(layoutRow.row, width);
var h = $a(this.cell, 'div','',{padding:(layout.with_border ? '0px 8px' : '0px')});
this.wrapper = $a(this.cell, 'div','',{padding:(layout.with_border ? '8px' : '0px')});
layout.cur_cell = this.wrapper;
layout.cur_cell.header = h;
}
// evenly distribute columns
LayoutCell.prototype.set_width = function(row, width) {
var w = 100;
var n_cells = row.cells.length;
var cells_with_no_width = n_cells;
// current cell
if(width) {
$y(row.cells[n_cells-1], {width: cint(width) + '%'})
} else {
row.cells[n_cells-1].estimated_width = 1;
}
// get user specified width
for(var i=0; i<n_cells; i++) {
if(!row.cells[i].estimated_width) {
w = w - cint(row.cells[i].style.width);
cells_with_no_width--;
}
}
// evenly distribute all
for(var i=0; i<n_cells; i++) {
if(row.cells[i].estimated_width)
$y(row.cells[i], {width:cint(w/cells_with_no_width) + '%'})
}
}
LayoutCell.prototype.show = function() { $(this.wrapper).toggle(true); }
LayoutCell.prototype.hide = function() { $(this.wrapper).toggle(false); }

View file

@ -1,691 +0,0 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
// default print style
_p.def_print_style_body = "html, body, div, span, td, p { \
font-family: inherit; \
font-size: inherit; \
}\
.page-settings {\
font-family: Helvetica, 'Open Sans', sans-serif;\
font-size: 9pt;\
}\
pre { margin:0; padding:0;}";
_p.def_print_style_other = "\n.simpletable, .noborder { \
border-collapse: collapse;\
margin-bottom: 10px;\
}\
.simpletable td {\
border: 1pt solid #777;\
vertical-align: top;\
padding: 4px;\
}\
.noborder td {\
vertical-align: top;\
}";
_p.go = function(html) {
var w = _p.preview(html);
w.print();
w.close();
}
_p.preview = function(html) {
var w = window.open();
if(!w) {
frappe.msgprint(__("Please enable pop-ups"));
return;
}
w.document.write(html);
w.document.close();
return w
}
_f.get_value = function(dt, dn, fn) {
if(locals[dt] && locals[dt][dn])
return locals[dt][dn][fn];
}
// _p can be referenced as this inside $.extend
$.extend(_p, {
show_dialog: function() {
if(!_p.dialog) {
_p.make_dialog();
}
_p.dialog.show();
},
make_dialog: function() {
// Prepare Dialog Box Layout
var dialog = new frappe.ui.Dialog({
title: "Print Formats",
fields: [
{fieldtype:"Select", label:"Print Format", fieldname:"print_format", reqd:1},
{fieldtype:"Check", label:"No Letter Head", fieldname:"no_letterhead"},
{fieldtype:"HTML", options: '<p style="text-align: right;">\
<button class="btn btn-primary btn-print">Print</button>\
<button class="btn btn-default btn-preview">Preview</button>\
</p>'},
]
});
dialog.$wrapper.find(".btn-print").click(function() {
var args = dialog.get_values();
_p.build(
args.print_format, // fmtname
_p.go, // onload
args.no_letterhead // no_letterhead
);
});
dialog.$wrapper.find(".btn-preview").click(function() {
var args = dialog.get_values();
_p.build(
args.print_format, // fmtname
_p.preview, // onload
args.no_letterhead // no_letterhead
);
});
dialog.on_page_show = function() {
var $print = dialog.fields_dict.print_format.$input;
$print.empty().add_options(cur_frm.print_preview.print_formats);
if(cur_frm.$print_view_select && cur_frm.$print_view_select.val())
$print.val(cur_frm.$print_view_select.val());
}
_p.dialog = dialog;
},
// Define formats dict
formats: {},
/* args dict can contain:
+ fmtname --> print format name
+ onload
+ no_letterhead
+ only_body
*/
build: function(fmtname, onload, no_letterhead, only_body, no_heading) {
if(!fmtname) {
fmtname= "Standard";
}
var args = {
fmtname: fmtname,
onload: onload,
no_letterhead: no_letterhead,
only_body: only_body
};
if(!cur_frm) {
frappe.msgprint(__("No document selected"));
return;
}
if(!frappe.model.can_print(cur_frm.doctype, cur_frm)) {
frappe.msgprint(__("You are not allowed to print this document"));
return;
}
// Get current doc (record)
var doc = locals[cur_frm.doctype][cur_frm.docname];
if(args.fmtname == 'Standard') {
args.onload(_p.render({
body: _p.print_std(args.no_letterhead, no_heading),
style: _p.print_style,
doc: doc,
title: doc.name,
no_letterhead: args.no_letterhead,
no_heading: no_heading,
only_body: args.only_body
}));
} else {
var print_format_doc = locals["Print Format"][args.fmtname];
if(!print_format_doc) {
frappe.msgprint(__("Unknown Print Format: {0}", [args.fmtname]));
return;
}
args.onload(_p.render({
body: print_format_doc.html,
style: '',
doc: doc,
title: doc.name,
no_letterhead: args.no_letterhead,
no_heading: no_heading,
only_body: args.only_body
}));
}
},
render: function(args) {
var container = document.createElement('div');
var stat = '';
if(!args.no_heading) {
// if draft/archived, show draft/archived banner
stat += _p.show_draft(args);
stat += _p.show_archived(args);
stat += _p.show_cancelled(args);
}
// Append args.body's content as a child of container
container.innerHTML = args.body;
// Show letterhead?
_p.show_letterhead(container, args);
_p.run_embedded_js(container, args.doc);
var style = _p.consolidate_css(container, args);
_p.render_header_on_break(container, args);
return _p.render_final(style, stat, container, args);
},
head_banner_format: function() {
return "\
<div style = '\
text-align: center; \
padding: 8px; \
background-color: #CCC;'> \
<div style = '\
font-size: 20px; \
font-weight: bold;'>\
{{HEAD}}\
</div>\
{{DESCRIPTION}}\
</div>"
},
/*
Check if doc's status is not submitted (docstatus == 0)
and submission is pending
Display draft in header if true
*/
show_draft: function(args) {
var is_doctype_submittable = 0;
var plist = locals['DocPerm'];
for(var perm in plist) {
var p = plist[perm];
if((p.parent==args.doc.doctype) && (p.submit==1)){
is_doctype_submittable = 1;
break;
}
}
if(args.doc && cint(args.doc.docstatus)==0 && is_doctype_submittable) {
var draft = _p.head_banner_format();
draft = draft.replace("{{HEAD}}", "DRAFT");
draft = draft.replace("{{DESCRIPTION}}", "This box will go away after the document is submitted.");
return draft;
} else {
return "";
}
},
/*
Check if doc is archived
Display archived in header if true
*/
show_archived: function(args) {
if(args.doc && args.doc.__archived) {
var archived = _p.head_banner_format();
archived = archived.replace("{{HEAD}}", "ARCHIVED");
archived = archived.replace("{{DESCRIPTION}}", "You must restore this document to make it editable.");
return archived;
} else {
return "";
}
},
/*
Check if doc is cancelled
Display cancelled in header if true
*/
show_cancelled: function(args) {
if(args.doc && args.doc.docstatus==2) {
var cancelled = _p.head_banner_format();
cancelled = cancelled.replace("{{HEAD}}", "CANCELLED");
cancelled = cancelled.replace("{{DESCRIPTION}}", "You must amend this document to make it editable.");
return cancelled;
} else {
return "";
}
},
consolidate_css: function(container, args) {
// Extract <style> content from container
var body_style = '';
var style_list = container.getElementsByTagName('style');
while(style_list && style_list.length>0) {
for(var i in style_list) {
if(style_list[i] && style_list[i].innerHTML) {
body_style += style_list[i].innerHTML;
var parent = style_list[i].parentNode;
if(parent) {
parent.removeChild(style_list[i]);
} else {
container.removeChild(style_list[i]);
}
}
}
style_list = container.getElementsByTagName('style');
}
// Concatenate all styles
var style_concat = (args.only_body ? '' : _p.def_print_style_body)
+ _p.def_print_style_other + args.style + body_style;
return style_concat;
},
// This is used to calculate and substitude values in the HTML
run_embedded_js: function(container, doc) {
var script_list = $(container).find("script");
for(var i=0, j=script_list.length; i<j; i++) {
var element = script_list[i];
var code = element.innerHTML;
try {
var new_html = code ? (eval(code) || "") : "";
} catch(e) {
console.log("Error in Custom Script:" + e + "\n" + code);
console.trace(e);
throw e;
}
if(in_list(["string", "number"], typeof new_html)) {
$(element).replaceWith(this.add_span(new_html + ""));
}
}
// remove scripts once executed
$(container).find("script").remove();
},
add_span: function(html) {
var tags = ["<span", "<p", "<div", "<br", "<table"];
var match = false;
for(var i=0; i<tags.length; i++) {
if(html.match(tags[i])) {
match = true;
break;
}
}
if(!match) {
html = "<span>" + html + "</span>";
}
return html;
},
// Attach letterhead at top of container
show_letterhead: function(container, args) {
if(!args.no_letterhead) {
container.innerHTML = '<div style="max-width: 100%">'
+ _p.get_letter_head() + '</div>'
+ container.innerHTML;
}
},
render_header_on_break: function(container, args) {
var page_set = container.getElementsByClassName('page-settings');
if(page_set.length) {
for(var i = 0; i < page_set.length; i++) {
var tmp = '';
// if draft/archived, show draft/archived banner
tmp += _p.show_draft(args);
tmp += _p.show_archived(args);
_p.show_letterhead(page_set[i], args);
page_set[i].innerHTML = tmp + page_set[i].innerHTML;
}
}
},
// called by _p.render for final render of print
render_final: function(style, stat, container, args) {
if(!args.only_body) {
var header = '<!DOCTYPE html>\
<html>\
<head>\
<meta charset="utf-8" />\
<title>' + args.title + '</title>\
<style>' + style + '</style>\
</head>\
<body>';
var footer = '\
</body>\
</html>';
} else {
var header = '';
var footer = '';
}
var finished = header
+ '<div class="page-settings">'
+ stat
+ container.innerHTML
+ '</div>'
+ footer;
// replace relative links by absolute links
var prefix = window.location.href.split("desk")[0]
// find unique matches
var matches = $.unique(finished.match(/src=['"]([^'"]*)['"]/g) || []);
$.each(matches, function(i, v) {
if(v.substr(0,4)=="src=") {
var v = v.substr(5, v.length-6);
if(v.substr(0,4)!="http") {
finished = finished.split(v).join(prefix + lstrip(v, "/"));
}
}
});
return finished;
},
// fetches letter head from current doc or control panel
get_letter_head: function() {
var lh = '';
if(cur_frm.doc.letter_head) {
lh = cstr(frappe.boot.letter_heads[cur_frm.doc.letter_head].header);
} else if (frappe.boot.sysdefaults.default_letter_head_content) {
lh = frappe.boot.sysdefaults.default_letter_head_content;
}
return lh;
},
// common print style setting
print_style: "\
.datalabelcell { \
padding: 2px 0px; \
width: 38%; \
vertical-align: top; \
} \
.datainputcell { \
padding: 2px 0px; \
width: 62%; \
text-align: left; \
}\
.sectionHeading { \
font-size: 16px; \
font-weight: bold; \
margin: 8px 0px; \
} \
.columnHeading { \
font-size: 14px; \
font-weight: bold; \
margin: 8px 0px; \
}",
print_std: function(no_letterhead, no_heading) {
// Get doctype, docname, layout for a doctype
var docname = cur_frm.docname;
var doctype = cur_frm.doctype;
var data = frappe.get_children("DocType", doctype, "fields");
var layout = _p.add_layout(doctype);
this.pf_list = [layout];
var me = this;
me.layout = layout;
$.extend(this, {
build_head: function(data, doctype, docname) {
// Heading
var h1_style = {
fontSize: '22px',
marginBottom: '8px'
}
var h1 = $a(me.layout.cur_row.header, 'h1', '', h1_style);
// Get print heading
if (cur_frm.pformat[docname]) {
// first check in cur_frm.pformat
h1.innerHTML = cur_frm.pformat[docname];
} else {
// then check if select print heading exists and has a value
var val = null;
for (var i = 0; i < data.length; i++) {
if (data[i].fieldname === 'select_print_heading') {
val = _f.get_value(doctype, docname, data[i].fieldname);
break;
}
}
// if not, just have doctype has heading
h1.innerHTML = val ? val : __(doctype);
}
var h2_style = {
fontSize: '16px',
color: '#888',
marginBottom: '8px',
paddingBottom: '8px',
borderBottom: (me.layout.with_border ? '0px' :
'1px solid #000')
}
var h2 = $a(me.layout.cur_row.header, 'div', '', h2_style);
h2.innerHTML = docname;
if(cur_frm.state_fieldname && !cur_frm.fields_dict[cur_frm.state_fieldname].df.print_hide) {
$a(h2, 'br');
var span = $a(h2, 'span', '',
{padding: "3px", color: "#fff", backgroundColor: "#777",
display:"inline-block"});
span.innerHTML = cur_frm.doc[cur_frm.state_fieldname];
}
},
build_data: function(data, doctype, docname) {
// Start with a row and a cell in that row
if(data[0] && data[0].fieldtype != "Section Break") {
me.layout.addrow();
if(data[0].fieldtype != "Column Break") {
me.layout.addcell();
}
}
$.extend(this, {
generate_custom_html: function(field, doctype, docname) {
var container = $a(me.layout.cur_cell, 'div');
container.innerHTML = cur_frm.pformat[field.fieldname](locals[doctype][docname]);
},
render_normal: function(field, data, i) {
switch(field.fieldtype) {
case 'Fold': break;
case 'Section Break':
me.layout.addrow();
// Add column if no column break after this field
if(data[i+1] && data[i+1].fieldtype !=
'Column Break') {
me.layout.addcell();
}
break;
case 'Column Break':
me.layout.addcell(field.width, field.label);
break;
case 'Table':
var table = print_table(
doctype, // dt
docname, // dn
field.fieldname,
field.options, // tabletype
null, // cols
null, // head_labels
null, // widths
null); // condition
me.layout = _p.print_std_add_table(table, me.layout, me.pf_list, doctype, no_letterhead);
break;
case 'HTML':
var div = $a(me.layout.cur_cell, 'div');
div.innerHTML = cstr(field.options);
break;
case 'Code':
var div = $a(me.layout.cur_cell, 'div');
var val = _f.get_value(doctype, docname,
field.fieldname);
div.innerHTML = '<div>' + __(field.label) +
': </div><pre style="font-family: Courier, Fixed;">' + (val ? val : '') +
'</pre>';
break;
case 'Text Editor':
var div = $a(me.layout.cur_cell, 'div');
var val = _f.get_value(doctype, docname,
field.fieldname);
div.innerHTML = val ? val : '';
break;
default:
// Add Cell Data
_p.print_std_add_field(doctype, docname, field, me.layout);
break;
}
}
});
// Then build each field
for(var i = 0; i < data.length; i++) {
var fieldname = data[i].fieldname ? data[i].fieldname :
data[i].label;
var field = fieldname ?
frappe.meta.get_docfield(doctype, fieldname, docname) : data[i];
if(!field.print_hide) {
if(cur_frm.pformat[field.fieldname]) {
// If there is a custom method to generate the HTML, then use it
this.generate_custom_html(field, doctype, docname);
} else {
// Do the normal rendering
this.render_normal(field, data, i);
}
}
}
me.layout.close_borders();
},
build_html: function() {
var html = '';
for(var i = 0; i < me.pf_list.length; i++) {
if(me.pf_list[i].wrapper) {
html += me.pf_list[i].wrapper.innerHTML;
} else if(me.pf_list[i].innerHTML) {
html += me.pf_list[i].innerHTML;
} else {
html += me.pf_list[i];
}
}
this.pf_list = [];
return html;
}
});
if(!no_heading) {
this.build_head(data, doctype, docname);
}
this.build_data(data, doctype, docname);
var html = this.build_html();
return html;
},
add_layout: function(doctype) {
var layout = new Layout();
layout.addrow();
if(locals['DocType'][doctype].print_outline == 'Yes') {
layout.with_border = 1
}
return layout;
},
print_std_add_table: function(t, layout, pf_list, dt, no_letterhead) {
if(t.appendChild) {
// If only one table is passed
layout.cur_cell.appendChild(t);
} else {
var page_break = '\n\
<div style = "page-break-after: always;" \
class = "page_break"></div><div class="page-settings"></div>';
// If a list of tables is passed
for(var i = 0; i < t.length-1; i++) {
// add to current page
layout.cur_cell.appendChild(t[i]);
layout.close_borders();
pf_list.push(page_break);
// Create new page
layout = _p.add_layout(dt, no_letterhead);
pf_list.push(layout);
layout.addrow();
layout.addcell();
var div = $a(layout.cur_cell, 'div');
div.innerHTML = 'Continued from previous page...';
div.style.padding = '4px';
}
// Append last table
layout.cur_cell.appendChild(t[t.length-1]);
}
return layout;
},
print_std_add_field: function(dt, dn, f, layout) {
var val = _f.get_value(dt, dn, f.fieldname);
if(f.fieldtype!='Button') {
if(val || in_list(['Float', 'Int', 'Currency'], f.fieldtype)) {
// If value or a numeric type then proceed
// Add field table
var row = _p.field_tab(layout.cur_cell);
// Add label
row.cells[0].innerHTML = __(f.label ? f.label : f.fieldname);
row.cells[1].innerHTML = frappe.format(val, f, {for_print: true});
// left align currency in normal display
if(f.fieldtype == 'Currency') {
$y(row.cells[1], { textAlign: 'left' });
}
}
}
},
field_tab: function(layout_cell) {
var tab = $a(layout_cell, 'table', '', {width:'100%'});
var row = tab.insertRow(0);
_p.row = row; // Don't know this line's purpose
row.insertCell(0);
row.insertCell(1);
row.cells[0].className = 'datalabelcell';
row.cells[0].style.width = "38%";
row.cells[1].className = 'datainputcell';
return row;
}
});

View file

@ -1,208 +0,0 @@
frappe.printTable = Class.extend({
init: function(opts) {
$.extend(this, opts);
if(!this.columns)
this.columns = this.get_columns();
this.data = this.get_data();
this.remove_empty_cols();
this.set_widths();
this.make();
},
get_columns: function() {
var perms = frappe.perm.get_perm(this.doctype);
return ['Sr'].concat($.map(frappe.meta.docfield_list[this.tabletype], function(df) {
return (cint(df.print_hide) || !(perms[df.permlevel] &&
perms[df.permlevel].read)) ? null : df.fieldname;
}));
},
get_data: function() {
var children = frappe.get_doc(this.doctype, this.docname)[this.fieldname] || [];
var data = []
for(var i=0; i<children.length; i++) {
data.push(copy_dict(children[i]));
}
return data;
},
remove_empty_cols: function() {
var me = this;
var cols_with_value = [];
$.each(this.data, function(i, row) {
$.each(me.columns, function(ci, fieldname) {
var value = row[fieldname];
if(value || ci==0) {
if(cols_with_value.indexOf(ci)===-1) {
cols_with_value.push(ci);
}
}
});
});
var columns = [],
widths = [],
head_labels = [];
// sort by col index, asc
cols_with_value.sort(function(a, b) { return a - b; });
// make new arrays to remove empty cols, widths and head labels
$.each(cols_with_value, function(i, col_idx) {
columns.push(me.columns[col_idx]);
me.widths && widths.push(me.widths[col_idx]);
me.head_labels && head_labels.push(me.head_labels[col_idx]);
});
this.columns = columns;
if(this.widths) this.widths = widths;
if(this.head_labels) this.head_labels = head_labels;
},
make: function() {
var me = this;
this.tables = [];
var table_data = [];
$.each(this.data, function(i, d) {
table_data.push(d);
if(d.page_break) {
me.add_table(table_data);
table_data = [];
}
});
if(table_data)
me.add_table(table_data);
},
add_table: function(data) {
var me = this;
var wrapper = $("<div>")
var table = $("<table>").css(this.table_style).appendTo(wrapper);
var headrow = $("<tr>").appendTo(table);
$.each(me.columns, function(ci, fieldname) {
var df = frappe.meta.docfield_map[me.tabletype][fieldname];
if(me.head_labels) {
var label = me.head_labels[ci];
} else {
var label = df ? df.label : fieldname;
}
var td = $("<td>").html(__(label))
.css(me.head_cell_style)
.css({"width": me.widths[ci]})
.appendTo(headrow)
if(df && in_list(['Float', 'Currency'], df.fieldtype)) {
td.css({"text-align": "right"});
}
});
$.each(data, function(ri, row) {
var allow = true;
if(me.condition) {
allow = me.condition(row);
}
if(allow) {
var tr = $("<tr>").appendTo(table);
$.each(me.columns, function(ci, fieldname) {
if(fieldname.toLowerCase()==="sr")
var value = row.idx;
else
var value = row[fieldname];
var df = frappe.meta.docfield_map[me.tabletype][fieldname];
value = frappe.format(value, df, {for_print:true});
// set formatted value back into data so that modifer can use it
row[fieldname] = value;
// modifier is called after formatting so that
// modifier's changes do not get lost in formatting (eg. 3.45%)
if(me.modifier && me.modifier[fieldname])
value = me.modifier[fieldname](row);
var td = $("<td>").html(value)
.css(me.cell_style)
.css({width: me.widths[ci]})
.appendTo(tr);
});
}
});
this.tables.push(wrapper)
},
set_widths: function() {
var me = this;
// if widths not passed (like in standard),
// get from doctype and redistribute to fit 100%
if(!this.widths) {
this.widths = $.map(this.columns, function(fieldname, ci) {
var df = frappe.meta.docfield_map[me.tabletype][fieldname];
return df && df.print_width || (fieldname=="Sr" ? 30 : 80);
});
var sum = 0;
$.each(this.widths, function(i, w) {
sum += cint(w);
});
this.widths = $.map(this.widths, function(w) {
w = (flt(w) / sum * 100).toFixed(0);
return (w < 5 ? 5 : w) + "%";
});
}
},
get_tables: function() {
if(this.tables.length > 1) {
return $.map(this.tables, function(t) {
return t.get(0);
});
} else {
return this.tables[0].get(0);
}
},
cell_style: {
border: '1px solid #999',
padding: '3px',
'vertical-align': 'top',
'word-wrap': 'break-word',
},
head_cell_style: {
border: '1px solid #999',
padding: '3px',
'vertical-align': 'top',
'background-color': '#ddd',
'font-weight': 'bold',
'word-wrap': 'break-word',
},
table_style: {
width: '100%',
'border-collapse': 'collapse',
'margin-bottom': '10px',
'margin-top': '10px',
'table-layout': 'fixed'
},
})
window.print_table = function print_table(dt, dn, fieldname, tabletype, cols, head_labels, widths, condition, cssClass, modifier) {
return new frappe.printTable({
doctype: dt,
docname: dn,
fieldname: fieldname,
tabletype: tabletype,
columns: cols,
head_labels: head_labels,
widths: widths,
condition: condition,
cssClass: cssClass,
modifier: modifier
}).get_tables();
}

View file

@ -88,11 +88,7 @@ frappe.render_grid = function(opts) {
// build context
if(opts.grid) {
opts.columns = opts.grid.getColumns();
if(opts.report && opts.report.dataView) {
opts.data = frappe.slickgrid_tools.get_filtered_items(opts.report.dataView);
} else if(opts.grid) {
opts.data = opts.grid.getData().getItems();
}
opts.data = opts.grid.getData().getItems();
}
// show landscape view if columns more than 10

View file

@ -305,6 +305,7 @@ class Session:
expiry = self.get_expiry_in_seconds(session_data.get("session_expiry"))
if self.time_diff > expiry:
print('deleting...')
self.delete_session()
data = None
@ -318,7 +319,7 @@ class Session:
SELECT `user`, `sessiondata`
FROM `tabSessions` WHERE `sid`=%s AND
(NOW() - lastupdate) < %s
""", (self.sid, get_expiry_period(self.device)))
""", (self.sid, get_expiry_period(self.device)), debug=1)
if rec:
data = frappe._dict(eval(rec and rec[0][1] or '{}'))

View file

@ -100,6 +100,10 @@ def to_csv(data):
return writer.getvalue()
def build_csv_response(data, filename):
frappe.response["result"] = cstr(to_csv(args.data))
frappe.response["doctype"] = filename
frappe.response["type"] = "csv"
class UnicodeWriter:
def __init__(self, encoding="utf-8"):