25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 
 

447 satır
11 KiB

  1. // _f.Grid
  2. _f.cur_grid_cell = null;
  3. _f.Grid = function(parent) { }
  4. _f.Grid.prototype.init = function(parent, row_height) {
  5. var me = this;
  6. this.col_idx_by_name = {}
  7. this.alt_row_bg = '#F2F2FF';
  8. this.row_height = row_height;
  9. // make the grid
  10. if(!row_height)this.row_height = '26px';
  11. this.make_ui(parent);
  12. // Sr No
  13. this.insert_column('', '', 'Int', 'Sr', '50px', '', [1,0,0]);
  14. if(this.oninit)this.oninit();
  15. // bind clicks
  16. $(this.wrapper).bind('keydown', function(e) {
  17. me.notify_keypress(e, e.which);
  18. })
  19. // reset grid heights after complete is triggerd on the form
  20. $(cur_frm.wrapper).bind('render_complete', function() {
  21. me.set_ht();
  22. });
  23. }
  24. _f.Grid.prototype.make_ui = function(parent) {
  25. var ht = make_table($a(parent, 'div'), 1, 2, '100%', ['60%','40%']);
  26. this.main_title = $td(ht,0,0); this.main_title.className = 'columnHeading';
  27. $td(ht,0,1).style.textAlign = 'right';
  28. this.tbar_div = $a($td(ht,0,1), 'div', 'grid_tbarlinks');
  29. this.tbar_tab = make_table(this.tbar_div,1,4,'100%',['25%','25%','25%','25%']);
  30. this.wrapper = $a(parent, 'div', 'grid_wrapper');
  31. this.head_wrapper = $a(this.wrapper, 'div', 'grid_head_wrapper');
  32. this.head_tab = $a(this.head_wrapper, 'table', 'grid_head_table');
  33. this.head_row = this.head_tab.insertRow(0);
  34. this.tab_wrapper = $a(this.wrapper, 'div', 'grid_tab_wrapper');
  35. this.tab = $a(this.tab_wrapper, 'table', 'grid_table');
  36. var me = this;
  37. this.wrapper.onscroll = function() { me.head_wrapper.style.top = me.wrapper.scrollTop+'px'; }
  38. }
  39. _f.Grid.prototype.show = function() {
  40. if(this.can_edit && this.field.df['default'].toLowerCase()!='no toolbar') {
  41. $ds(this.tbar_div);
  42. if(this.can_add_rows) {
  43. $td(this.tbar_tab, 0, 0).style.display = 'table-cell';
  44. $td(this.tbar_tab, 0, 1).style.display = 'table-cell';
  45. } else {
  46. $td(this.tbar_tab, 0, 0).style.display = 'none';
  47. $td(this.tbar_tab, 0, 1).style.display = 'none';
  48. }
  49. } else {
  50. $dh(this.tbar_div);
  51. }
  52. $ds(this.wrapper);
  53. }
  54. _f.Grid.prototype.hide = function() {
  55. $dh(this.wrapper); $dh(this.tbar_div);
  56. }
  57. _f.Grid.prototype.insert_column = function(doctype, fieldname, fieldtype, label, width, options, perm, reqd) {
  58. var idx = this.head_row.cells.length;
  59. if(!width)width = '100px';
  60. if((width+'').slice(-2)!='px') {
  61. width= width + 'px';
  62. }
  63. var col = this.head_row.insertCell(idx);
  64. col.doctype = doctype; // for report (fields may be from diff doctypes)
  65. col.fieldname = fieldname;
  66. col.fieldtype = fieldtype;
  67. col.innerHTML = '<div>'+label+'</div>';
  68. col.label = label;
  69. if(reqd)
  70. col.childNodes[0].style.color = "#D22";
  71. col.style.width = width;
  72. col.options = options;
  73. col.perm = perm;
  74. this.col_idx_by_name[fieldname] = idx;
  75. }
  76. _f.Grid.prototype.reset_table_width = function() {
  77. var w = 0;
  78. for(var i=0, len=this.head_row.cells.length; i<len; i++) {
  79. w += cint(this.head_row.cells[i].style.width);
  80. }
  81. this.head_tab.style.width = w + 'px';
  82. this.tab.style.width = w + 'px';
  83. }
  84. _f.Grid.prototype.set_column_disp = function(fieldname, show) {
  85. var cidx = this.col_idx_by_name[fieldname];
  86. if(!cidx) {
  87. msgprint('Trying to hide unknown column: ' + fieldname);
  88. return;
  89. }
  90. var disp = show ? 'table-cell' : 'none';
  91. // head
  92. this.head_row.cells[cidx].style.display = disp;
  93. // body
  94. for(var i=0, len=this.tab.rows.length; i<len; i++) {
  95. var cell = this.tab.rows[i].cells[cidx];
  96. cell.style.display = disp;
  97. }
  98. // reset table width
  99. this.reset_table_width();
  100. }
  101. _f.Grid.prototype.append_row = function(idx, docname) {
  102. if(!idx)idx = this.tab.rows.length;
  103. var row = this.tab.insertRow(idx);
  104. row.docname = docname;
  105. if(idx % 2)var odd=true; else var odd=false;
  106. var me = this;
  107. // make cells
  108. for(var i=0; i<this.head_row.cells.length; i++){
  109. var cell = row.insertCell(i);
  110. var hc = this.head_row.cells[i];
  111. // ape style of head
  112. cell.style.width = hc.style.width;
  113. cell.style.display = hc.style.display;
  114. cell.row = row;
  115. cell.grid = this;
  116. cell.className = 'grid_cell';
  117. cell.div = $a(cell, 'div', 'grid_cell_div');
  118. if(this.row_height) {
  119. cell.div.style.height = this.row_height; }
  120. cell.div.cell = cell;
  121. cell.div.onclick = function(e) { me.cell_select(this.cell); }
  122. if(odd) {
  123. $bg(cell, this.alt_row_bg); cell.is_odd = 1;
  124. cell.div.style.border = '2px solid ' + this.alt_row_bg;
  125. } else $bg(cell,'#FFF');
  126. if(!hc.fieldname) cell.div.style.cursor = 'default'; // Index
  127. }
  128. this.set_ht();
  129. return row;
  130. }
  131. _f.Grid.prototype.refresh_cell = function(docname, fieldname) {
  132. for(var r=0;r<this.tab.rows.length;r++) {
  133. if(this.tab.rows[r].docname==docname) {
  134. for(var c=0;c<this.head_row.cells.length;c++) {
  135. var hc = this.head_row.cells[c];
  136. if(hc.fieldname==fieldname) {
  137. this.set_cell_value(this.tab.rows[r].cells[c]);
  138. }
  139. }
  140. }
  141. }
  142. }
  143. // for form edit
  144. _f.cur_grid;
  145. _f.cur_grid_ridx;
  146. _f.Grid.prototype.set_cell_value = function(cell) {
  147. // if newrow
  148. if(cell.row.is_newrow)return;
  149. // show static
  150. var hc = this.head_row.cells[cell.cellIndex];
  151. if(hc.fieldname) {
  152. var v = locals[hc.doctype][cell.row.docname][hc.fieldname];
  153. } else {
  154. var v = (cell.row.rowIndex + 1); // Index
  155. }
  156. if(v==null){ v=''; }
  157. var me = this;
  158. // variations
  159. if(cell.cellIndex) {
  160. var ft = hc.fieldtype;
  161. if(ft=='Link' && cur_frm.doc.docstatus < 1) ft='Data';
  162. $s(cell.div, v, ft, hc.options);
  163. } else {
  164. // Index column
  165. cell.div.style.padding = '2px';
  166. cell.div.style.textAlign = 'left';
  167. cell.innerHTML = '';
  168. var t = make_table(cell,1,3,'60px',['20px','20px','20px'],{verticalAlign: 'middle', padding:'2px'});
  169. $y($td(t,0,0),{paddingLeft:'4px'});
  170. $td(t,0,0).innerHTML = cell.row.rowIndex + 1;
  171. if(cur_frm.editable && this.can_edit) {
  172. var ed = $a($td(t,0,1),'div','wn-icon ic-doc_edit',{cursor:'pointer'}); ed.cell = cell; ed.title = 'Edit Row';
  173. ed.onclick = function() {
  174. _f.cur_grid = me;
  175. _f.cur_grid_ridx = this.cell.row.rowIndex;
  176. _f.edit_record(me.doctype, this.cell.row.docname, 1);
  177. }
  178. } else {
  179. cell.div.innerHTML = (cell.row.rowIndex + 1);
  180. cell.div.style.cursor = 'default';
  181. cell.div.onclick = function() { }
  182. }
  183. }
  184. }
  185. // if clicked on whitespace
  186. // and a grid cell is selected
  187. // deselect the cell
  188. $(document).bind('click', function(e) {
  189. var is_target_toolbar = function() {
  190. return $(e.target).parents('.grid_tbarlinks').length;
  191. }
  192. var is_target_input = function() {
  193. return $(e.target).parents().get().indexOf(_f.cur_grid_cell)!=-1;
  194. }
  195. if(_f.cur_grid_cell && !is_target_input() && !is_target_toolbar()) {
  196. if(!(text_dialog && text_dialog.display)
  197. && !datepicker_active && !(selector && selector.display) && !(cur_autosug)) {
  198. _f.cur_grid_cell.grid.cell_deselect();
  199. }
  200. }
  201. });
  202. _f.Grid.prototype.cell_deselect = function() {
  203. if(_f.cur_grid_cell) {
  204. var c = _f.cur_grid_cell;
  205. c.grid.remove_template(c);
  206. c.div.className = 'grid_cell_div';
  207. if(c.is_odd) c.div.style.border = '2px solid ' + c.grid.alt_row_bg;
  208. else c.div.style.border = '2px solid #FFF';
  209. _f.cur_grid_cell = null;
  210. _f.cur_grid = null;
  211. }
  212. }
  213. _f.Grid.prototype.cell_select = function(cell, ri, ci) {
  214. if(ri!=null && ci!=null)
  215. cell = this.tab.rows[ri].cells[ci];
  216. var hc = this.head_row.cells[cell.cellIndex];
  217. if(!hc.template) {
  218. this.make_template(hc);
  219. }
  220. hc.template.perm = this.field ? this.field.perm : hc.perm; // get latest permissions
  221. if(hc.fieldname && hc.template.get_status()=='Write') {
  222. this.cell_deselect();
  223. cell.div.style.border = '2px solid #88F';
  224. _f.cur_grid_cell = cell;
  225. this.add_template(cell);
  226. }
  227. }
  228. _f.Grid.prototype.add_template = function(cell) {
  229. if(!cell.row.docname && this.add_newrow) { // activate new row here
  230. this.add_newrow();
  231. this.cell_select(cell);
  232. } else {
  233. var hc = this.head_row.cells[cell.cellIndex];
  234. cell.div.innerHTML = '';
  235. cell.div.appendChild(hc.template.wrapper);
  236. hc.template.activate(cell.row.docname);
  237. hc.template.activated=1;
  238. if(hc.template.input && hc.template.input.set_width) {
  239. hc.template.input.set_width($(cell).width());
  240. }
  241. }
  242. }
  243. _f.Grid.prototype.get_field = function(fieldname) { // get template
  244. for(var i=0;i<this.head_row.cells.length;i++) {
  245. var hc = this.head_row.cells[i];
  246. if(hc.fieldname == fieldname) {
  247. if(!hc.template) {
  248. this.make_template(hc);
  249. }
  250. return hc.template;
  251. }
  252. }
  253. return {} // did not find, return empty object not to throw error in get_query
  254. }
  255. _f.grid_date_cell = '';
  256. _f.grid_refresh_date = function() {
  257. _f.grid_date_cell.grid.set_cell_value(_f.grid_date_cell);
  258. }
  259. _f.grid_refresh_field = function(temp, input) {
  260. if(input.value != _f.get_value(temp.doctype, temp.docname, temp.df.fieldname))
  261. if(input.onchange)input.onchange();
  262. }
  263. _f.Grid.prototype.remove_template = function(cell) {
  264. var hc = this.head_row.cells[cell.cellIndex];
  265. if(!hc.template)return;
  266. if(!hc.template.activated)return;
  267. if(hc.template.txt) {
  268. if(hc.template.df.fieldtype=='Date') {
  269. // for calendar popup. the value will come after this
  270. _f.grid_date_cell = cell;
  271. setTimeout('_f.grid_refresh_date()', 100);
  272. }
  273. if(hc.template.txt.value)
  274. _f.grid_refresh_field(hc.template, hc.template.txt);
  275. } else if(hc.template.input) {
  276. _f.grid_refresh_field(hc.template, hc.template.input);
  277. }
  278. if(hc.template && hc.template.wrapper.parentNode)
  279. cell.div.removeChild(hc.template.wrapper);
  280. this.set_cell_value(cell);
  281. hc.template.activated=0;
  282. }
  283. _f.Grid.prototype.notify_keypress = function(e, keycode) {
  284. if(keycode>=37 && keycode<=40 && e.shiftKey) {
  285. if(text_dialog && text_dialog.display) {
  286. return;
  287. }
  288. } else
  289. return;
  290. if(!_f.cur_grid_cell) return;
  291. if(_f.cur_grid_cell.grid != this) return;
  292. var ri = _f.cur_grid_cell.row.rowIndex;
  293. var ci = _f.cur_grid_cell.cellIndex;
  294. switch(keycode) {
  295. case 38: // up
  296. if (ri > 0) {
  297. this.cell_select('', ri - 1, ci);
  298. } break;
  299. case 40: // down
  300. if (ri < (this.tab.rows.length - 1)) {
  301. this.cell_select('', ri + 1, ci);
  302. } break;
  303. case 39: // right
  304. if (ci < (this.head_row.cells.length - 1)) {
  305. this.cell_select('', ri, ci + 1);
  306. } break;
  307. case 37: // left
  308. if (ci > 1) {
  309. this.cell_select('', ri, ci - 1);
  310. } break;
  311. }
  312. }
  313. _f.Grid.prototype.make_template = function(hc) {
  314. hc.template = make_field(get_field(hc.doctype, hc.fieldname), hc.doctype, '', this.field.frm, true);
  315. hc.template.grid = this;
  316. }
  317. _f.Grid.prototype.append_rows = function(n) {
  318. for(var i=0;i<n;i++) this.append_row();
  319. }
  320. _f.Grid.prototype.truncate_rows = function(n) {
  321. for(var i=0;i<n;i++) this.tab.deleteRow(this.tab.rows.length-1);
  322. }
  323. _f.Grid.prototype.set_data = function(data) {
  324. // deselect if not done yet
  325. this.cell_deselect();
  326. // set table widths
  327. this.reset_table_width();
  328. // append if reqd
  329. if(data.length > this.tab.rows.length)
  330. this.append_rows(data.length - this.tab.rows.length);
  331. // truncate if reqd
  332. if(data.length < this.tab.rows.length)
  333. this.truncate_rows(this.tab.rows.length - data.length);
  334. // set data
  335. for(var ridx=0;ridx<data.length;ridx++) {
  336. this.refresh_row(ridx, data[ridx]);
  337. }
  338. if(this.can_add_rows && this.make_newrow) {
  339. this.make_newrow();
  340. }
  341. if(this.wrapper.onscroll)this.wrapper.onscroll();
  342. }
  343. _f.Grid.prototype.set_ht = function() {
  344. var max_ht = cint(0.37 * screen.width);
  345. var ht = $(this.tab).height() + $(this.head_tab).height() + 30;
  346. if(ht < 100)
  347. ht=100;
  348. if(ht > max_ht) ht = max_ht;
  349. ht += 4;
  350. $y(this.wrapper,{height:ht+'px'});
  351. }
  352. _f.Grid.prototype.refresh_row = function(ridx, docname) {
  353. var row = this.tab.rows[ridx];
  354. row.docname = docname;
  355. row.is_newrow = false;
  356. for(var cidx=0; cidx<row.cells.length; cidx++) {
  357. this.set_cell_value(row.cells[cidx]);
  358. }
  359. }