// _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 d = new Dialog( 360, // w 140, // h 'Print Formats', // title [ // content ['HTML', 'Select'], ['Check', 'No Letterhead'], ['HTML', 'Buttons'] ]); //d.widgets['No Letterhead'].checked = 1; // Print Button $btn(d.widgets.Buttons, 'Print', function() { _p.build( sel_val(cur_frm.print_sel), // fmtname _p.go, // onload d.widgets['No Letterhead'].checked // no_letterhead ); }, { cssFloat: 'right', marginBottom: '16px', marginLeft: '7px' }, 'green'); // Print Preview $btn(d.widgets.Buttons, 'Preview', function() { _p.build( sel_val(cur_frm.print_sel), // fmtname _p.preview, // onload d.widgets['No Letterhead'].checked // no_letterhead ); }, { cssFloat: 'right', marginBottom: '16px' }, ''); // Delete previous print format select list and Reload print format list from current form d.onshow = function() { var c = _p.dialog.widgets['Select']; if(c.cur_sel && c.cur_sel.parentNode == c) { c.removeChild(c.cur_sel); } c.appendChild(cur_frm.print_sel); c.cur_sel = cur_frm.print_sel; } _p.dialog = d; }, // 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) { args = { fmtname: fmtname, onload: onload, no_letterhead: no_letterhead, only_body: only_body }; if(!cur_frm) { alert('No Document Selected'); return; } // Get current doc (record) var doc = locals[cur_frm.doctype][cur_frm.docname]; if(args.fmtname == 'Standard') { /* Render standard print layout The function passed as args onload is then called using these parameters */ args.onload(_p.render({ body: _p.print_std(args.no_letterhead), style: _p.print_style, doc: doc, title: doc.name, no_letterhead: args.no_letterhead, only_body: args.only_body })); } else { if (!_p.formats[args.fmtname]) { /* If print formats are not loaded, then load them and call the args onload function on callback. I think, this case happens when preview is invoked directly */ var build_args = args; $c( command = 'webnotes.widgets.form.get_print_format', args = { 'name': build_args.fmtname }, fn = function(r, rt) { _p.formats[build_args.fmtname] = r.message; build_args.onload(_p.render({ body: _p.formats[build_args.fmtname], style: '', doc: doc, title: doc.name, no_letterhead: build_args.no_letterhead, only_body: build_args.only_body })); } ); } else { // If print format is already loaded, go ahead with args onload function call args.onload(_p.render({ body: _p.formats[args.fmtname], style: '', doc: doc, title: doc.name, no_letterhead: args.no_letterhead, only_body: args.only_body })); } } }, /* args dict can contain: + body + style + doc + title + no_letterhead + only_body */ render: function(args) { var container = document.createElement('div'); var stat = ''; // if draft/archived, show draft/archived banner stat += _p.show_draft(args); stat += _p.show_archived(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 "\
\
\ {{HEAD}}\
\ {{DESCRIPTION}}\
" }, /* Check if doc's status is not submitted (docstatus == 0) and submission is pending Display draft in header if true */ show_draft: function(args) { if(args.doc && cint(args.doc.docstatus)==0 && cur_frm.perm[0][SUBMIT]) { 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) { archived = _p.head_banner_format(); archived = archived.replace("{{HEAD}}", "ARCHIVED"); archived = archived.replace("{{DESCRIPTION}}", "You must restore this document to make it editable."); } else { return ""; } }, consolidate_css: function(container, args) { // Extract \ \ \n' + header; footer = footer + '\n\n\ '; } var finished = header + stat + container.innerHTML.replace(/
' + (val ? val : '') +
									'
'; 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 ? get_field(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); } } } 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; } }); this.build_head(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 { page_break = '\n\
'; // 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 row = _p.field_tab(layout.cur_cell); // Add label row.cells[0].innerHTML = f.label ? f.label : f.fieldname; $s(row.cells[1], val, f.fieldtype); // 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[1].className = 'datainputcell'; return row; } }); print_table = function(dt, dn, fieldname, tabletype, cols, head_labels, widths, condition, cssClass, modifier) { var me = this; $.extend(this, { flist: fields_list[tabletype], data: getchildren( tabletype, // child_dt dn, // parent fieldname, // parentfield dt // parenttype ), cell_style: { border: '1px solid #000', padding: '2px', verticalAlign: 'top' }, head_cell_style: { border: '1px solid #000', padding: '2px', verticalAlign: 'top', backgroundColor: '#ddd', fontWeight: 'bold' }, table_style: { width: '100%', borderCollapse: 'collapse', marginBottom: '10px' }, /* This function prepares a list of columns to be displayed and calls make_print_table to create a table with these columns */ prepare_col_heads: function(flist) { var new_flist = []; // Make a list of column headings if(cols && cols.length) { // If cols to be displayed are passed in print_table if(cols[0] == 'SR') { new_flist.push('SR') } for(var i = 0; i < cols.length; i++) { for(var j = 0; j < flist.length; j++) { if(flist[j].fieldname == cols[i]) { new_flist.push(flist[j]); break; } } } } else { // Default action: remove hidden cols new_flist.push('SR'); for(var i = 0; i < flist.length; i++) { if(!flist[i].print_hide) { new_flist.push(flist[i]); } } } // Changing me.flist so that it could be used to hide data me.flist = new_flist; }, // This function makes a new table with its heading rows make_print_table: function(flist) { // Make a table var wrapper = document.createElement('div'); var table = $a(wrapper, 'table', '', me.table_style); table.wrapper = wrapper; // Make Head Row table.insertRow(0); var col_start = 0; // If 'SR' exists in flist, then create its heading column cell if(flist[0]=='SR') { var cell = table.rows[0].insertCell(0); cell.innerHTML = head_labels?head_labels[0]:'SR'; $y(cell, { width: '30px' }); $y(cell, me.head_cell_style); col_start++; } for(var c = col_start; c < flist.length; c++) { var cell = table.rows[0].insertCell(c); $y(cell, me.head_cell_style); cell.innerHTML = head_labels?head_labels[c]:flist[c].label; if(flist[c].width) { $y(cell, {width: flist[c].width}); } if(widths) { $y(cell, {width: widths[c]}); } if(in_list(['Currency', 'Float'], flist[c].fieldtype)) { $y(cell, { textAlign: 'right' }); } } return table; }, // Populate table with data populate_table: function(table, data) { for(var r = 0; r < data.length; r++) { if((!condition) || (condition(data[r]))) { // Check for page break if(data[r].page_break) { table = me.make_print_table(me.flist); me.table_list.push(table.wrapper); } var row = table.insertRow(table.rows.length); // Add serial number if required if(me.flist[0] == 'SR') { var cell = row.insertCell(0); cell.innerHTML = r + 1; $y(cell, me.cell_style); } for(var c=me.flist.indexOf('SR')+1; c 1) ? me.table_list : me.table_list[0]; }