您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

175 行
6.3 KiB

  1. wn.provide('wn.utils');
  2. wn.utils = {
  3. get_file_link: function(filename) {
  4. return wn.utils.is_url(filename) || (filename.indexOf("images/")!=-1) || (filename.indexOf("files/")!=-1)
  5. ? filename : 'files/' + filename;
  6. },
  7. is_url: function(txt) {
  8. return txt.toLowerCase().substr(0,7)=='http://'
  9. || txt.toLowerCase().substr(0,8)=='https://'
  10. },
  11. filter_dict: function(dict, filters) {
  12. var ret = [];
  13. if(typeof filters=='string') {
  14. return [dict[filters]]
  15. }
  16. $.each(dict, function(i, d) {
  17. for(key in filters) {
  18. if($.isArray(filters[key])) {
  19. if(filters[key][0]=="in") {
  20. if(filters[key][1].indexOf(d[key])==-1)
  21. return;
  22. } else if(filters[key][0]=="not in") {
  23. if(filters[key][1].indexOf(d[key])!=-1)
  24. return;
  25. }
  26. } else {
  27. if(d[key]!=filters[key]) return;
  28. }
  29. }
  30. ret.push(d);
  31. });
  32. return ret;
  33. },
  34. comma_or: function(list) {
  35. return wn.utils.comma_sep(list, " " + wn._("or") + " ");
  36. },
  37. comma_and: function(list) {
  38. return wn.utils.comma_sep(list, " " + wn._("and") + " ");
  39. },
  40. comma_sep: function(list, sep) {
  41. if(list instanceof Array) {
  42. if(list.length==0) {
  43. return "";
  44. } else if (list.length==1) {
  45. return list[0];
  46. } else {
  47. return list.slice(0, list.length-1).join(", ") + sep + list.slice(-1)[0];
  48. }
  49. } else {
  50. return list;
  51. }
  52. },
  53. set_intro: function(me, wrapper, txt) {
  54. if(!me.intro_area) {
  55. me.intro_area = $('<div class="alert form-intro-area" style="margin-top: 20px;">')
  56. .prependTo(wrapper);
  57. }
  58. if(txt) {
  59. if(txt.search(/<p>/)==-1) txt = '<p>' + txt + '</p>';
  60. me.intro_area.html(txt);
  61. } else {
  62. me.intro_area.remove();
  63. me.intro_area = null;
  64. }
  65. },
  66. set_footnote: function(me, wrapper, txt) {
  67. if(!me.footnote_area) {
  68. me.footnote_area = $('<div class="alert alert-info form-intro-area" style="margin-top: 20px;">')
  69. .appendTo(wrapper);
  70. }
  71. if(txt) {
  72. if(txt.search(/<p>/)==-1) txt = '<p>' + txt + '</p>';
  73. me.footnote_area.html(txt);
  74. } else {
  75. me.footnote_area.remove();
  76. me.footnote_area = null;
  77. }
  78. },
  79. get_args_dict_from_url: function(txt) {
  80. var args = {};
  81. $.each(decodeURIComponent(txt).split("&"), function(i, arg) {
  82. arg = arg.split("=");
  83. args[arg[0]] = arg[1]
  84. });
  85. return args;
  86. },
  87. get_url_from_dict: function(args) {
  88. return encodeURIComponent($.map(args, function(val, key) { return key+"="+val; }).join("&") || "");
  89. },
  90. disable_export_btn: function(btn) {
  91. if(!wn.user.is_report_manager()) {
  92. btn.attr("disabled", "disabled").attr("title",
  93. wn._("Can only be exported by users with role 'Report Manager'"));
  94. }
  95. },
  96. validate_type: function ( val, type ) {
  97. // from https://github.com/guillaumepotier/Parsley.js/blob/master/parsley.js#L81
  98. var regExp;
  99. switch ( type ) {
  100. case "number":
  101. regExp = /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/;
  102. break;
  103. case "digits":
  104. regExp = /^\d+$/;
  105. break;
  106. case "alphanum":
  107. regExp = /^\w+$/;
  108. break;
  109. case "email":
  110. regExp = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i;
  111. break;
  112. case "url":
  113. regExp = /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i;
  114. break;
  115. case "dateIso":
  116. regExp = /^(\d{4})\D?(0[1-9]|1[0-2])\D?([12]\d|0[1-9]|3[01])$/;
  117. break;
  118. default:
  119. return false;
  120. break;
  121. }
  122. // test regExp if not null
  123. return '' !== val ? regExp.test( val ) : false;
  124. },
  125. guess_style: function(text, default_style) {
  126. var style = default_style;
  127. if(!text)
  128. return style;
  129. if(has_words(["Open", "Pending"], text)) {
  130. style = "important";
  131. } else if(has_words(["Closed", "Finished", "Converted", "Completed", "Confirmed",
  132. "Approved", "Yes", "Active"], text)) {
  133. style = "success";
  134. } else if(has_words(["Submitted"], text)) {
  135. style = "info";
  136. }
  137. return style;
  138. },
  139. sort: function(list, key, compare_type, reverse) {
  140. var sort_fn = {
  141. "string": function(a, b) {
  142. return cstr(a[key]).localeCompare(cstr(b[key]));
  143. },
  144. "number": function(a, b) {
  145. return flt(a[key]) - flt(b[key]);
  146. }
  147. };
  148. list.sort(sort_fn[compare_type]);
  149. if(reverse) { list.reverse(); }
  150. return list;
  151. },
  152. unique: function(list) {
  153. var dict = {},
  154. arr = [];
  155. for(var i=0, l=list.length; i < l; i++) {
  156. if(!dict.hasOwnProperty(list[i])) {
  157. dict[list[i]] = null;
  158. arr.push(list[i]);
  159. }
  160. }
  161. return arr;
  162. },
  163. sum: function(list) {
  164. return list.reduce(function(previous_value, current_value) { return flt(previous_value) + flt(current_value); });
  165. },
  166. };