Você não pode selecionar mais de 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.
 
 
 
 
 
 

235 linhas
6.4 KiB

  1. // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
  2. // MIT License. See license.txt
  3. frappe.provide("frappe.ui.form.handlers");
  4. frappe.ui.form.get_event_handler_list = function(doctype, fieldname) {
  5. if(!frappe.ui.form.handlers[doctype]) {
  6. frappe.ui.form.handlers[doctype] = {};
  7. }
  8. if(!frappe.ui.form.handlers[doctype][fieldname]) {
  9. frappe.ui.form.handlers[doctype][fieldname] = [];
  10. }
  11. return frappe.ui.form.handlers[doctype][fieldname];
  12. }
  13. frappe.ui.form.on = frappe.ui.form.on_change = function(doctype, fieldname, handler) {
  14. var add_handler = function(fieldname, handler) {
  15. var handler_list = frappe.ui.form.get_event_handler_list(doctype, fieldname);
  16. let _handler = (...args) => {
  17. try {
  18. return handler(...args);
  19. } catch (error) {
  20. console.error(handler);
  21. throw error;
  22. }
  23. }
  24. handler_list.push(_handler);
  25. // add last handler to events so it can be called as
  26. // frm.events.handler(frm)
  27. if(cur_frm && cur_frm.doctype===doctype) {
  28. cur_frm.events[fieldname] = _handler;
  29. }
  30. }
  31. if (!handler && $.isPlainObject(fieldname)) {
  32. // a dict of handlers {fieldname: handler, ...}
  33. for (var key in fieldname) {
  34. var fn = fieldname[key];
  35. if (typeof fn === "function") {
  36. add_handler(key, fn);
  37. }
  38. }
  39. } else {
  40. add_handler(fieldname, handler);
  41. }
  42. }
  43. // remove standard event handlers
  44. frappe.ui.form.off = function(doctype, fieldname, handler) {
  45. var handler_list = frappe.ui.form.get_event_handler_list(doctype, fieldname);
  46. if(handler_list.length) {
  47. frappe.ui.form.handlers[doctype][fieldname] = [];
  48. }
  49. if(cur_frm && cur_frm.doctype===doctype && cur_frm.events[fieldname]) {
  50. delete cur_frm.events[fieldname];
  51. }
  52. if(cur_frm && cur_frm.cscript && cur_frm.cscript[fieldname]) {
  53. delete cur_frm.cscript[fieldname];
  54. }
  55. }
  56. frappe.ui.form.trigger = function(doctype, fieldname) {
  57. cur_frm.script_manager.trigger(fieldname, doctype);
  58. }
  59. frappe.ui.form.ScriptManager = class ScriptManager {
  60. constructor(opts) {
  61. $.extend(this, opts);
  62. }
  63. make(ControllerClass) {
  64. this.frm.cscript = $.extend(this.frm.cscript,
  65. new ControllerClass({frm: this.frm}));
  66. }
  67. trigger(event_name, doctype, name) {
  68. // trigger all the form level events that
  69. // are bound to this event_name
  70. let me = this;
  71. doctype = doctype || this.frm.doctype;
  72. name = name || this.frm.docname;
  73. let tasks = [];
  74. let handlers = this.get_handlers(event_name, doctype);
  75. // helper for child table
  76. this.frm.selected_doc = frappe.get_doc(doctype, name);
  77. let runner = (_function, is_old_style) => {
  78. let _promise = null;
  79. if(is_old_style) {
  80. // old style arguments (doc, cdt, cdn)
  81. _promise = me.frm.cscript[_function](me.frm.doc, doctype, name);
  82. } else {
  83. // new style (frm, doctype, name)
  84. _promise = _function(me.frm, doctype, name);
  85. }
  86. // if the trigger returns a promise, return it,
  87. // or use the default promise frappe.after_ajax
  88. if (_promise && _promise.then) {
  89. return _promise;
  90. } else {
  91. return frappe.after_server_call();
  92. }
  93. };
  94. // make list of functions to be run serially
  95. handlers.new_style.forEach((_function) => {
  96. if(event_name==='setup') {
  97. // setup must be called immediately
  98. runner(_function, false);
  99. } else {
  100. tasks.push(() => runner(_function, false));
  101. }
  102. });
  103. handlers.old_style.forEach((_function) => {
  104. if(event_name==='setup') {
  105. // setup must be called immediately
  106. runner(_function, true);
  107. } else {
  108. tasks.push(() => runner(_function, true));
  109. }
  110. });
  111. // run them serially
  112. return frappe.run_serially(tasks);
  113. }
  114. has_handlers(event_name, doctype) {
  115. let handlers = this.get_handlers(event_name, doctype);
  116. return handlers && (handlers.old_style.length || handlers.new_style.length);
  117. }
  118. get_handlers(event_name, doctype) {
  119. // returns list of all functions to be called (old style and new style)
  120. let me = this;
  121. let handlers = {
  122. old_style: [],
  123. new_style: []
  124. };
  125. if(frappe.ui.form.handlers[doctype] && frappe.ui.form.handlers[doctype][event_name]) {
  126. $.each(frappe.ui.form.handlers[doctype][event_name], function(i, fn) {
  127. handlers.new_style.push(fn);
  128. });
  129. }
  130. if(this.frm.cscript[event_name]) {
  131. handlers.old_style.push(event_name);
  132. }
  133. if(this.frm.cscript["custom_" + event_name]) {
  134. handlers.old_style.push("custom_" + event_name);
  135. }
  136. return handlers;
  137. }
  138. setup() {
  139. const doctype = this.frm.meta;
  140. const me = this;
  141. let client_script;
  142. // process the custom script for this form
  143. if (this.frm.doctype_layout) {
  144. client_script = this.frm.doctype_layout.client_script;
  145. } else {
  146. client_script = doctype.__js;
  147. }
  148. if (client_script) {
  149. eval(client_script);
  150. }
  151. if (!this.frm.doctype_layout && doctype.__custom_js) {
  152. try {
  153. eval(doctype.__custom_js);
  154. } catch(e) {
  155. frappe.msgprint({
  156. title: __('Error in Client Script'),
  157. indicator: 'orange',
  158. message: '<pre class="small"><code>' + e.stack + '</code></pre>'
  159. });
  160. }
  161. }
  162. function setup_add_fetch(df) {
  163. if ((['Data', 'Read Only', 'Text', 'Small Text', 'Currency', 'Check',
  164. 'Text Editor', 'Code', 'Link', 'Float', 'Int', 'Date', 'Select'].includes(df.fieldtype) || df.read_only==1)
  165. && df.fetch_from && df.fetch_from.indexOf(".")!=-1) {
  166. var parts = df.fetch_from.split(".");
  167. me.frm.add_fetch(parts[0], parts[1], df.fieldname);
  168. }
  169. }
  170. // setup add fetch
  171. $.each(this.frm.fields, function(i, field) {
  172. setup_add_fetch(field.df);
  173. if(frappe.model.table_fields.includes(field.df.fieldtype)) {
  174. $.each(frappe.meta.get_docfields(field.df.options, me.frm.docname), function(i, df) {
  175. setup_add_fetch(df);
  176. });
  177. }
  178. });
  179. // css
  180. doctype.__css && frappe.dom.set_style(doctype.__css);
  181. this.trigger('setup');
  182. }
  183. log_error(caller, e) {
  184. frappe.show_alert({message: __("Error in Client Script."), indicator: "error"});
  185. console.group && console.group();
  186. console.log("----- error in client script -----");
  187. console.log("method: " + caller);
  188. console.log(e);
  189. console.log("error message: " + e.message);
  190. console.trace && console.trace();
  191. console.log("----- end of error message -----");
  192. console.group && console.groupEnd();
  193. }
  194. copy_from_first_row(parentfield, current_row, fieldnames) {
  195. var data = this.frm.doc[parentfield];
  196. if(data.length===1 || data[0]===current_row) return;
  197. if(typeof fieldnames==='string') {
  198. fieldnames = [fieldnames];
  199. }
  200. $.each(fieldnames, function(i, fieldname) {
  201. frappe.model.set_value(current_row.doctype, current_row.name, fieldname,
  202. data[0][fieldname]);
  203. });
  204. }
  205. };