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.

listing.js 9.1 KiB

13 anos atrás
13 anos atrás
13 anos atrás
13 anos atrás
13 anos atrás
13 anos atrás
13 anos atrás
13 anos atrás
13 anos atrás
12 anos atrás
13 anos atrás
12 anos atrás
13 anos atrás
11 anos atrás
11 anos atrás
13 anos atrás
13 anos atrás
13 anos atrás
13 anos atrás
13 anos atrás
13 anos atrás
13 anos atrás
11 anos atrás
11 anos atrás
12 anos atrás
13 anos atrás
13 anos atrás
13 anos atrás
13 anos atrás
12 anos atrás
13 anos atrás
13 anos atrás
12 anos atrás
11 anos atrás
13 anos atrás
12 anos atrás
12 anos atrás
12 anos atrás
12 anos atrás
12 anos atrás
12 anos atrás
12 anos atrás
12 anos atrás
12 anos atrás
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
  2. // MIT License. See license.txt
  3. // new re-factored Listing object
  4. // removed rarely used functionality
  5. //
  6. // opts:
  7. // parent
  8. // method (method to call on server)
  9. // args (additional args to method)
  10. // get_args (method to return args as dict)
  11. // show_filters [false]
  12. // doctype
  13. // filter_fields (if given, this list is rendered, else built from doctype)
  14. // query or get_query (will be deprecated)
  15. // query_max
  16. // buttons_in_frame
  17. // no_result_message ("No result")
  18. // page_length (20)
  19. // hide_refresh (False)
  20. // no_toolbar
  21. // new_doctype
  22. // [function] render_row(parent, data)
  23. // [function] onrun
  24. // no_loading (no ajax indicator)
  25. wn.provide('wn.ui');
  26. wn.ui.Listing = Class.extend({
  27. init: function(opts) {
  28. this.opts = opts || {};
  29. this.page_length = 20;
  30. this.start = 0;
  31. this.data = [];
  32. if(opts) {
  33. this.make();
  34. }
  35. },
  36. prepare_opts: function() {
  37. if(this.opts.new_doctype) {
  38. if(wn.boot.profile.can_create.indexOf(this.opts.new_doctype)==-1) {
  39. this.opts.new_doctype = null;
  40. } else {
  41. this.opts.new_doctype = this.opts.new_doctype;
  42. }
  43. }
  44. if(!this.opts.no_result_message) {
  45. this.opts.no_result_message = wn._('Nothing to show');
  46. }
  47. this.opts._more = wn._("More");
  48. },
  49. make: function(opts) {
  50. if(opts) {
  51. this.opts = opts;
  52. }
  53. this.prepare_opts();
  54. $.extend(this, this.opts);
  55. $(this.parent).html(repl('\
  56. <div class="wnlist">\
  57. <h3 class="title hide">%(title)s</h3>\
  58. \
  59. <div class="list-filters" style="display: none;">\
  60. <div class="show_filters" style="display: none;">\
  61. <div class="filter_area"></div>\
  62. <div>\
  63. <button class="btn btn-info search-btn">\
  64. <i class="icon-refresh icon-white"></i> \
  65. <span class="hidden-phone">Search</span></button>\
  66. <button class="btn btn-default add-filter-btn">\
  67. <i class="icon-plus"></i> \
  68. <span class="hidden-phone">Add Filter</span></button>\
  69. </div>\
  70. </div>\
  71. </div>\
  72. \
  73. <div style="margin-bottom:9px" class="list-toolbar-wrapper">\
  74. <div class="list-toolbar btn-group" style="display:inline-block; margin-right: 10px;">\
  75. </div>\
  76. <div style="display: none; width: 24px; margin-left: 4px">\
  77. <img src="assets/webnotes/images/ui/button-load.gif" \
  78. class="img-load"/></div>\
  79. </div><div style="clear:both"></div>\
  80. \
  81. <div class="no-result" style="display: none;">\
  82. %(no_result_message)s\
  83. </div>\
  84. \
  85. <div class="result">\
  86. <div class="result-list"></div>\
  87. </div>\
  88. \
  89. <p class="paging-button" style="text-align: center;">\
  90. <button class="btn btn-default btn-more" style="display: none; margin: 15px 0px;">%(_more)s...</div>\
  91. </p>\
  92. </div>\
  93. ', this.opts));
  94. this.$w = $(this.parent).find('.wnlist');
  95. this.set_events();
  96. if(this.appframe) {
  97. this.$w.find('.list-toolbar-wrapper').toggle(false);
  98. }
  99. if(this.show_filters) {
  100. this.make_filters();
  101. }
  102. },
  103. add_button: function(label, click, icon) {
  104. if(this.appframe) {
  105. return this.appframe.add_button(label, click, icon)
  106. } else {
  107. $button = $('<button class="btn btn-default"></button>')
  108. .appendTo(this.$w.find('.list-toolbar'))
  109. .html((icon ? ("<i class='"+icon+"'></i> ") : "") + label)
  110. .click(click);
  111. return $button
  112. }
  113. },
  114. show_view: function($btn, $div, $btn_unsel, $div_unsel) {
  115. $btn_unsel.removeClass('btn-info');
  116. $btn_unsel.find('i').removeClass('icon-white');
  117. $div_unsel.toggle(false);
  118. $btn.addClass('btn-info');
  119. $btn.find('i').addClass('icon-white');
  120. $div.toggle(true);
  121. },
  122. set_events: function() {
  123. var me = this;
  124. // next page
  125. this.$w.find('.btn-more').click(function() {
  126. me.run({append: true });
  127. });
  128. // title
  129. if(this.title) {
  130. this.$w.find('h3').html(this.title).toggle(true);
  131. }
  132. // hide-refresh
  133. if(!(this.hide_refresh || this.no_refresh)) {
  134. this.add_button('Refresh', function() {
  135. me.run();
  136. }, 'icon-refresh');
  137. }
  138. // new
  139. if(this.new_doctype) {
  140. if(this.appframe) {
  141. this.appframe.set_title_right("<i class='icon-plus'></i> New", function() {
  142. (me.custom_new_doc || me.make_new_doc).apply(me, [me.new_doctype]); });
  143. }
  144. this.add_button(wn._('New'), function() {
  145. (me.custom_new_doc || me.make_new_doc).apply(me, [me.new_doctype]);
  146. }, 'icon-plus');
  147. }
  148. // hide-filter
  149. if(me.show_filters) {
  150. this.add_button(wn._('Filter'), function() {
  151. me.filter_list.show_filters();
  152. }, 'icon-search').addClass('btn-filter');
  153. }
  154. if(me.no_toolbar || me.hide_toolbar) {
  155. me.$w.find('.list-toolbar-wrapper').toggle(false);
  156. }
  157. },
  158. make_new_doc: function(doctype) {
  159. var me = this;
  160. wn.model.with_doctype(doctype, function() {
  161. var doc = wn.model.get_new_doc(doctype);
  162. if(me.filter_list) {
  163. $.each(me.filter_list.get_filters(), function(i, f) {
  164. if(f[0]===doctype && f[2]==="=" && f[1]!=="name")
  165. doc[f[1]]=f[3];
  166. })
  167. }
  168. wn.set_route("Form", doctype, doc.name);
  169. });
  170. },
  171. make_filters: function() {
  172. this.filter_list = new wn.ui.FilterList({
  173. listobj: this,
  174. $parent: this.$w.find('.list-filters').toggle(true),
  175. doctype: this.doctype,
  176. filter_fields: this.filter_fields
  177. });
  178. },
  179. clear: function() {
  180. this.data = [];
  181. this.$w.find('.result-list').empty();
  182. this.$w.find('.result').toggle(true);
  183. this.$w.find('.no-result').toggle(false);
  184. this.start = 0;
  185. },
  186. run: function(more) {
  187. var me = this;
  188. if(!more) {
  189. this.start = 0;
  190. if(this.onreset) this.onreset();
  191. }
  192. if(!me.opts.no_loading)
  193. me.set_working(true);
  194. return wn.call({
  195. method: this.opts.method || 'webnotes.widgets.query_builder.runquery',
  196. type: "GET",
  197. args: this.get_call_args(),
  198. callback: function(r) {
  199. if(!me.opts.no_loading)
  200. me.set_working(false);
  201. me.dirty = false;
  202. me.render_results(r);
  203. },
  204. no_spinner: this.opts.no_loading
  205. });
  206. },
  207. set_working: function(flag) {
  208. this.$w.find('.img-load').toggle(flag);
  209. },
  210. get_call_args: function() {
  211. // load query
  212. if(!this.method) {
  213. var query = this.get_query ? this.get_query() : this.query;
  214. query = this.add_limits(query);
  215. var args={
  216. query_max: this.query_max,
  217. as_dict: 1
  218. }
  219. args.simple_query = query;
  220. } else {
  221. var args = {
  222. limit_start: this.start,
  223. limit_page_length: this.page_length
  224. }
  225. }
  226. // append user-defined arguments
  227. if(this.args)
  228. $.extend(args, this.args)
  229. if(this.get_args) {
  230. $.extend(args, this.get_args());
  231. }
  232. return args;
  233. },
  234. render_results: function(r) {
  235. if(this.start===0) this.clear();
  236. this.$w.find('.btn-more').toggle(false);
  237. if(r.message) {
  238. r.values = this.get_values_from_response(r.message);
  239. }
  240. if(r.values && r.values.length) {
  241. this.data = this.data.concat(r.values);
  242. this.render_list(r.values);
  243. this.update_paging(r.values);
  244. } else {
  245. if(this.start===0) {
  246. this.$w.find('.result').toggle(false);
  247. var msg = this.get_no_result_message
  248. ? this.get_no_result_message()
  249. : (this.no_result_message
  250. ? this.no_result_message
  251. : wn._("Nothing to show"));
  252. this.$w.find('.no-result')
  253. .html(msg)
  254. .toggle(true);
  255. }
  256. }
  257. // callbacks
  258. if(this.onrun) this.onrun();
  259. if(this.callback) this.callback(r);
  260. this.$w.trigger("render-complete");
  261. },
  262. get_values_from_response: function(data) {
  263. // make dictionaries from keys and values
  264. if(data.keys) {
  265. var values = [];
  266. $.each(data.values, function(row_idx, row) {
  267. var new_row = {};
  268. $.each(data.keys, function(key_idx, key) {
  269. new_row[key] = row[key_idx];
  270. })
  271. values.push(new_row);
  272. });
  273. return values;
  274. } else {
  275. return data;
  276. }
  277. },
  278. render_list: function(values) {
  279. var m = Math.min(values.length, this.page_length);
  280. this.data = values;
  281. if(this.filter_list)
  282. this.filter_values = this.filter_list.get_filters();
  283. // render the rows
  284. for(var i=0; i < m; i++) {
  285. this.render_row(this.add_row(), values[i], this, i);
  286. }
  287. },
  288. update_paging: function(values) {
  289. if(values.length >= this.page_length) {
  290. this.$w.find('.btn-more').toggle(true);
  291. this.start += this.page_length;
  292. }
  293. },
  294. add_row: function() {
  295. return $('<div class="list-row">').appendTo(this.$w.find('.result-list')).get(0);
  296. },
  297. refresh: function() {
  298. this.run();
  299. },
  300. add_limits: function(query) {
  301. query += ' LIMIT ' + this.start + ',' + (this.page_length+1);
  302. return query
  303. },
  304. set_filter: function(fieldname, label, doctype) {
  305. if(!doctype) doctype = this.doctype;
  306. var filter = this.filter_list.get_filter(fieldname);
  307. if(filter) {
  308. var v = filter.field.get_parsed_value();
  309. if(v.indexOf(label)!=-1) {
  310. // already set
  311. return false;
  312. } else {
  313. // second filter set for this field
  314. if(fieldname=='_user_tags') {
  315. // and for tags
  316. this.filter_list.add_filter(doctype, fieldname,
  317. 'like', '%' + label);
  318. } else {
  319. // or for rest using "in"
  320. filter.set_values(doctype, fieldname, 'in', v + ', ' + label);
  321. }
  322. }
  323. } else {
  324. // no filter for this item,
  325. // setup one
  326. if(['_user_tags', '_comments'].indexOf(fieldname)!==-1) {
  327. this.filter_list.add_filter(doctype, fieldname,
  328. 'like', '%' + label);
  329. } else {
  330. this.filter_list.add_filter(doctype, fieldname, '=', label);
  331. }
  332. }
  333. }
  334. });