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.

docbrowser.js 20 KiB

14 vuotta sitten
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742
  1. /* ItemBrowserPage
  2. + this.my_page
  3. + this.page_layout (wn.PageLayout)
  4. + this.wrapper
  5. + this.body
  6. + ItemBrowser
  7. + this.wrapper
  8. + this.wtab
  9. + body
  10. + has_results
  11. + head
  12. + toolbar_area
  13. + no_result
  14. + loading_div
  15. + sidebar
  16. */
  17. ItemBrowserPage = function() {
  18. this.lists = {};
  19. this.dt_details = {};
  20. this.cur_list = null;
  21. this.my_page = page_body.add_page('ItemBrowser');
  22. this.wrapper = $a(this.my_page,'div');
  23. }
  24. // -------------------------------------------------
  25. ItemBrowserPage.prototype.show = function(dt, label, field_list) {
  26. var me = this;
  27. if(this.cur_list && this.cur_list.dt != dt) $dh(this.cur_list.layout.wrapper);
  28. if(!me.lists[dt]) {
  29. me.lists[dt] = new ItemBrowser(me.wrapper, dt, label, field_list);
  30. }
  31. me.cur_list = me.lists[dt];
  32. me.cur_list.show();
  33. page_body.change_to('ItemBrowser');
  34. }
  35. // -------------------------------------------------
  36. ItemBrowser = function(parent, dt, label, field_list) {
  37. var me = this;
  38. this.label = label ? label : dt;
  39. this.dt = dt;
  40. this.field_list = field_list;
  41. this.tag_filter_dict = {};
  42. this.items = [];
  43. this.cscript = {}; // dictionary for custom scripting
  44. // heading
  45. var l = get_doctype_label(dt);
  46. l = (l.toLowerCase().substr(-4) == 'list') ? l : (l + ' List')
  47. // make the layout
  48. this.layout = new wn.PageLayout({
  49. parent: parent,
  50. main_width: '75%',
  51. sidebar_width: '25%',
  52. heading: l
  53. })
  54. this.layout.no_records = $a($td(this.layout.wtab,0,0), 'div');
  55. // header (?)
  56. this.desc_area = $a(this.layout.head, 'div', 'field_description', '');
  57. $dh(this.layout.page_head.separator);
  58. // areas
  59. this.no_result_area = $a(this.layout.no_records, 'div','layout_wrapper',{fontSize:'14px', textAlign:'center', padding:'200px 0px'});
  60. // loading...
  61. this.layout.loading = $a($td(this.layout.wtab,0,0), 'div','layout_wrapper',{padding:'200px 0px', textAlign:'center', fontSize:'14px', color:'#444', display:'none'});
  62. this.layout.loading.innerHTML = 'Loading<img src="lib/images/ui/button-load.gif" style="margin-bottom: -2px; margin-left: 8px">';
  63. // setup toolbar
  64. this.setup_toolbar();
  65. // setup list and sidebar
  66. this.setup_sidebar();
  67. }
  68. // one of "loading", "no_result", "main"
  69. ItemBrowser.prototype.show_area = function(area) {
  70. $ds(this.layout[area]);
  71. var al = ['loading','no_records','main'];
  72. for(var a in al) {
  73. if(al[a]!=area)
  74. $dh(this.layout[al[a]]);
  75. }
  76. }
  77. ItemBrowser.prototype.setup_sidebar = function() {
  78. var me = this;
  79. // table
  80. $y(this.layout.sidebar_area, {paddingTop:'53px'});
  81. // sidebar
  82. this.sidebar = new wn.widgets.PageSidebar(this.layout.sidebar_area, {
  83. sections: [
  84. {
  85. title: 'Top Tags',
  86. render: function(body) {
  87. new wn.widgets.TagCloud(body, me.dt, function(tag) { me.set_tag_filter(tag) });
  88. }
  89. }
  90. ]
  91. });
  92. }
  93. // setup the toolbar and archiving and deleteing functionality
  94. ItemBrowser.prototype.setup_toolbar = function() {
  95. var me = this;
  96. var parent = this.layout.toolbar_area
  97. // toolbar
  98. this.main_toolbar = $a(parent, 'div', '', {padding: '3px', backgroundColor:'#EEE'});
  99. $br(this.main_toolbar, '3px'); $gr(this.main_toolbar, '#DDD', '#CCC');
  100. this.sub_toolbar = $a(parent, 'div', '', {marginBottom:'7px', padding: '3px', textAlign:'right', fontSize:'11px', color:'#444'});
  101. // archives label
  102. this.archives_label = $a(parent, 'div', 'help_box_big',{display:'none'},'Showing from Archives');
  103. var span = $a(this.archives_label, 'span', 'link_type', {marginLeft:'8px'}, 'Show Active');
  104. span.onclick = function() { me.show_archives.checked = 0; me.show_archives.onclick(); }
  105. this.trend_area = $a(parent, 'div', '', {marginBottom:'16px', padding: '4px', backgroundColor:'#EEF', border: '1px solid #CCF', display:'none'});
  106. $br(this.trend_area, '5px');
  107. // tag filters
  108. this.tag_filters = $a(parent, 'div', '', {marginBottom:'8px', display:'none', padding:'6px 8px 8px 8px', backgroundColor:'#FFD'});
  109. var span = $a(this.tag_filters,'span','',{marginRight:'4px',color:'#444'}); span.innerHTML = '<i>Showing for:</i>';
  110. this.tag_area = $a(this.tag_filters, 'span');
  111. // select all area
  112. var div = $a(parent, 'div', '', {margin:'3px 5px'});
  113. var chk = $a_input(div, 'checkbox');
  114. var lab = $a(div, 'span', '', {marginLeft:'9px'}, 'Select All');
  115. chk.onclick = function() {
  116. for(var i=0; i<me.items.length; i++) {
  117. me.items[i].check.checked = this.checked;
  118. me.items[i].check.onclick();
  119. }
  120. }
  121. this.select_all = chk;
  122. }
  123. // -------------------------------------------------
  124. ItemBrowser.prototype.make_checkbox = function(status, checked) {
  125. var me = this;
  126. var chk = $a_input(this.sub_toolbar, 'checkbox');
  127. var lab = $a(this.sub_toolbar, 'span', '', {marginRight:'8px'}, 'Show ' + status);
  128. chk.onclick = function() { me.run(); }
  129. chk.checked = checked;
  130. this['check_'+status] = chk;
  131. }
  132. ItemBrowser.prototype.get_status_check = function() {
  133. ret = [];
  134. if(this.check_Draft.checked) ret.push(0);
  135. if(this.check_Submitted.checked) ret.push(1);
  136. if(this.check_Cancelled.checked) ret.push(2);
  137. if(!ret.length) {
  138. msgprint('Atleast of Draft, Submitted or Cancelled must be checked!');
  139. return
  140. }
  141. return ret;
  142. }
  143. ItemBrowser.prototype.make_toolbar = function() {
  144. var me = this;
  145. // description
  146. if(this.dt_details.description)this.desc_area.innerHTML = this.dt_details.description;
  147. // new button
  148. if(inList(profile.can_create, this.dt)) {
  149. this.new_button = $btn(this.main_toolbar, '+ New ' + get_doctype_label(this.dt), function() { newdoc(me.dt) }, {fontWeight:'bold',marginRight:'0px'}, 'green');
  150. }
  151. // archive, delete
  152. if(in_list(profile.can_write, this.dt)) {
  153. this.archive_btn = $btn(this.main_toolbar, 'Archive', function() { me.archive_items(); }, {marginLeft:'24px'});
  154. }
  155. if(this.dt_details.can_cancel) {
  156. this.delete_btn = $btn(this.main_toolbar, 'Delete', function() { me.delete_items(); });
  157. }
  158. // search box
  159. this.search_input = $a(this.main_toolbar, 'input', '', {width:'120px', marginLeft:'24px', border:'1px solid #AAA'});
  160. this.search_btn = $btn(this.main_toolbar, 'Search', function() { me.run(); }, {marginLeft:'4px'});
  161. // show hide filters
  162. this.filters_on = 0;
  163. this.filter_btn = $ln(this.main_toolbar, 'Show Filters', function() { me.show_filters(); }, {marginLeft:'24px'});
  164. // show hide trend
  165. //this.trend_on = 0; this.trend_loaded = 0;
  166. //this.trend_btn = $ln(this.main_toolbar, 'Show Activity', function() { me.show_activity(); }, {marginLeft:'24px'});
  167. // checks for show cancelled and show archived
  168. if(this.dt_details.submittable) {
  169. this.make_checkbox('Draft', 1)
  170. this.make_checkbox('Submitted', 1)
  171. this.make_checkbox('Cancelled', 0)
  172. }
  173. this.set_archiving();
  174. }
  175. // -------------------------------------------------
  176. ItemBrowser.prototype.set_archiving = function() {
  177. var me = this;
  178. this.show_archives = $a_input(this.sub_toolbar, 'checkbox');
  179. var lab = $a(this.sub_toolbar, 'span'); lab.innerHTML = 'Show Archives';
  180. this.show_archives.onclick = function() {
  181. if(this.checked) {
  182. if(me.archive_btn) me.archive_btn.innerHTML = 'Restore';
  183. $(me.archives_label).slideDown();
  184. } else {
  185. if(me.archive_btn) me.archive_btn.innerHTML = 'Archive';
  186. $(me.archives_label).slideUp();
  187. }
  188. me.run();
  189. }
  190. }
  191. // -------------------------------------------------
  192. ItemBrowser.prototype.show_filters = function() {
  193. if(this.filters_on) {
  194. $(this.lst.filter_wrapper).slideUp();
  195. this.filters_on = 0;
  196. this.filter_btn.innerHTML = 'Advanced Search';
  197. } else {
  198. $(this.lst.filter_wrapper).slideDown();
  199. this.filters_on = 1;
  200. this.filter_btn.innerHTML = 'Hide Filters';
  201. }
  202. }
  203. // -------------------------------------------------
  204. ItemBrowser.prototype.show_activity = function() {
  205. var me = this;
  206. if(this.trend_on) {
  207. $(this.trend_area).slideUp();
  208. me.trend_btn.innerHTML = 'Show Activity';
  209. me.trend_on = 0;
  210. } else {
  211. // show
  212. if(!this.trend_loaded) {
  213. // load the trend
  214. var callback = function(r,rt) {
  215. me.show_trend(r.message.trend);
  216. $(me.trend_area).slideDown();
  217. me.trend_btn.done_working();
  218. me.trend_btn.innerHTML = 'Hide Activity';
  219. me.trend_loaded = 1;
  220. me.trend_on = 1;
  221. }
  222. $c('webnotes.widgets.menus.get_trend', {'dt':this.dt}, callback);
  223. me.trend_btn.set_working();
  224. } else {
  225. // slide up and dwon
  226. $(this.trend_area).slideDown();
  227. me.trend_btn.innerHTML = 'Hide Activity';
  228. me.trend_on = 1;
  229. }
  230. }
  231. }
  232. // -------------------------------------------------
  233. ItemBrowser.prototype.show = function(onload) {
  234. $ds(this.layout.wrapper);
  235. if(onload) this.cscript.onload = onload
  236. if(this.loaded && this.lst.n_records) return;
  237. this.show_area('loading');
  238. var me = this;
  239. var callback = function(r, rt) {
  240. if(r.message == 'Yes') {
  241. if(!me.loaded) {
  242. me.load_details();
  243. } else {
  244. me.show_results();
  245. }
  246. } else {
  247. if(me.cscript.onload) me.cscript.onload(this);
  248. me.show_no_result();
  249. }
  250. }
  251. $c('webnotes.widgets.menus.has_result', {'dt': this.dt}, callback);
  252. }
  253. // -------------------------------------------------
  254. ItemBrowser.prototype.load_details = function() {
  255. var me = this;
  256. var callback = function(r,rt) {
  257. me.dt_details = r.message;
  258. if(r.message) {
  259. me.make_toolbar();
  260. me.make_the_list(me.dt, me.layout.body);
  261. // fire onload
  262. if(me.cscript.onload)
  263. me.cscript.onload(me);
  264. me.show_results();
  265. }
  266. }
  267. var fl = this.field_list ? this.field_list.split('\n') : [];
  268. $c('webnotes.widgets.menus.get_dt_details', {'dt': this.dt, 'fl': JSON.stringify(fl)}, callback);
  269. this.loaded = 1;
  270. }
  271. // -------------------------------------------------
  272. ItemBrowser.prototype.show_results = function() {
  273. this.show_area('main');
  274. set_title(get_doctype_label(this.label));
  275. }
  276. // -------------------------------------------------
  277. ItemBrowser.prototype.show_trend = function(trend) {
  278. var maxval = 0;
  279. for(var key in trend) { if(trend[key]>maxval) maxval = trend[key] };
  280. // head
  281. var div = $a(this.trend_area, 'div','',{marginLeft:'32px'}); div.innerHTML = 'Activity in last 30 days';
  282. var wrapper_tab = make_table(this.trend_area, 1, 2, '100%', ['20px',null], {padding:'2px 4px',fontSize:'10px',color:'#888'});
  283. // y-label
  284. var ylab_tab = make_table($td(wrapper_tab,0,0),2,1,'100%',['100%'],{verticalAlign:'top', textAlign:'right',height:'24px'});
  285. $td(ylab_tab,0,0).innerHTML = maxval;
  286. $y($td(ylab_tab,1,0),{verticalAlign:'bottom'});
  287. $td(ylab_tab,1,0).innerHTML = '0';
  288. // infogrid
  289. var tab = make_table($td(wrapper_tab,0,1), 1, 30, '100%', [],
  290. {width:10/3 + '%', border:'1px solid #DDD', height:'40px', verticalAlign:'bottom', textAlign:'center', padding:'2px', backgroundColor:'#FFF'});
  291. // labels
  292. var labtab = make_table($td(wrapper_tab,0,1), 1, 6, '100%', [],
  293. {width:100/6 + '%', border:'1px solid #EEF', height:'16px',color:'#888',textAlign:'right',fontSize:'10px'});
  294. for(var i=0; i<30; i++) {
  295. var div = $a($td(tab,0,29-i),'div','',{backgroundColor:'#4AC', width:'50%', margin:'auto', height:(trend[i+''] ? (trend[i+'']*100/maxval) : 0) + '%'});
  296. div.setAttribute('title', trend[i] + ' records');
  297. // date string
  298. if(i % 5 == 0) {
  299. $td(labtab,0,5-(i/5)).innerHTML = dateutil.obj_to_user(dateutil.add_days(new Date(), -i));
  300. $y($td(tab,0,i-1),{'backgroundColor':'#EEE'});
  301. }
  302. }
  303. $td(labtab,0,5).innerHTML = 'Today';
  304. }
  305. // -------------------------------------------------
  306. ItemBrowser.prototype.show_no_result = function() {
  307. this.show_area('no_records');
  308. this.no_result_area.innerHTML = repl('No %(dt)s found. <span class="link_type" onclick="newdoc(\'%(dt)s\')">Click here</span> to create your first %(dt)s!', {dt:get_doctype_label(this.dt)});
  309. set_title(get_doctype_label(this.label));
  310. }
  311. // -------------------------------------------------
  312. ItemBrowser.prototype.make_new = function(dt, label, field_list) {
  313. // make the list
  314. this.make_the_list(dt, this.layout.body);
  315. }
  316. // -------------------------------------------------
  317. ItemBrowser.prototype.add_search_conditions = function(q) {
  318. if(this.search_input.value) {
  319. q.conds += ' AND ' + q.table + '.name LIKE "%'+ this.search_input.value +'%"';
  320. }
  321. }
  322. // -------------------------------------------------
  323. ItemBrowser.prototype.add_tag_conditions = function(q) {
  324. var me = this;
  325. if(keys(me.tag_filter_dict).length) {
  326. var cl = [];
  327. for(var key in me.tag_filter_dict) {
  328. var val = key;
  329. var op = '=';
  330. var fn = me.tag_filter_dict[key].fieldname;
  331. fn = fn ? fn : '_user_tags';
  332. // conditions based on user tags
  333. if(fn=='docstatus')val=(key=='Draft'?'0':'1');
  334. else if(fn=='_user_tags'){ val='%,'+key + '%'; op=' LIKE '; }
  335. cl.push(q.table + '.`' + fn + '`'+op+'"' + val + '"');
  336. }
  337. if(cl)
  338. q.conds += ' AND ' + cl.join(' AND ') + ' ';
  339. }
  340. }
  341. // -------------------------------------------------
  342. ItemBrowser.prototype.make_the_list = function(dt, wrapper) {
  343. var me = this;
  344. var lst = new Listing(dt, 1);
  345. lst.dt = dt;
  346. lst.cl = this.dt_details.columns;
  347. lst.opts = {
  348. cell_style : {padding:'0px 2px'},
  349. alt_cell_style : {backgroundColor:'#FFFFFF'},
  350. hide_export : 1,
  351. hide_print : 1,
  352. hide_rec_label: 0,
  353. show_calc: 0,
  354. show_empty_tab : 0,
  355. show_no_records_label: 1,
  356. show_new: 0,
  357. show_report: 1,
  358. no_border: 1,
  359. append_records: 1,
  360. formatted: 1
  361. }
  362. if(user_defaults.hide_report_builder) lst.opts.show_report = 0;
  363. // build th query
  364. lst.is_std_query = 1;
  365. lst.get_query = function() {
  366. q = {};
  367. var fl = [];
  368. q.table = repl('`%(prefix)s%(dt)s`', {prefix:(me.show_archives.checked ? 'arc' : 'tab'), dt:this.dt});
  369. // columns
  370. for(var i=0;i<this.cl.length;i++) {
  371. if(!(me.show_archives && me.show_archives.checked && this.cl[i][0]=='_user_tags'))
  372. fl.push(q.table+'.`'+this.cl[i][0]+'`')
  373. }
  374. if(me.dt_details.submittable) {
  375. fl.push(q.table + '.docstatus');
  376. var tmp = me.get_status_check();
  377. if(!tmp) { this.query=null; return; }
  378. // docstatus conditions
  379. q.conds = q.table + '.docstatus in ('+ tmp.join(',') +') ';
  380. } else {
  381. q.conds = q.table + '.docstatus != 2'
  382. }
  383. // columns
  384. q.fields = fl.join(', ');
  385. // filter conditions
  386. me.add_tag_conditions(q);
  387. // filter conditions
  388. me.add_search_conditions(q);
  389. this.query = repl("SELECT %(fields)s FROM %(table)s WHERE %(conds)s", q);
  390. this.query_max = repl("SELECT COUNT(*) FROM %(table)s WHERE %(conds)s", q);
  391. if(me.show_archives.checked)
  392. this.prefix = 'arc';
  393. else
  394. this.prefix = 'tab'
  395. }
  396. // make the columns
  397. lst.colwidths=['100%']; lst.coltypes=['Data']; lst.coloptions = [''];
  398. // show cell
  399. lst.show_cell = function(cell, ri, ci, d) {
  400. me.items.push(new ItemBrowserItem(cell, d[ri], me));
  401. }
  402. lst.make(wrapper);
  403. // add the filters
  404. var sf = me.dt_details.filters;
  405. for(var i=0;i< sf.length;i++) {
  406. var fname = sf[i][0]; var label = sf[i][1]; var ftype = sf[i][2]; var fopts = sf[i][3];
  407. if(in_list(['Int','Currency','Float','Date'], ftype)) {
  408. lst.add_filter('From '+label, ftype, fopts, dt, fname, '>=');
  409. lst.add_filter('To '+label, ftype, fopts, dt, fname, '<=');
  410. } else {
  411. lst.add_filter(label, ftype, fopts, dt, fname, (in_list(['Data','Text','Link'], ftype) ? 'LIKE' : ''));
  412. }
  413. }
  414. $dh(lst.filter_wrapper);
  415. // default sort
  416. lst.set_default_sort('modified', 'DESC');
  417. this.lst = lst;
  418. lst.run();
  419. }
  420. // -------------------------------------------------
  421. ItemBrowser.prototype.run = function() {
  422. this.items = [];
  423. this.select_all.checked = false;
  424. this.lst.run();
  425. }
  426. // -------------------------------------------------
  427. ItemBrowser.prototype.get_checked = function() {
  428. var il = [];
  429. for(var i=0; i<this.items.length; i++) {
  430. if(this.items[i].check.checked) il.push([this.dt, this.items[i].dn]);
  431. }
  432. return il;
  433. }
  434. // -------------------------------------------------
  435. ItemBrowser.prototype.delete_items = function() {
  436. var me = this;
  437. if(confirm('This is PERMANENT action and you cannot undo. Continue?'))
  438. $c('webnotes.widgets.menus.delete_items', {'items': JSON.stringify(this.get_checked()) }, function(r, rt) { if(!r.exc) me.run(); })
  439. }
  440. // -------------------------------------------------
  441. ItemBrowser.prototype.archive_items = function() {
  442. var me = this;
  443. var arg = {
  444. 'action': this.show_archives.checked ? 'Restore' : 'Archive'
  445. ,'items': JSON.stringify(this.get_checked())
  446. }
  447. $c('webnotes.widgets.menus.archive_items', arg, function(r, rt) { if(!r.exc) me.run(); })
  448. }
  449. // -------------------------------------------------
  450. ItemBrowser.prototype.set_tag_filter = function(tag) {
  451. var me = this;
  452. // check if exists
  453. if(in_list(keys(me.tag_filter_dict), tag.label)) return;
  454. // create a tag in filters
  455. var filter_tag = new SingleTag({
  456. parent: me.tag_area,
  457. label: tag.label,
  458. dt: me.dt,
  459. color: tag.color
  460. });
  461. filter_tag.fieldname = tag.fieldname;
  462. // remove tag from filters
  463. filter_tag.remove = function(tag_remove) {
  464. $(tag_remove.body).fadeOut();
  465. delete me.tag_filter_dict[tag_remove.label];
  466. // hide everything?
  467. if(!keys(me.tag_filter_dict).length) {
  468. $(me.tag_filters).slideUp(); // hide
  469. }
  470. // run
  471. me.run();
  472. }
  473. // add to dict
  474. me.tag_filter_dict[tag.label] = filter_tag;
  475. $ds(me.tag_filters);
  476. // run
  477. me.run();
  478. }
  479. // ========================== ITEM ==================================
  480. function ItemBrowserItem(parent, det, ib) {
  481. this.wrapper = $a(parent, 'div');
  482. $y(this.wrapper, {borderTop:'1px solid #DDD'});
  483. this.tab = make_table(this.wrapper, 1, 2, '100%', ['24px', null]);
  484. this.body = $a($td(this.tab, 0, 1), 'div');
  485. this.link_area = $a(this.body, 'div')
  486. this.details_area = this.link_area // $a(this.body, 'div');
  487. this.det = det;
  488. this.ib = ib;
  489. this.dn = det[0];
  490. this.make_check();
  491. this.make_tags();
  492. this.make_details();
  493. this.add_timestamp();
  494. }
  495. // -------------------------------------------------
  496. ItemBrowserItem.prototype.make_check = function() {
  497. if(this.ib.archive_btn || this.ib.delete_btn) {
  498. var me = this;
  499. this.check = $a_input($td(this.tab, 0, 0), 'checkbox');
  500. this.check.onclick = function() {
  501. if(this.checked) {
  502. $y(me.wrapper, {backgroundColor:'#FFC'});
  503. } else {
  504. $y(me.wrapper, {backgroundColor:'#FFF'});
  505. }
  506. }
  507. }
  508. }
  509. // -------------------------------------------------
  510. ItemBrowserItem.prototype.make_details = function() {
  511. // link
  512. var me = this;
  513. var div = this.details_area;
  514. var span = $a(this.link_area, 'span', 'link_type', {fontWeight:'bold', marginRight: '7px'});
  515. span.innerHTML = me.dn;
  516. span.onclick = function() { loaddoc(me.ib.dt, me.dn, null, null, (me.ib.show_archives ? me.ib.show_archives.checked : null)); }
  517. var cl = me.ib.dt_details.columns;
  518. var tag_fields = me.ib.dt_details.tag_fields ? me.ib.dt_details.tag_fields.split(',') : [];
  519. for(var i=0;i<tag_fields.length;i++) tag_fields[i] = strip(tag_fields[i]);
  520. if(me.ib.dt_details.subject) {
  521. // if there is a subject mentioned in the
  522. // doctype, build the string based on the
  523. // subject string
  524. var det_dict = {};
  525. for(var i=0; i<cl.length; i++) {
  526. var fieldname = cl[i][0];
  527. det_dict[fieldname] = me.det[i] ? me.det[i] : '';
  528. // set tag (optionally)
  529. if(in_list(tag_fields, fieldname))
  530. me.taglist.add_tag(me.det[i], 1, fieldname);
  531. }
  532. // write the subject
  533. var s = repl(me.ib.dt_details.subject, det_dict);
  534. if(s.substr(0,5)=='eval:') s = eval(s.substr(5));
  535. $a(div, 'span', '', {color:'#444'}, s)
  536. } else {
  537. // old -style - based on search_fields!
  538. // properties
  539. var tmp = [];
  540. var first_property = 1;
  541. for(var i=3; i<me.det.length; i++) {
  542. if(cl[i] && cl[i][1] && me.det[i]) {
  543. // has status, group or type in the label
  544. if(cl[i][1].indexOf('Status') != -1 ||
  545. cl[i][1].indexOf('Group') != -1 ||
  546. cl[i][1].indexOf('Priority') != -1 ||
  547. cl[i][1].indexOf('Type') != -1) {
  548. me.taglist.add_tag(me.det[i], 1, cl[i][0], '#c0c0c0');
  549. } else {
  550. // separator
  551. if(!first_property) {
  552. var span = $a(div,'span'); span.innerHTML = ',';
  553. } else first_property = 0;
  554. // label
  555. var span = $a(div,'span','',{color:'#888'});
  556. span.innerHTML = ' ' + cl[i][1] + ': ';
  557. // value
  558. var span = $a(div,'span');
  559. $s(span,me.det[i],(cl[i][2]=='Link'?'Data':cl[i][2]), cl[i][3]);
  560. }
  561. }
  562. }
  563. }
  564. }
  565. // -------------------------------------------------
  566. ItemBrowserItem.prototype.make_tags = function() {
  567. // docstatus tag
  568. var docstatus = cint(this.det[this.det.length - 1]);
  569. // make custom tags
  570. var me = this;
  571. var tl = this.det[2] ? this.det[2].split(',') : [];
  572. var div = $a(this.body, 'div', '', {margin: '7px 0px'})
  573. this.taglist = new TagList(div, tl, this.ib.dt, this.dn, 0, function(tag) { me.ib.set_tag_filter(tag); });
  574. }
  575. // -------------------------------------------------
  576. ItemBrowserItem.prototype.add_timestamp = function() {
  577. // time
  578. var div = $a(this.body, 'div', '', {color:'#888', fontSize:'11px'});
  579. div.innerHTML = comment_when(this.det[1]);
  580. }