25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

194 lines
6.9 KiB

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