Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 
 

372 řádky
11 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. this.cell = this.frm.layout.addcell(this.df.width);
  30. $y(this.cell.wrapper, {padding: '8px'});
  31. _f.cur_col_break_width = this.df.width;
  32. var fn = this.df.fieldname || this.df.label;
  33. // header
  34. if(this.df&&this.df.label){
  35. this.label = $a(this.cell.wrapper, 'h4', '', '', wn._(this.df.label));
  36. if(this.df.description)
  37. $('<div class="help small" style="margin-top: 4px; margin-bottom: 8px;">'
  38. +wn._(this.df.description)+'</div>')
  39. .appendTo(this.cell.wrapper)
  40. }
  41. }
  42. _f.ColumnBreak.prototype.refresh = function(layout) {
  43. //if(!this.cell)return; // no perm
  44. var hidden = 0;
  45. // we generate column breaks, but hide it based on perms/hidden value
  46. if((!this.perm[this.df.permlevel]) || (!this.perm[this.df.permlevel][READ]) ||
  47. this.df.hidden) {
  48. // do not display, as no permission
  49. hidden = 1;
  50. }
  51. // hidden
  52. if(this.set_hidden!=hidden) {
  53. if(hidden)
  54. this.cell.hide();
  55. else
  56. this.cell.show();
  57. this.set_hidden = hidden;
  58. }
  59. }
  60. // ======================================================================================
  61. _f.SectionBreak = function() {
  62. this.fields = [];
  63. this.set_input = function() { };
  64. this.make_row = function() {
  65. this.row = this.df.label ? this.frm.layout.addrow() : this.frm.layout.addsubrow();
  66. }
  67. }
  68. _f.SectionBreak.prototype.make_body = function() {
  69. var me = this;
  70. this.make_row();
  71. if(this.df.label) {
  72. if(!this.df.description)
  73. this.df.description = '';
  74. this.df._label = wn._(this.df.label);
  75. this.df._description = wn._(this.df.description);
  76. $(this.row.main_head).html(repl('<div class="form-section-head">\
  77. <h3 class="head">%(_label)s</h3>\
  78. <div class="help small" \
  79. style="margin-top: 4px; margin-bottom: 8px;">%(_description)s</div>\
  80. </div>', this.df));
  81. } else {
  82. // simple
  83. $(this.wrapper).html('<div class="form-section-head"></div>');
  84. }
  85. // collapse section
  86. this.section_collapse = function() {
  87. $(me.row.main_head).find('.head')
  88. .html('<i class="icon-chevron-right"></i> \
  89. <a href="#" onclick="return false;">Show "' + me.df.label + '"</a>');
  90. $(me.row.main_body).toggle(false);
  91. }
  92. // expand section
  93. this.section_expand = function(no_animation) {
  94. $(me.row.main_head).find('.head')
  95. .html('<h3><i class="icon-chevron-down" style="vertical-align: middle; margin-bottom: 2px"></i> '
  96. + me.df.label + '</h3>');
  97. if(no_animation)
  98. $(me.row.main_body).toggle(true);
  99. else
  100. $(me.row.main_body).slideDown();
  101. }
  102. }
  103. _f.SectionBreak.prototype.refresh = function(from_form) {
  104. var hidden = 0;
  105. // we generate section breaks, but hide it based on perms/hidden value
  106. if((!this.perm[this.df.permlevel]) || (!this.perm[this.df.permlevel][READ]) || this.df.hidden) {
  107. // no display
  108. hidden = 1;
  109. }
  110. if(hidden) {
  111. if(this.row)this.row.hide();
  112. } else {
  113. if(this.row)this.row.show();
  114. }
  115. }
  116. // Image field definition
  117. // ======================================================================================
  118. _f.ImageField = function() { this.images = {}; }
  119. _f.ImageField.prototype = new Field();
  120. _f.ImageField.prototype.onrefresh = function() {
  121. $(this.label_span).toggle(false);
  122. $(this.wrapper).find("img").remove();
  123. if(this.df.options && this.frm.doc[this.df.options]) {
  124. $("<img src='"+wn.utils.get_file_link(this.frm.doc[this.df.options])+"' style='max-width: 70%;'>")
  125. .appendTo($(this.wrapper).empty());
  126. } else {
  127. $("<div class='missing-image'><i class='icon-camera'></i></div>")
  128. .appendTo($(this.wrapper).empty())
  129. }
  130. }
  131. _f.ImageField.prototype.set_disp = function (val) { }
  132. _f.ImageField.prototype.set = function (val) { }
  133. // Table
  134. // ======================================================================================
  135. _f.TableField = function() { };
  136. _f.TableField.prototype = new Field();
  137. _f.TableField.prototype.with_label = 0;
  138. _f.TableField.prototype.make_body = function() {
  139. if(this.perm[this.df.permlevel] && this.perm[this.df.permlevel][READ]) {
  140. this.wrapper = $("<div>").appendTo(this.parent).get(0);
  141. this.grid = new _f.FormGrid(this);
  142. if(this.frm)this.frm.grids[this.frm.grids.length] = this;
  143. this.grid.make_buttons();
  144. // description
  145. if(this.df.description) {
  146. this.desc_area = $a(this.wrapper, 'div', 'help small',
  147. {marginBottom:'9px', marginTop:'0px'}, this.df.description)
  148. }
  149. }
  150. }
  151. _f.TableField.prototype.refresh = function() {
  152. if(!this.grid)return;
  153. // hide / show grid
  154. var st = this.get_status();
  155. if(!this.df['default'])
  156. this.df['default']='';
  157. this.grid.can_add_rows = false;
  158. this.grid.can_edit = false;
  159. if(st=='Write') {
  160. this.grid.can_edit = true;
  161. if(this.df['default'].toLowerCase()!='no toolbar')
  162. this.grid.can_add_rows = true;
  163. if(this.df['default'].toLowerCase()=='no add rows') {
  164. this.grid.can_add_rows = false;
  165. }
  166. }
  167. if(st=='Write' || st=="Read") {
  168. $(this.wrapper).toggle(true);
  169. this.grid.show();
  170. } else {
  171. $(this.wrapper).toggle(false);
  172. this.grid.hide();
  173. }
  174. this.grid.refresh();
  175. }
  176. _f.TableField.prototype.set = function(v) { }; // nothing
  177. _f.TableField.prototype.set_input = function(v) { }; // nothing
  178. _f.CodeField = function() { };
  179. _f.CodeField.prototype = new Field();
  180. _f.CodeField.prototype.make_input = function() {
  181. var me = this;
  182. this.label_span.innerHTML = this.df.label;
  183. if(this.df.fieldtype=='Text Editor') {
  184. $(this.input_area).css({"min-height":"360px"});
  185. this.input = $a(this.input_area, 'text_area', '', {fontSize:'12px'});
  186. this.myid = wn.dom.set_unique_id(this.input);
  187. // setup tiny mce
  188. $(me.input).tinymce({
  189. // Location of TinyMCE script
  190. script_url : 'lib/js/lib/tiny_mce_3.5.7/tiny_mce.js',
  191. // General options
  192. theme : "advanced",
  193. plugins : "style,inlinepopups,table,advimage",
  194. extended_valid_elements: "script|embed",
  195. // w/h
  196. width: '100%',
  197. height: '360px',
  198. // buttons
  199. theme_advanced_buttons1 : "bold,italic,underline,hr,|,justifyleft,justifycenter,|,formatselect,fontsizeselect,|,bullist,numlist,|,image,|,outdent,indent,|,link,|,forecolor,backcolor,|,code",
  200. theme_advanced_buttons2 : "",
  201. theme_advanced_buttons3 : "",
  202. theme_advanced_toolbar_location : "top",
  203. theme_advanced_toolbar_align : "left",
  204. theme_advanced_statusbar_location: "none",
  205. theme_advanced_path: false,
  206. valid_elements : "*[*]",
  207. content_css: "lib/js/lib/tiny_mce_3.5.7/custom_content.css?q=1",
  208. oninit: function() { me.init_editor(); },
  209. setup: function(ed) {
  210. ed.onChange.add(function(ed, l) {
  211. me.set(l.content);
  212. me.run_trigger();
  213. });
  214. }
  215. });
  216. this.input.set_input = function(v) {
  217. if(me.editor) {
  218. me.editor.setContent(v==null ? "" : v);
  219. } else {
  220. $(me.input).val(v);
  221. }
  222. }
  223. this.get_value = function() {
  224. return me.editor && me.editor.getContent(); // tinyMCE
  225. }
  226. } else {
  227. // setup ace
  228. wn.require('lib/js/lib/ace/ace.js');
  229. $(this.input_area).css('border','1px solid #aaa');
  230. this.pre = $("<pre style='position: relative; height: 400px; \
  231. width: 100%; padding: 0px; border-radius: 0px;\
  232. margin: 0px; background-color: #fff;'>").appendTo(this.input_area).get(0);
  233. this.input = {};
  234. this.myid = wn.dom.set_unique_id(this.pre);
  235. this.editor = ace.edit(this.myid);
  236. if(me.df.options=='Markdown' || me.df.options=='HTML') {
  237. wn.require('lib/js/lib/ace/mode-html.js');
  238. var HTMLMode = require("ace/mode/html").Mode;
  239. me.editor.getSession().setMode(new HTMLMode());
  240. }
  241. else if(me.df.options=='Javascript') {
  242. wn.require('lib/js/lib/ace/mode-javascript.js');
  243. var JavascriptMode = require("ace/mode/javascript").Mode;
  244. me.editor.getSession().setMode(new JavascriptMode());
  245. }
  246. else if(me.df.options=='Python') {
  247. wn.require('lib/js/lib/ace/mode-python.js');
  248. var PythonMode = require("ace/mode/python").Mode;
  249. me.editor.getSession().setMode(new PythonMode());
  250. }
  251. this.input.set_input = function(v) {
  252. // during field refresh in run trigger, set_input is called
  253. // if called during on_change, setting doesn't make sense
  254. // and causes cursor to shift back to first position
  255. if(me.changing_value) return;
  256. me.setting_value = true;
  257. me.editor.getSession().setValue(v==null ? "" : v);
  258. me.setting_value = false;
  259. }
  260. this.get_value = function() {
  261. return me.editor.getSession().getValue(); // tinyMCE
  262. }
  263. $(cur_frm.wrapper).bind('render_complete', function() {
  264. me.editor.resize();
  265. me.editor.getSession().on('change', function() {
  266. if(me.setting_value) return;
  267. var val = me.get_value();
  268. if(locals[cur_frm.doctype][cur_frm.docname][me.df.fieldname] != val) {
  269. me.set(me.get_value());
  270. me.changing_value = true;
  271. me.run_trigger();
  272. me.changing_value = false;
  273. }
  274. })
  275. });
  276. this.onrefresh = function() {
  277. me.editor && me.editor.resize();
  278. }
  279. }
  280. }
  281. _f.CodeField.prototype.init_editor = function() {
  282. // attach onchange methods
  283. var me = this;
  284. this.editor = tinymce.get(this.myid);
  285. this.editor.onKeyUp.add(function(ed, e) {
  286. me.set(ed.getContent());
  287. });
  288. this.editor.onPaste.add(function(ed, e) {
  289. me.set(ed.getContent());
  290. });
  291. this.editor.onSetContent.add(function(ed, e) {
  292. me.set(ed.getContent());
  293. });
  294. // reset content
  295. var c = locals[cur_frm.doctype][cur_frm.docname][this.df.fieldname];
  296. if(cur_frm && c) {
  297. this.editor.setContent(c);
  298. }
  299. }
  300. _f.CodeField.prototype.set_disp = function(val) {
  301. $y(this.disp_area, {width:'90%'})
  302. if(this.df.fieldtype=='Text Editor') {
  303. this.disp_area.innerHTML = val;
  304. } else {
  305. this.disp_area.innerHTML = '<textarea class="code_text" readonly=1>'+val+'</textarea>';
  306. }
  307. }
  308. // ======================================================================================