Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

449 linhas
13 KiB

  1. // Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
  2. //
  3. // MIT License (MIT)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a
  6. // copy of this software and associated documentation files (the "Software"),
  7. // to deal in the Software without restriction, including without limitation
  8. // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. // and/or sell copies of the Software, and to permit persons to whom the
  10. // Software is furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  16. // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  17. // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  19. // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  20. // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. //
  22. //
  23. // Form Input
  24. // ======================================================================================
  25. _f.ColumnBreak = function() {
  26. this.set_input = function() { };
  27. }
  28. _f.ColumnBreak.prototype.make_body = function() {
  29. if((!this.perm[this.df.permlevel]) || (!this.perm[this.df.permlevel][READ]) ||
  30. this.df.hidden) {
  31. // no display
  32. return;
  33. }
  34. this.cell = this.frm.layout.addcell(this.df.width);
  35. $y(this.cell.wrapper, {padding: '8px'});
  36. _f.cur_col_break_width = this.df.width;
  37. var fn = this.df.fieldname?this.df.fieldname:this.df.label;
  38. // header
  39. if(this.df&&this.df.label){
  40. this.label = $a(this.cell.wrapper, 'div', '', '', this.df.label);
  41. }
  42. }
  43. _f.ColumnBreak.prototype.refresh = function(layout) {
  44. if(!this.cell)return; // no perm
  45. // hidden
  46. if(this.set_hidden!=this.df.hidden) {
  47. if(this.df.hidden)
  48. this.cell.hide();
  49. else
  50. this.cell.show();
  51. this.set_hidden = this.df.hidden;
  52. }
  53. }
  54. // ======================================================================================
  55. _f.SectionBreak = function() {
  56. this.fields = [];
  57. this.set_input = function() { };
  58. this.make_row = function() {
  59. this.row = this.df.label ? this.frm.layout.addrow() : this.frm.layout.addsubrow();
  60. }
  61. }
  62. _f.SectionBreak.prototype.make_body = function() {
  63. var me = this;
  64. if((!this.perm[this.df.permlevel]) || (!this.perm[this.df.permlevel][READ]) || this.df.hidden) {
  65. // no display
  66. return;
  67. }
  68. this.make_row();
  69. if(this.df.label) {
  70. if(!this.df.description)
  71. this.df.description = '';
  72. $(this.row.main_head).html(repl('<div class="form-section-head">\
  73. <h3 class="head">%(label)s</h3>\
  74. <div class="help small" \
  75. style="margin-top: 4px; margin-bottom: 8px;">%(description)s</div>\
  76. </div>', this.df));
  77. } else {
  78. // simple
  79. $(this.wrapper).html('<div class="form-section-head"></div>');
  80. }
  81. // collapse section
  82. this.section_collapse = function() {
  83. $(me.row.main_head).find('.head')
  84. .html('<i class="icon-chevron-right"></i> \
  85. <a href="#" onclick="return false;">Show "' + me.df.label + '"</a>');
  86. $(me.row.main_body).toggle(false);
  87. }
  88. // expand section
  89. this.section_expand = function(no_animation) {
  90. $(me.row.main_head).find('.head')
  91. .html('<h3><i class="icon-chevron-down" style="vertical-align: middle; margin-bottom: 2px"></i> '
  92. + me.df.label + '</h3>');
  93. if(no_animation)
  94. $(me.row.main_body).toggle(true);
  95. else
  96. $(me.row.main_body).slideDown();
  97. }
  98. }
  99. _f.SectionBreak.prototype.has_data = function() {
  100. // return true if
  101. // 1. any field in the section is mandatory & not set as default
  102. // 2. any field in the section has data that is not default
  103. // 3. if table, table has rows
  104. var me = this;
  105. for(var i in me.fields) {
  106. var f = me.fields[i];
  107. var v = f.get_value ? f.get_value() : null;
  108. // value that is not default
  109. defaultval = f.df['default'] || sys_defaults[f.fieldname] || user_defaults[f.fieldname];
  110. if(v && v != defaultval) {
  111. return true;
  112. }
  113. // unfilled mandatory field
  114. if(f.df.reqd && !v) {
  115. return true;
  116. }
  117. // filled table
  118. if(f.df.fieldtype=='Table') {
  119. if(f.grid.get_children().length || f.df.reqd) {
  120. return true;
  121. }
  122. }
  123. }
  124. return false;
  125. }
  126. _f.SectionBreak.prototype.refresh = function(from_form) {
  127. if(this.df.hidden) {
  128. if(this.row)this.row.hide();
  129. } else {
  130. if(this.collapsible) {
  131. //this.section_expand(from_form);
  132. //if(this.df.reqd || this.has_data()) {
  133. // this.section_expand(from_form);
  134. //} else {
  135. // this.section_collapse();
  136. //}
  137. }
  138. }
  139. }
  140. // Image field definition
  141. // ======================================================================================
  142. _f.ImageField = function() { this.images = {}; }
  143. _f.ImageField.prototype = new Field();
  144. _f.ImageField.prototype.onmake = function() {
  145. this.no_img = $a(this.wrapper, 'div','no_img');
  146. this.no_img.innerHTML = "No Image";
  147. $dh(this.no_img);
  148. }
  149. _f.ImageField.prototype.get_image_src = function(doc) {
  150. if(doc.file_list) {
  151. file = doc.file_list.split(',');
  152. // if image
  153. extn = file[0].split('.');
  154. extn = extn[extn.length - 1].toLowerCase();
  155. var img_extn_list = ['gif', 'jpg', 'bmp', 'jpeg', 'jp2', 'cgm', 'ief', 'jpm', 'jpx', 'png', 'tiff', 'jpe', 'tif'];
  156. if(in_list(img_extn_list, extn)) {
  157. var src = wn.request.url + "?cmd=downloadfile&file_id="+file[1];
  158. }
  159. } else {
  160. var src = "";
  161. }
  162. return src;
  163. }
  164. _f.ImageField.prototype.onrefresh = function() {
  165. var me = this;
  166. if(!this.images[this.docname]) this.images[this.docname] = $a(this.wrapper, 'img');
  167. else $di(this.images[this.docname]);
  168. var img = this.images[this.docname]
  169. // hide all other
  170. for(var dn in this.images) if(dn!=this.docname)$dh(this.images[dn]);
  171. var doc = locals[this.frm.doctype][this.frm.docname];
  172. if(!this.df.options) var src = this.get_image_src(doc);
  173. else var src = wn.request.url + '?cmd=get_file&fname='+this.df.options+"&__account="+account_id + (__sid150 ? ("&sid150="+__sid150) : '');
  174. if(src) {
  175. $dh(this.no_img);
  176. if(img.getAttribute('src')!=src) img.setAttribute('src',src);
  177. canvas = this.wrapper;
  178. canvas.img = this.images[this.docname];
  179. canvas.style.overflow = "auto";
  180. $w(canvas, "100%");
  181. if(!this.col_break_width)this.col_break_width = '100%';
  182. var allow_width = cint(1000 * (cint(this.col_break_width)-10) / 100);
  183. if((!img.naturalWidth) || cint(img.naturalWidth)>allow_width)
  184. $w(img, allow_width + 'px');
  185. } else {
  186. $ds(this.no_img);
  187. }
  188. }
  189. _f.ImageField.prototype.set_disp = function (val) { }
  190. _f.ImageField.prototype.set = function (val) { }
  191. // Table
  192. // ======================================================================================
  193. _f.TableField = function() { };
  194. _f.TableField.prototype = new Field();
  195. _f.TableField.prototype.with_label = 0;
  196. _f.TableField.prototype.make_body = function() {
  197. if(this.perm[this.df.permlevel] && this.perm[this.df.permlevel][READ]) {
  198. // add comment area
  199. if(this.df.description) {
  200. this.desc_area = $a(this.parent, 'div', 'help small', '', this.df.description)
  201. }
  202. this.grid = new _f.FormGrid(this);
  203. if(this.frm)this.frm.grids[this.frm.grids.length] = this;
  204. this.grid.make_buttons();
  205. }
  206. }
  207. _f.TableField.prototype.refresh = function() {
  208. if(!this.grid)return;
  209. // hide / show grid
  210. var st = this.get_status();
  211. if(!this.df['default'])
  212. this.df['default']='';
  213. this.grid.can_add_rows = false;
  214. this.grid.can_edit = false
  215. if(st=='Write') {
  216. if(cur_frm.editable && this.perm[this.df.permlevel] && this.perm[this.df.permlevel][WRITE]) {
  217. this.grid.can_edit = true;
  218. if(this.df['default'].toLowerCase()!='no toolbar')
  219. this.grid.can_add_rows = true;
  220. }
  221. // submitted or cancelled
  222. if(cur_frm.editable && cur_frm.doc.docstatus > 0) {
  223. if(this.df.allow_on_submit && cur_frm.doc.docstatus==1) {
  224. this.grid.can_edit = true;
  225. if(this.df['default'].toLowerCase()=='no toolbar') {
  226. this.grid.can_add_rows = false;
  227. } else {
  228. this.grid.can_add_rows = true;
  229. }
  230. } else {
  231. this.grid.can_add_rows = false;
  232. this.grid.can_edit = false;
  233. }
  234. }
  235. if(this.df['default'].toLowerCase()=='no add rows') {
  236. this.grid.can_add_rows = false;
  237. }
  238. }
  239. //if(this.old_status!=st) {
  240. if(st=='Write') {
  241. // nothing
  242. this.grid.show();
  243. } else if(st=='Read') {
  244. this.grid.show();
  245. } else {
  246. this.grid.hide();
  247. }
  248. // this.old_status = st; // save this if next time
  249. //}
  250. this.grid.refresh();
  251. }
  252. _f.TableField.prototype.set = function(v) { }; // nothing
  253. _f.TableField.prototype.set_input = function(v) { }; // nothing
  254. // ==============================================================
  255. _f.CodeField = function() { };
  256. _f.CodeField.prototype = new Field();
  257. _f.CodeField.prototype.make_input = function() {
  258. var me = this;
  259. this.label_span.innerHTML = this.df.label;
  260. if(this.df.fieldtype=='Text Editor') {
  261. this.input = $a(this.input_area, 'text_area', '', {fontSize:'12px'});
  262. this.myid = wn.dom.set_unique_id(this.input);
  263. // setup tiny mce
  264. $(me.input).tinymce({
  265. // Location of TinyMCE script
  266. script_url : 'js/lib/tiny_mce_33/tiny_mce.js',
  267. // General options
  268. theme : "advanced",
  269. plugins : "style,inlinepopups,table",
  270. extended_valid_elements: "div[id|dir|class|align|style]",
  271. // w/h
  272. width: '100%',
  273. height: '360px',
  274. // buttons
  275. theme_advanced_buttons1 : "bold,italic,underline,strikethrough,hr,|,justifyleft,justifycenter,justifyright,|,formatselect,fontselect,fontsizeselect",
  276. theme_advanced_buttons2 : "bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,code,|,forecolor,backcolor,|,tablecontrols",
  277. theme_advanced_buttons3 : "",
  278. theme_advanced_toolbar_location : "top",
  279. theme_advanced_toolbar_align : "left",
  280. content_css: "js/lib/tiny_mce_33/custom_content.css",
  281. oninit: function() { me.init_editor(); }
  282. });
  283. this.input.set_input = function(v) {
  284. if(me.editor) {
  285. me.editor.setContent(v);
  286. } else {
  287. $(me.input).val(v);
  288. }
  289. }
  290. this.input.onchange = function() {
  291. me.set(me.editor.getContent());
  292. me.run_trigger();
  293. }
  294. this.get_value = function() {
  295. return me.editor.getContent(); // tinyMCE
  296. }
  297. } else {
  298. // setup ace
  299. //this.input = $a(this.input_area, 'div', '', {position:'relative', width: '90%', height:'300px'});
  300. wn.require('js/lib/ace/ace.js');
  301. //wn.require('js/lib/ace/theme-twilight.js');
  302. $(this.input_area).css('border','1px solid #aaa');
  303. this.pre = $a(this.input_area, 'pre', '', {
  304. position:'relative', height: '400px', width:'100%'
  305. });
  306. this.input = {};
  307. this.myid = wn.dom.set_unique_id(this.pre);
  308. this.editor = ace.edit(this.myid);
  309. //this.editor.getSession().setUseWrapMode(true);
  310. //this.editor.setTheme("ace/theme/twilight");
  311. if(me.df.options=='Markdown' || me.df.options=='HTML') {
  312. wn.require('js/lib/ace/mode-html.js');
  313. var HTMLMode = require("ace/mode/html").Mode;
  314. me.editor.getSession().setMode(new HTMLMode());
  315. }
  316. else if(me.df.options=='Javascript') {
  317. wn.require('js/lib/ace/mode-javascript.js');
  318. var JavascriptMode = require("ace/mode/javascript").Mode;
  319. me.editor.getSession().setMode(new JavascriptMode());
  320. }
  321. else if(me.df.options=='Python') {
  322. wn.require('js/lib/ace/mode-python.js');
  323. var PythonMode = require("ace/mode/python").Mode;
  324. me.editor.getSession().setMode(new PythonMode());
  325. }
  326. this.input.set_input = function(v) {
  327. me.setting_value = true;
  328. me.editor.getSession().setValue(v);
  329. me.setting_value = false;
  330. }
  331. this.get_value = function() {
  332. return me.editor.getSession().getValue(); // tinyMCE
  333. }
  334. $(cur_frm.wrapper).bind('render_complete', function() {
  335. me.editor.resize();
  336. me.editor.getSession().on('change', function() {
  337. if(me.setting_value) return;
  338. var val = me.get_value();
  339. if(locals[cur_frm.doctype][cur_frm.docname][me.df.fieldname] != val) {
  340. me.set(me.get_value());
  341. me.run_trigger();
  342. }
  343. })
  344. });
  345. }
  346. }
  347. _f.CodeField.prototype.init_editor = function() {
  348. // attach onchange methods
  349. var me = this;
  350. this.editor = tinymce.get(this.myid);
  351. this.editor.onKeyUp.add(function(ed, e) {
  352. me.set(ed.getContent());
  353. });
  354. this.editor.onPaste.add(function(ed, e) {
  355. me.set(ed.getContent());
  356. });
  357. this.editor.onSetContent.add(function(ed, e) {
  358. me.set(ed.getContent());
  359. });
  360. // reset content
  361. var c = locals[cur_frm.doctype][cur_frm.docname][this.df.fieldname];
  362. if(cur_frm && c) {
  363. this.editor.setContent(c);
  364. }
  365. }
  366. _f.CodeField.prototype.set_disp = function(val) {
  367. $y(this.disp_area, {width:'90%'})
  368. if(this.df.fieldtype=='Text Editor') {
  369. this.disp_area.innerHTML = val;
  370. } else {
  371. this.disp_area.innerHTML = '<textarea class="code_text" readonly=1>'+val+'</textarea>';
  372. }
  373. }
  374. // ======================================================================================