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.

266 lines
10 KiB

2 years ago
  1. /*
  2. * Created with Sublime Text 3.
  3. * license: http://www.lovewebgames.com/jsmodule/index.html
  4. * github: https://github.com/tianxiangbing/format-number
  5. * User: 田想兵
  6. * Date: 2015-08-01
  7. * Time: 11:27:55
  8. * Contact: 55342775@qq.com
  9. */
  10. ;
  11. (function (root, factory) {
  12. //amd
  13. if (typeof define === 'function' && define.amd) {
  14. define(['$'], factory);
  15. } else if (typeof exports === 'object') { //umd
  16. module.exports = factory();
  17. } else {
  18. root.FormatNumber = factory(window.Zepto || window.jQuery || $);
  19. }
  20. })(this, function ($) {
  21. $.fn.FormatNumber = function (settings) {
  22. var arr = [];
  23. $(this).each(function () {
  24. var options = $.extend({
  25. trigger: $(this)
  26. }, settings);
  27. var number = new FormatNumber();
  28. number.init(options);
  29. arr.push(number);
  30. });
  31. return arr;
  32. };
  33. var FormatNumber = function () { };
  34. FormatNumber.prototype = {
  35. init: function (settings) {
  36. var _this = this,
  37. minus = ''
  38. settings = $.extend({
  39. trigger: '[data-type="money"]',
  40. decimal: 2,
  41. minus: false, //是否支持负数,默认不支持
  42. parent: 'body'
  43. }, settings);
  44. this.settings = settings;
  45. var excludeKey = {
  46. "left": 37,
  47. "right": 39,
  48. "top": 38,
  49. "down": 40,
  50. "home": 36,
  51. "end": 35,
  52. "shift": 16
  53. };
  54. var regex = '([1-9]\\d*(\\.\\d{1,2})?|0(\\.\\d{1,2})?)';
  55. if (settings.decimal <= 0 && settings.minus == true) {
  56. regex = '(^-?[1-9]\\d*$)|(^[0]$)'; //正负整数
  57. } else if (settings.decimal == 0) {
  58. regex = '(^[1-9]\\d*$)|(^[0]$)'; //正整数
  59. } else if (settings.minus == true) {
  60. //regex = '^-?([1-9]\\d*(\\.\\d{1,' + settings.decimal + '})?|([^0]{1}(\\.\\d{1,' + settings.decimal + '}))?)';
  61. regex = '(^-)?((([1-9]d*(\\.\\d{1,' + settings.decimal + '})?)|((^[0]{1}\\.(\\d{1,' + settings.decimal + '})?$))|^[0]$))'
  62. } else {
  63. regex = '([1-9]\\d*(\\.\\d{1,' + settings.decimal + '})?|([^0]{1}(\\.\\d{1,' + settings.decimal + '}))?)';
  64. }
  65. parent = parent || 'body';
  66. $(settings.trigger, parent).each(function (i, v) {
  67. var txt, formatTxt;
  68. if ($(v)[0].tagName == 'INPUT') {
  69. txt = $(v).val();
  70. if ($(v).attr('data-name')) {
  71. var name = $(v).attr('data-name'),
  72. id = name.split('.')[1] || name.split('.')[0];
  73. $(v).parent().append('<input data-rule="number" id="' + id + '" type="hidden" />');
  74. $('#' + id).val(_this.getMoneyfloat($(v).val()));
  75. }
  76. formatTxt = _this.doFormat(txt);
  77. $(v).val(formatTxt);
  78. $(this).attr('data-value', _this.getMoneyfloat($(v).val()));
  79. } else {
  80. txt = $(v).text();
  81. formatTxt = _this.doFormat(txt);
  82. $(v).attr('data-value', txt).text(formatTxt);
  83. }
  84. });
  85. $(settings.trigger, parent).on('keyup keydown', function (e) {
  86. var that = this, _e = e;
  87. setTimeout(function () {
  88. if (_e.keyCode === 9) { return false; }//當是tab鍵時不做動作
  89. checkNumber.call(that, _e);
  90. }, 10);//全選時直接key入取代
  91. });
  92. // $(settings.trigger, parent).on('blur', function(e) {
  93. // checkNumber.call(this, e)
  94. // });
  95. function checkNumber(e) {
  96. var name = $(this).attr('data-name'),
  97. id = name.split('.')[1] || name.split('.')[0];
  98. GetNumberResult(e, $(this)[0], regex);
  99. var v = _this.getMoneyfloat($(this).val());
  100. $('#' + id).val(v);
  101. $(this).attr('data-value', v);
  102. }
  103. function GetNumberResult(e, obj, reg) {
  104. var valueLength = obj.value.length;
  105. var position = getTxtCursorPosition(obj);
  106. var key = window.event ? e.keyCode : e.which;
  107. if ('17,65'.indexOf(key) > -1) {
  108. return;
  109. }
  110. var result = convertNumberN(key, obj.value, reg);
  111. obj.value = result;
  112. if ('8,46'.indexOf(key) > -1) {
  113. setTimeout(function () {
  114. position += (result.length - valueLength);
  115. setTxtCursorPosition(obj, position);
  116. }, 10);
  117. }
  118. else {
  119. position += (result.length - valueLength);
  120. setTxtCursorPosition(obj, position);
  121. }
  122. }
  123. /**
  124. * 说明: 检查不做处理的键盘Key
  125. * 参数: 键盘KeyCode {String}
  126. * 返回值: 如果是不做处理的key返回true反之false {bool}
  127. */
  128. function checkInactionKey(keyCode) {
  129. for (var key in excludeKey) {
  130. if (keyCode == excludeKey[key]) {
  131. return true;
  132. }
  133. }
  134. return false;
  135. }
  136. /**
  137. * 说明: 获取文本框的光标位置
  138. * 参数: 文本框对象 {dom object}
  139. * 返回值: {int}
  140. */
  141. function getTxtCursorPosition(txtObj) {
  142. var tempObj = txtObj;
  143. var cursurPosition = -1;
  144. if (tempObj.selectionStart != undefined) { //非IE浏览器
  145. cursurPosition = tempObj.selectionStart;
  146. } else { //IE
  147. var range = document.selection.createRange();
  148. range.moveStart("character", -tempObj.value.length);
  149. cursurPosition = range.text.length;
  150. }
  151. return cursurPosition;
  152. }
  153. /**
  154. * 说明: 转换数字为千分位常用于财务系统
  155. * 参数: 键盘key {String}被处理的字符串 {String}
  156. * 返回值: 返回转换的结果 {String}
  157. */
  158. function convertNumberN(key, value, reg) {
  159. if (checkInactionKey(key)) {
  160. return value;
  161. }
  162. var tempValue = value;
  163. var isminus = false;
  164. var replaceReg = /[^\d\.]/g;
  165. if (settings.minus && /^\-/.test(tempValue)) {
  166. tempValue = tempValue.slice(1);
  167. isminus = true;
  168. }
  169. if (tempValue.indexOf(".") <= 0) {
  170. //replaceReg = /[^\d]/g;
  171. tempValue = tempValue.replace(replaceReg, "");
  172. } else {
  173. tempValue = tempValue.replace(replaceReg, "");
  174. var isNaNNum = parseFloat(tempValue + "00");
  175. if (isNaN(isNaNNum)) {
  176. tempValue = isNaNNum;
  177. }
  178. if (/\./.test(tempValue) && settings.decimal == 0) {
  179. tempValue = tempValue.toString().replace(/\./g, '');
  180. }
  181. }
  182. var re = new RegExp(reg);
  183. if (!re.exec(tempValue) && tempValue != "") {
  184. tempValue = "0";
  185. }
  186. var tempValueArray = tempValue.split(".");
  187. tempValue = tempValueArray.length > 1 ?
  188. (tempValueArray[0].length > 14 ? tempValueArray[0].substr(0, 14) : tempValueArray[0]) + "." + tempValueArray[1] :
  189. (tempValue.length > 14 ? tempValue.substr(0, 14) : tempValue);
  190. var result = _this.doFormat(tempValue);
  191. if (isminus) result = '-' + result;
  192. if (result == null) {
  193. return;
  194. }
  195. var resultArray = result.split(".");
  196. if (tempValue.lastIndexOf(".") >= 0) {
  197. if (tempValue.lastIndexOf(".") == tempValue.length - 1) {
  198. tempValue = resultArray[0] + '.';
  199. } else {
  200. var subLength = tempValue.length - (tempValue.lastIndexOf(".") + 1);
  201. tempValue = resultArray[0] + "." + (resultArray[1] ? resultArray[1].substring(0, subLength) : '0');
  202. }
  203. } else {
  204. tempValue = resultArray[0];
  205. }
  206. return tempValue;
  207. }
  208. /**
  209. * 说明: 设置文本框的光标位置
  210. * 参数: 文本框对象 {dom object}, 光标的位置 {int}
  211. * 返回值: {void}
  212. */
  213. function setTxtCursorPosition(txtObj, pos) {
  214. var tempObj = txtObj;
  215. var cursurPosition = -1;
  216. if (tempObj.selectionStart != undefined) { //非IE浏览器
  217. tempObj.setSelectionRange(pos, pos);
  218. } else { //IE
  219. var range = tempObj.createTextRange();
  220. range.move("character", pos);
  221. range.select();
  222. }
  223. }
  224. },
  225. getMoneyfloat: function (s) {
  226. if (s == '') {
  227. return null;
  228. }
  229. return parseFloat((s + "").replace(/[^\d\.-]/g, ""));
  230. },
  231. doFormat: function (s) {
  232. var _this = this;
  233. if (!s) return "";
  234. if ($.isNumeric(s)) {
  235. s = s.toString();
  236. }
  237. if (typeof s === 'string') {
  238. s = s.replace(/^(\d+)((\.\d*)?)$/, function (v1, v2, v3) {
  239. var sInteger = v2.replace(/\d{1,3}(?=(\d{3})+$)/g, '$&,'),
  240. sDecimal = (v3 || '.00000000000').slice(0, _this.settings.decimal + 1);
  241. return _this.settings.decimal === 0 ? sInteger : sInteger + sDecimal;
  242. });
  243. }
  244. return s.replace(/^\./, "0.")
  245. }
  246. };
  247. return FormatNumber;
  248. });