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.
 
 
 
 
 
 

317 lines
8.9 KiB

  1. // Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
  2. //
  3. // MIT License (MIT)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a
  6. // copy of this software and associated documentation files (the "Software"),
  7. // to deal in the Software without restriction, including without limitation
  8. // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. // and/or sell copies of the Software, and to permit persons to whom the
  10. // Software is furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  16. // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  17. // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  19. // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  20. // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. //
  22. wn.provide('wn.pages.doclistview');
  23. wn.pages.doclistview.pages = {};
  24. wn.pages.doclistview.show = function(doctype) {
  25. var pagename = doctype + ' List';
  26. if(!wn.pages.doclistview.pages[pagename]) {
  27. var page = page_body.add_page(pagename);
  28. page.doclistview = new wn.pages.DocListView(doctype, page);
  29. wn.pages.doclistview.pages[pagename] = page;
  30. }
  31. page_body.change_to(pagename);
  32. }
  33. wn.pages.DocListView = Class.extend({
  34. init: function(doctype, page) {
  35. this.doctype = doctype;
  36. this.wrapper = page;
  37. this.label = get_doctype_label(doctype);
  38. this.label = (this.label.toLowerCase().substr(-4) == 'list') ?
  39. this.label : (this.label + ' List')
  40. this.make();
  41. this.load_doctype();
  42. },
  43. make: function() {
  44. $(this.wrapper).html('<div class="layout-wrapper layout-wrapper-background">\
  45. <div class="layout-main-section">\
  46. <a class="close" onclick="window.history.back();">&times;</a>\
  47. <h1>List</h1>\
  48. <hr>\
  49. <div id="list-filters"></div>\
  50. <button class="btn btn-small btn-info run-btn" style="margin-top: 11px">\
  51. <i class="icon-refresh icon-white"></i> Refresh</button>\
  52. <div id="list-body"></div>\
  53. </div>\
  54. <div class="layout-side-section">\
  55. </div>\
  56. </div>');
  57. // filter button
  58. $(this.wrapper).find('.run-btn').click(function() {
  59. me.list.run();
  60. });
  61. },
  62. load_doctype: function() {
  63. var me = this;
  64. wn.call({
  65. method: 'webnotes.widgets.form.load.getdoctype',
  66. args: {doctype:this.doctype},
  67. callback: function() {
  68. me.make_filters();
  69. me.make_list();
  70. }
  71. });
  72. },
  73. make_filters: function() {
  74. this.filter_list = new wn.ui.FilterList(this, $('#list-filters').get(0), this.doctype);
  75. },
  76. make_list: function() {
  77. var me = this;
  78. this.list = new wn.widgets.Listing({
  79. parent: $('#list-body').get(0),
  80. method: 'webnotes.widgets.doclistview.get',
  81. args: {
  82. doctype: this.doctype,
  83. subject: locals.DocType[this.doctype].subject,
  84. },
  85. get_args: function() {
  86. return {filters: JSON.stringify(me.filter_list.get_filters())}
  87. },
  88. render_row: function(row, data) {
  89. row.innerHTML = data;
  90. },
  91. hide_refresh: true
  92. });
  93. this.list.run();
  94. }
  95. });
  96. wn.require('lib/css/ui/filter.css');
  97. wn.ui.FilterList = Class.extend({
  98. init: function(list_obj, parent, doctype) {
  99. this.filters = [];
  100. this.list_obj = list_obj;
  101. this.doctype = doctype;
  102. this.make(parent);
  103. this.set_events();
  104. },
  105. make: function(parent) {
  106. $(parent).html('<div>\
  107. <span class="link_type set_filters">Filter this list</span>\
  108. </div>\
  109. <div class="show_filters well">\
  110. <div class="filter_area"></div>\
  111. <div>\
  112. <button class="btn btn-small add-filter-btn">\
  113. <i class="icon-plus"></i> Add Filter</button>\
  114. </div>\
  115. </div>');
  116. this.$w = $(parent);
  117. },
  118. set_events: function() {
  119. var me = this;
  120. // show filters
  121. this.$w.find('.set_filters').bind('click', function() {
  122. me.$w.find('.show_filters').slideToggle();
  123. if(!me.filters.length)
  124. me.add_filter();
  125. });
  126. // show filters
  127. this.$w.find('.add-filter-btn').bind('click', function() {
  128. me.add_filter();
  129. });
  130. },
  131. add_filter: function(fieldname, condition, value) {
  132. this.filters.push(new wn.ui.Filter(this, this.doctype, fieldname, condition, value));
  133. },
  134. get_filters: function() {
  135. // get filter values as dict
  136. var values = [];
  137. $.each(this.filters, function(i, f) {
  138. if(f.filter_field)
  139. values.push(f.get_value());
  140. })
  141. return values;
  142. }
  143. });
  144. wn.ui.Filter = Class.extend({
  145. init: function(flist, doctype, fieldname, condition, value) {
  146. flist.$w.find('.filter_area').append('<div class="list_filter">\
  147. <select class="fieldname_select"></select>\
  148. <select class="condition">\
  149. <option value="=">Equals</option>\
  150. <option value="like">Like</option>\
  151. <option value=">=">Greater or equals</option>\
  152. <option value=">=">Less or equals</option>\
  153. <option value=">">Greater than</option>\
  154. <option value="<">Less than</option>\
  155. <option value="!=">Not equals</option>\
  156. </select>\
  157. <span class="filter_field"></span>\
  158. <a class="close">&times;</a>\
  159. </div>');
  160. this.fields_by_name = {};
  161. this.flist = flist;
  162. this.$w = this.flist.$w.find('.list_filter:last-child');
  163. this.doctype = doctype;
  164. this.fieldname = fieldname;
  165. this.condition = condition;
  166. this.value = value;
  167. this.set_events();
  168. },
  169. set_events: function() {
  170. var me = this;
  171. // render fields
  172. this.render_field_select();
  173. this.$w.find('.fieldname_select').bind('change', function() {
  174. me.set_field(this.value);
  175. });
  176. this.$w.find('a.close').bind('click', function() {
  177. me.$w.css('display','none');
  178. var value = me.filter_field.get_value();
  179. me.filter_field = null;
  180. if(!me.flist.get_filters().length) {
  181. me.flist.$w.find('.set_filters').toggle(true);
  182. me.flist.$w.find('.show_filters').toggle(false);
  183. me.list_obj.list.run();
  184. }
  185. if(value) {
  186. me.list_obj.list.run();
  187. }
  188. return false;
  189. });
  190. // set the field
  191. if(me.fieldname) {
  192. // presents given (could be via tags!)
  193. me.set_field(me.fieldname);
  194. if(me.condition) me.$w.find('.condition').val(me.condition)
  195. if(me.value) me.filter_field.set_input(me.value)
  196. } else {
  197. me.set_field('name');
  198. }
  199. },
  200. render_field_select: function() {
  201. var me = this;
  202. var $fs = me.$w.find('.fieldname_select');
  203. me.table_fields = [];
  204. var std_filters = [
  205. {fieldname:'name', fieldtype:'Data', label:'ID', parent:me.doctype},
  206. {fieldname:'modified', fieldtype:'Date', label:'Last Modified', parent:me.doctype},
  207. {fieldname:'owner', fieldtype:'Data', label:'Created By', parent:me.doctype},
  208. {fieldname:'_user_tags', fieldtype:'Data', label:'Tags', parent:me.doctype}
  209. ];
  210. // main table
  211. $.each(std_filters.concat(fields_list[me.doctype]), function(i, df) {
  212. me.add_field_option(df, $fs);
  213. });
  214. // child tables
  215. $.each(me.table_fields, function(i,table_df) {
  216. if(table_df.options) {
  217. $.each(fields_list[table_df.options], function(i, df) {
  218. me.add_field_option(df, $fs);
  219. });
  220. }
  221. })
  222. },
  223. add_field_option: function(df, $fs) {
  224. var me = this;
  225. if(df.parent==me.doctype) {
  226. var label = df.label;
  227. var table = get_label_doctype(me.doctype);
  228. if(df.fieldtype=='Table') me.table_fields.push(df);
  229. } else {
  230. var label = df.label + ' (' + df.parent + ')';
  231. var table = df.parent;
  232. }
  233. if(wn.model.no_value_type.indexOf(df.fieldtype)==-1 &&
  234. !me.fields_by_name[df.fieldname]) {
  235. $fs.append($('<option>', {
  236. value: df.fieldname,
  237. table: table
  238. }).text(label));
  239. me.fields_by_name[df.fieldname] = df;
  240. }
  241. },
  242. set_field: function(fieldname) {
  243. var me = this;
  244. // set in fieldname (again)
  245. me.$w.find('.fieldname_select').val(fieldname);
  246. wn.require('lib/js/legacy/widgets/form/fields.js');
  247. var field_area = me.$w.find('.filter_field').get(0);
  248. field_area.innerHTML = '';
  249. var df = me.fields_by_name[fieldname];
  250. df.original_type = df.fieldtype;
  251. df.description = '';
  252. if(df.fieldtype=='Check') {
  253. df.fieldtype='Select';
  254. df.options='No\nYes';
  255. } else if(['Text','Text Editor','Code','Link'].indexOf(df.fieldtype)!=-1) {
  256. df.fieldtype = 'Data';
  257. }
  258. f = make_field(me.fields_by_name[fieldname], null, field_area, null, 0, 1);
  259. f.df.single_select = 1;
  260. f.not_in_form = 1;
  261. f.with_label = 0;
  262. f.refresh();
  263. me.filter_field = f;
  264. // set as "like" for data fields
  265. if(df.fieldtype=='Data') {
  266. me.$w.find('.condition').val('like');
  267. } else {
  268. me.$w.find('.condition').val('=');
  269. }
  270. },
  271. get_value: function() {
  272. var me = this;
  273. var val = me.filter_field.get_value();
  274. var cond = me.$w.find('.condition').val();
  275. if(me.filter_field.df.original_type == 'Check') {
  276. val = (val=='Yes' ? 1 :0);
  277. }
  278. if(cond=='like') {
  279. val = val + '%';
  280. }
  281. return [me.$w.find('.fieldname_select option:selected').attr('table'),
  282. me.filter_field.df.fieldname, me.$w.find('.condition').val(), val];
  283. }
  284. });