Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

251 lignes
6.6 KiB

  1. // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
  2. // MIT License. See license.txt
  3. wn.provide("wn.ui.form");
  4. wn.ui.form.Layout = Class.extend({
  5. init: function(opts) {
  6. this.views = {};
  7. this.sections = [];
  8. this.fields_list = [];
  9. this.fields_dict = {};
  10. this.labelled_section_count = 0;
  11. this.ignore_types = ["Section Break", "Column Break"];
  12. $.extend(this, opts);
  13. },
  14. make: function() {
  15. if(!this.parent && this.body)
  16. this.parent = this.body;
  17. this.wrapper = $('<div class="form-layout">').appendTo(this.parent);
  18. if(!this.fields)
  19. this.fields = wn.meta.sort_docfields(wn.meta.docfield_map[this.doctype]);
  20. this.setup_tabbing();
  21. this.render();
  22. },
  23. add_view: function(label) {
  24. var view = $('<div class="form-add-view">').appendTo(this.parent).toggle(false);
  25. this.views[label] = view;
  26. },
  27. set_view: function(label) {
  28. if(this.cur_view) this.cur_view.toggle(false);
  29. if(label) {
  30. this.wrapper.toggle(false);
  31. if(!this.views[label])
  32. this.add_view(label);
  33. this.cur_view = this.views[label].toggle(true);
  34. } else {
  35. this.wrapper.toggle(true);
  36. }
  37. },
  38. refresh: function() {
  39. var me = this;
  40. $.each(this.fields_list, function(i, fieldobj) {
  41. if(me.frm) {
  42. fieldobj.docname = me.frm.docname;
  43. fieldobj.df = wn.meta.get_docfield(me.frm.doctype,
  44. fieldobj.df.fieldname, me.frm.docname);
  45. // on form change, permissions can change
  46. fieldobj.perm = me.frm.perm;
  47. };
  48. fieldobj.refresh && fieldobj.refresh();
  49. });
  50. if(this.frm)
  51. $(this.frm.wrapper).trigger("refresh-fields");
  52. },
  53. render: function() {
  54. var me = this;
  55. this.section = null;
  56. this.column = null;
  57. if(this.fields[0] && this.fields[0].fieldtype!="Section Break") {
  58. this.make_section();
  59. }
  60. $.each(this.fields, function(i, df) {
  61. switch(df.fieldtype) {
  62. case "Section Break":
  63. me.make_section(df);
  64. break;
  65. case "Column Break":
  66. me.make_column(df);
  67. break;
  68. default:
  69. me.make_field(df);
  70. }
  71. });
  72. },
  73. make_column: function(df) {
  74. this.column = $('<div class="form-column">\
  75. <form>\
  76. </form>\
  77. </div>').appendTo(this.section.body)
  78. .find("form")
  79. .on("submit", function() { return false; })
  80. // distribute all columns equally
  81. var colspan = cint(12 / this.section.find(".form-column").length);
  82. this.section.find(".form-column").removeClass()
  83. .addClass("form-column")
  84. .addClass("col-md-" + colspan);
  85. },
  86. make_field: function(df, colspan) {
  87. !this.column && this.make_column();
  88. var fieldobj = make_field(df, this.doctype, this.column.get(0), this.frm);
  89. this.fields_list.push(fieldobj);
  90. this.fields_dict[df.fieldname] = fieldobj;
  91. if(this.frm) {
  92. fieldobj.perm = this.frm.perm;
  93. }
  94. },
  95. make_section: function(df) {
  96. if(this.section) {
  97. //$("<hr>").appendTo(this.wrapper);
  98. }
  99. this.section = $('<div class="row">')
  100. .appendTo(this.wrapper);
  101. this.sections.push(this.section);
  102. var section = this.section[0];
  103. section.df = df;
  104. if(df) {
  105. if(df.label) {
  106. this.labelled_section_count++;
  107. var head = $('<h4 class="col-md-12 text-muted">'
  108. + (df.options ? (' <i class="icon-in-circle '+df.options+'"></i> ') : "")
  109. + '<span class="section-count-label">' + this.labelled_section_count + "</span>. "
  110. + wn._(df.label)
  111. + "</h4>")
  112. .appendTo(this.section);
  113. if(df && df.idx===1)
  114. head.css({"margin-top": "0px"})
  115. if(this.sections.length > 1)
  116. this.section.css({
  117. "margin-top": "15px",
  118. "border-top": "1px solid #ddd"
  119. });
  120. }
  121. if(df.description) {
  122. $('<div class="col-md-12 small text-muted">' + df.description + '</div>')
  123. .css("padding-left", "40px")
  124. .appendTo(this.section);
  125. }
  126. if(df.label || df.description) {
  127. // spacer
  128. $('<div class="col-md-12"></div>')
  129. .appendTo(this.section)
  130. .css({"height": "10px"});
  131. }
  132. this.fields_dict[df.fieldname] = section;
  133. this.fields_list.push(section);
  134. }
  135. // for bc
  136. this.section.body = $('<div>').appendTo(this.section);
  137. // if(this.frm)
  138. // this.section.body.css({"padding":"0px 3%"})
  139. section.row = {
  140. wrapper: section
  141. };
  142. section.refresh = function() {
  143. if(!this.df) return;
  144. $(this).toggle(this.df.hidden ? false : (cur_frm ? !!cur_frm.get_perm(this.df.permlevel, READ) : true))
  145. }
  146. this.column = null;
  147. section.refresh.call(section);
  148. return this.section;
  149. },
  150. refresh_section_count: function() {
  151. this.wrapper.find(".section-count-label:visible").each(function(i) {
  152. $(this).html(i+1);
  153. });
  154. },
  155. setup_tabbing: function() {
  156. var me = this;
  157. this.wrapper.on("keydown", function(ev) {
  158. if(ev.which==9) {
  159. var current = $(ev.target).trigger("change"),
  160. doctype = current.attr("data-doctype"),
  161. fieldname = current.attr("data-fieldname");
  162. if(doctype)
  163. return me.handle_tab(doctype, fieldname, ev.shiftKey);
  164. }
  165. })
  166. },
  167. handle_tab: function(doctype, fieldname, shift) {
  168. var me = this,
  169. grid_row = null;
  170. prev = null,
  171. fields = me.fields,
  172. in_grid = false;
  173. // in grid
  174. if(doctype != me.doctype) {
  175. grid_row =me.get_open_grid_row()
  176. fields = grid_row.fields;
  177. }
  178. for(var i=0, len=fields.length; i < len; i++) {
  179. if(fields[i].df.fieldname==fieldname) {
  180. if(shift) {
  181. if(prev) {
  182. this.set_focus(prev)
  183. } else {
  184. $(this.primary_button).focus();
  185. }
  186. break;
  187. }
  188. if(i==len-1) {
  189. // last field in this group
  190. if(grid_row) {
  191. // in grid
  192. if(grid_row.doc.idx==grid_row.grid.grid_rows.length) {
  193. // last row, close it and find next field
  194. grid_row.toggle_view(false, function() {
  195. me.handle_tab(grid_row.grid.df.parent, grid_row.grid.df.fieldname);
  196. })
  197. } else {
  198. // next row
  199. grid_row.grid.grid_rows[grid_row.doc.idx].toggle_view(true);
  200. }
  201. } else {
  202. $(this.primary_button).focus();
  203. }
  204. } else {
  205. me.focus_on_next_field(i, fields);
  206. }
  207. break;
  208. }
  209. if(fields[i].disp_status==="Write")
  210. prev = fields[i];
  211. }
  212. return false;
  213. },
  214. focus_on_next_field: function(start_idx, fields) {
  215. // loop to find next eligible fields
  216. for(var i= start_idx + 1, len = fields.length; i < len; i++) {
  217. if(fields[i].disp_status==="Write" && !in_list(wn.model.no_value_type, fields[i].df.fieldtype)) {
  218. this.set_focus(fields[i]);
  219. break;
  220. }
  221. }
  222. },
  223. set_focus: function(field) {
  224. // next is table, show the table
  225. if(field.df.fieldtype=="Table") {
  226. if(!field.grid.grid_rows.length) {
  227. field.grid.add_new_row(1);
  228. } else {
  229. field.grid.grid_rows[0].toggle_view(true);
  230. }
  231. }
  232. else if(field.editor) {
  233. field.editor.set_focus();
  234. }
  235. else if(field.$input) {
  236. field.$input.focus();
  237. }
  238. },
  239. get_open_grid_row: function() {
  240. return $(".grid-row-open").data("grid_row");
  241. },
  242. })