You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. wn.ui.form.Grid = Class.extend({
  2. init: function(opts) {
  3. $.extend(this, opts);
  4. this.fieldinfo = {};
  5. this.docfields = wn.meta.docfield_list[this.df.options];
  6. this.docfields.sort(function(a, b) { return a.idx > b.idx ? 1 : -1 });
  7. },
  8. make: function() {
  9. var me = this;
  10. this.wrapper = $('<div>\
  11. <div class="panel">\
  12. <div class="panel-heading" style="font-size: 15px;"></div>\
  13. <div class="rows"></div>\
  14. <div style="margin-top: 5px; margin-bottom: -5px;">\
  15. <a href="#" class="grid-add-row">+ '+wn._("Add new row")+'.</a>\
  16. <span class="text-muted">Click on row to edit.</span></div>\
  17. </div>\
  18. </div>').appendTo(this.parent);
  19. $(this.wrapper).find(".grid-add-row").click(function() {
  20. wn.model.add_child(me.frm.doc, me.df.options, me.df.fieldname);
  21. me.refresh();
  22. me.wrapper.find(".grid-row:last").data("grid_row").toggle_view(true);
  23. return false;
  24. })
  25. },
  26. make_head: function() {
  27. // labels
  28. new wn.ui.form.GridRow({
  29. parent: $(this.parent).find(".panel-heading"),
  30. parent_df: this.df,
  31. docfields: this.docfields,
  32. frm: this.frm,
  33. grid: this
  34. });
  35. },
  36. refresh: function() {
  37. !this.wrapper && this.make();
  38. var me = this,
  39. $rows = $(me.parent).find(".rows"),
  40. data = this.get_data();
  41. this.display_status = wn.perm.get_field_display_status(this.df, this.frm.doc,
  42. this.perm);
  43. if(this.data_rows_are_same(data)) {
  44. // soft refresh
  45. $.each(this.grid_rows, function(i, g) {
  46. g.refresh();
  47. });
  48. } else {
  49. // redraw
  50. this.wrapper.find(".grid-row").remove();
  51. this.make_head();
  52. this.grid_rows = [];
  53. this.grid_rows_by_docname = {};
  54. $.each(data || [], function(ri, d) {
  55. var grid_row = new wn.ui.form.GridRow({
  56. parent: $rows,
  57. parent_df: me.df,
  58. docfields: me.docfields,
  59. doc: d,
  60. frm: me.frm,
  61. grid: me
  62. });
  63. me.grid_rows.push(grid_row)
  64. me.grid_rows_by_docname[d.name] = grid_row;
  65. });
  66. this.wrapper.find(".grid-add-row").toggle(this.display_status=="Write"
  67. && !this.static_rows);
  68. if(this.display_status=="Write" && !this.static_rows) {
  69. this.make_sortable($rows);
  70. }
  71. this.last_display_status = this.display_status;
  72. this.last_docname = this.frm.docname;
  73. }
  74. },
  75. refresh_row: function(docname) {
  76. this.grid_rows_by_docname[docname] &&
  77. this.grid_rows_by_docname[docname].refresh();
  78. },
  79. data_rows_are_same: function(data) {
  80. if(this.grid_rows) {
  81. var same = data.length==this.grid_rows.length
  82. && this.display_status==this.last_display_status
  83. && this.frm.docname==this.last_docname
  84. && !$.map(this.grid_rows, function(g, i) {
  85. return g.doc.name==data[i].name ? null : true;
  86. }).length;
  87. return same;
  88. }
  89. },
  90. make_sortable: function($rows) {
  91. var me =this;
  92. $rows.sortable({
  93. update: function(event, ui) {
  94. $rows.find(".grid-row").each(function(i, item) {
  95. var doc = $(item).data("doc");
  96. doc.idx = i + 1;
  97. $(this).find(".row-index").html(i + 1);
  98. me.frm.dirty();
  99. })
  100. }
  101. });
  102. },
  103. get_data: function() {
  104. var data = wn.model.get(this.df.options, {
  105. "parenttype": this.frm.doctype,
  106. "parentfield": this.df.fieldname,
  107. "parent": this.frm.docname
  108. });
  109. data.sort(function(a, b) { return a.idx > b.idx ? 1 : -1 });
  110. return data;
  111. },
  112. set_column_disp: function() {
  113. // return
  114. },
  115. get_field: function(fieldname) {
  116. if(!this.fieldinfo[fieldname])
  117. this.fieldinfo[fieldname] = {}
  118. return this.fieldinfo[fieldname];
  119. },
  120. set_value: function(fieldname, value, doc) {
  121. this.grid_rows_by_docname[doc.name].set_value(fieldname, value);
  122. },
  123. add_new_row: function(idx, callback) {
  124. wn.model.add_child(this.frm.doc, this.df.options, this.df.fieldname, idx);
  125. this.refresh();
  126. // show
  127. this.wrapper.find("[data-idx='"+idx+"']").data("grid_row")
  128. .toggle_view(true, callback);
  129. }
  130. });
  131. wn.ui.form.GridRow = Class.extend({
  132. init: function(opts) {
  133. $.extend(this, opts);
  134. this.show = false;
  135. this.make();
  136. },
  137. make: function() {
  138. var me = this;
  139. this.wrapper = $('<div class="grid-row">\
  140. <div class="data-row" style="min-height: 15px;"></div>\
  141. <div class="panel panel-warning" style="display: none;">\
  142. <div class="panel-heading">\
  143. <div class="toolbar" style="height: 36px;">\
  144. Editing Row #<span class="row-index"></span>\
  145. <button class="btn btn-success pull-right" \
  146. title="'+wn._("Close")+'"\
  147. style="margin-left: 7px;">\
  148. <i class="icon-ok"></i></button>\
  149. <button class="btn btn-default pull-right grid-insert-row" \
  150. title="'+wn._("Insert Row")+'"\
  151. style="margin-left: 7px;">\
  152. <i class="icon-plus"></i></button>\
  153. <button class="btn btn-danger pull-right"\
  154. title="'+wn._("Delete Row")+'"\
  155. ><i class="icon-trash"></i></button>\
  156. </div>\
  157. </div>\
  158. <div class="form-area"></div>\
  159. </div>\
  160. <div class="divider row"></div>\
  161. </div>')
  162. .appendTo(this.parent)
  163. .data("grid_row", this);
  164. if(this.doc) {
  165. this.wrapper
  166. .attr("data-idx", this.doc.idx)
  167. .find(".row-index").html(this.doc.idx)
  168. this.wrapper.find(".data-row, .panel-heading")
  169. .click(function() {
  170. me.toggle_view();
  171. return false;
  172. });
  173. this.set_button_events();
  174. }
  175. this.form_panel = this.wrapper.find(".panel");
  176. this.row = this.wrapper.find(".data-row");
  177. this.form_area = this.wrapper.find(".form-area");
  178. this.make_columns();
  179. if(this.doc) {
  180. this.set_data();
  181. }
  182. },
  183. set_button_events: function() {
  184. var me = this;
  185. this.wrapper.find(".btn-danger").click(function() {
  186. me.wrapper.fadeOut(function() {
  187. wn.model.clear_doc(me.doc.doctype, me.doc.name);
  188. me.frm.dirty();
  189. me.grid.refresh();
  190. });
  191. return false;
  192. });
  193. this.wrapper.find(".grid-insert-row").click(function() {
  194. var idx = me.doc.idx;
  195. me.toggle_view(false);
  196. me.grid.add_new_row(idx);
  197. return false;
  198. })
  199. },
  200. refresh: function() {
  201. this.doc = locals[this.doc.doctype][this.doc.name];
  202. // re write columns
  203. this.make_columns();
  204. // refersh form fields
  205. if(this.show) {
  206. $.each(this.fields, function(i, f) {
  207. f.refresh();
  208. });
  209. }
  210. },
  211. make_columns: function() {
  212. var me = this,
  213. total_colsize = 1;
  214. me.row.empty();
  215. col = $('<div class="col col-lg-1 row-index">' + (me.doc ? me.doc.idx : "#")+ '</div>')
  216. .appendTo(me.row)
  217. $.each(me.docfields, function(ci, df) {
  218. if(!df.hidden && !df.print_hide && me.grid.frm.perm[df.permlevel][READ]) {
  219. var colsize = 2,
  220. txt = me.doc ?
  221. wn.format(me.doc[df.fieldname], df, null, me.doc) :
  222. df.label;
  223. switch(df.fieldtype) {
  224. case "Text":
  225. colsize = 3;
  226. break;
  227. case "Check":
  228. colsize = 1;
  229. break;
  230. }
  231. total_colsize += colsize
  232. if(total_colsize > 12)
  233. return false;
  234. $col = $('<div class="col col-lg-'+colsize+'">'
  235. + txt + '</div>')
  236. .css({
  237. "overflow": "hidden",
  238. "text-overflow": "ellipsis",
  239. "white-space": "nowrap",
  240. "padding-right": "0px"
  241. })
  242. .attr("data-fieldname", df.fieldname)
  243. .data("df", df)
  244. .appendTo(me.row)
  245. if(in_list(["Int", "Currency", "Float"], df.fieldtype))
  246. $col.css({"text-align": "right"})
  247. }
  248. });
  249. },
  250. toggle_view: function(show, callback) {
  251. this.doc = locals[this.doc.doctype][this.doc.name];
  252. // hide other
  253. var open_row = $(".grid-row-open").data("grid_row"),
  254. me = this;
  255. this.fields = [];
  256. this.fields_dict = {};
  257. this.show = show===undefined ?
  258. show = !this.show :
  259. show
  260. if(show && open_row) {
  261. if(open_row==this) {
  262. // already open, do nothing
  263. callback();
  264. return;
  265. } else {
  266. // close other views
  267. open_row.toggle_view(false);
  268. }
  269. }
  270. this.make_columns();
  271. this.wrapper.toggleClass("grid-row-open", this.show);
  272. this.show && this.render_form()
  273. this.show && this.row.toggle(false);
  274. this.form_panel.slideToggle(this.show, function() {
  275. if(me.show) {
  276. me.form_area.find(":input:first").focus();
  277. } else {
  278. $(me.form_area).empty();
  279. me.row.toggle(true);
  280. }
  281. callback && callback();
  282. });
  283. },
  284. render_form: function() {
  285. var me = this,
  286. cnt = 0,
  287. row = $('<div class="row">').appendTo(me.form_area),
  288. col1 = $('<div class="col col-lg-6"></div>').appendTo(row),
  289. col2 = $('<div class="col col-lg-6"></div>').appendTo(row),
  290. len = $.map(me.docfields, function(d) {
  291. return !d.hidden ? true : null }).length;
  292. len = (len + len % 2) / 2;
  293. $.each(me.docfields, function(ci, df) {
  294. if(!df.hidden) {
  295. var fieldwrapper = $('<div>')
  296. .appendTo(ci <= len ? col1 : col2)
  297. var fieldobj = make_field(df, me.parent_df.options,
  298. fieldwrapper.get(0), me.frm);
  299. fieldobj.docname = me.doc.name;
  300. fieldobj.refresh();
  301. fieldobj.input &&
  302. $(fieldobj.input).css({"max-height": "100px"});
  303. // set field properties
  304. // used for setting custom get queries in links
  305. if(me.grid.fieldinfo[df.fieldname])
  306. $.extend(fieldobj, me.grid.fieldinfo[df.fieldname]);
  307. me.fields.push(fieldobj);
  308. me.fields_dict[df.fieldname] = fieldobj;
  309. cnt++;
  310. }
  311. });
  312. if(this.grid.display_status!="Write" || this.grid.static_rows) {
  313. this.wrapper.find(".btn-danger, .grid-insert-row").toggle(false);
  314. return;
  315. }
  316. },
  317. set_data: function() {
  318. this.wrapper.data({
  319. "doc": this.doc
  320. })
  321. },
  322. set_value: function(fieldname, value) {
  323. // in row
  324. var $col = this.row.find("[data-fieldname='"+fieldname+"']");
  325. $col.length && $col.html(wn.format(value, $col.data("df"), null, this.doc));
  326. // in form
  327. if(this.fields_dict && this.fields_dict[fieldname]) {
  328. this.fields_dict[fieldname].set_input(value);
  329. }
  330. },
  331. refresh_field: function(fieldname) {
  332. var $col = this.row.find("[data-fieldname='"+fieldname+"']");
  333. if($col.length) {
  334. var value = wn.model.get_value(this.doc.doctype, this.doc.name, fieldname);
  335. $col.html(wn.format(value, $col.data("df"), null, this.doc));
  336. }
  337. // in form
  338. if(this.fields_dict && this.fields_dict[fieldname]) {
  339. this.fields_dict[fieldname].refresh();
  340. }
  341. },
  342. });