zhiqim_form.mobile.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. /*
  2. * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。
  3. *
  4. * 指定登记&发行网站: https://www.zhiqim.com/ 欢迎加盟知启蒙,[编程有你,知启蒙一路随行]。
  5. *
  6. * 本文采用《知启蒙登记发行许可证》,除非符合许可证,否则不可使用该文件!
  7. * 1、您可以免费使用、修改、合并、出版发行和分发,再授权软件、软件副本及衍生软件;
  8. * 2、您用于商业用途时,必须在原作者指定的登记网站,按原作者要求进行登记;
  9. * 3、您在使用、修改、合并、出版发行和分发时,必须包含版权声明、许可声明,及保留原作者的著作权、商标和专利等知识产权;
  10. * 4、您在互联网、移动互联网等大众网络下发行和分发再授权软件、软件副本及衍生软件时,必须在原作者指定的发行网站进行发行和分发;
  11. * 5、您可以在以下链接获取一个完整的许可证副本。
  12. *
  13. * 许可证链接:http://zhiqim.org/licenses/zhiqim_register_publish_license.htm
  14. *
  15. * 除非法律需要或书面同意,软件由原始码方式提供,无任何明示或暗示的保证和条件。详见完整许可证的权限和限制。
  16. */
  17. +(function(Z)
  18. {//BEGIN
  19. Z.Input = Z.Class.newInstance();
  20. //定义支持的类型数值的,整数,小数的,字母的,两位小数金额的,折扣值,小时分钟值
  21. Z.Input.types = ["Numeric", "Alphabetic", "AlphaNumeric", "Integer", "Decimal", "Amount2R", "Discount", "Date", "HourMinute"];
  22. Z.Input.speTypes = ["number", "email"];
  23. Z.Input.prototype =
  24. {
  25. defaults:
  26. {
  27. elem: null,
  28. options: null
  29. },
  30. init: function()
  31. {//初始化
  32. if (!this.elem)
  33. return;
  34. this.$elem = Z(this.elem);
  35. if (!this.options && !Z.AR.contains(Z.Input.speTypes, this.$elem.attr("type")))
  36. return;
  37. // max(最大值)/maxlength(最大长度) 特殊处理
  38. if (this.$elem.attr("max") != null)
  39. {
  40. this.$elem.max = parseFloat(this.$elem.attr("max"));
  41. }
  42. if (this.$elem.attr("maxlength") != null)
  43. {
  44. this.$elem.maxlength = parseInt(this.$elem.attr("maxlength"));
  45. }
  46. //键点击双击,按下事件,按下恢复事件和值被修改事件
  47. this.$elem.on("input",this.onInput, this);
  48. },
  49. /************************************************/
  50. //事件方法,设置三种控制方式:
  51. //1、键按下时判断是否可以输入,用is开头方法
  52. //2、键恢复时表示判断通过,用on再检查一次
  53. //3、由其他方式修改了值input事件时,用ch检查控制
  54. //4、由设置值方式修改值,不会触发input方法暂时没办法控制
  55. /************************************************/
  56. onInput: function(e)
  57. {
  58. this.call("on", e);
  59. },
  60. call: function(action, e)
  61. {
  62. if (!this.options)
  63. {
  64. this.$elem.val(this.inputMax(this.$elem.val()));
  65. }
  66. else if (this.options.type && action+this.options.type in this)
  67. {
  68. this[action+this.options.type].call(this, e);
  69. }
  70. },
  71. inputMax: function(value)
  72. {
  73. if (this.$elem.max && +value > this.$elem.max)
  74. return value = this.$elem.max;
  75. if (this.$elem.maxlength && (""+value).length > this.$elem.maxlength)
  76. return value = value.substring(0,this.$elem.maxlength);
  77. return value;
  78. },
  79. /************************************************/
  80. //数值型判断,替换和粘贴
  81. /************************************************/
  82. onNumeric: function(e)
  83. {//处理非数值型数据
  84. var value = this.$elem.val();
  85. if (!/^[0-9]*$/.test(value))
  86. {
  87. value = value.replace(/[^0-9]/g, "");
  88. this.inputMax(value);
  89. this.$elem.val(value);
  90. }
  91. },
  92. /************************************************/
  93. //整数型判断,替换和粘贴
  94. /************************************************/
  95. onInteger: function(e)
  96. {//处理非整数型数据
  97. var value = this.$elem.val();
  98. if (!/^[0-9]*$/.test(value)){
  99. value = value.replace(/[^0-9]/g, "");
  100. }
  101. value = Z.S.prefixZeroRemove(value);
  102. this.inputMax(value);
  103. this.$elem.val(value);
  104. },
  105. /************************************************/
  106. //小数型判断,替换和粘贴
  107. /************************************************/
  108. onDecimal: function(e)
  109. {//处理非小数型数据
  110. var value = this.$elem.val();
  111. if (!/^[0-9.]*$/.test(value)){
  112. value = value.replace(/[^0-9.]/g, "");
  113. }
  114. //删除前缀0,第二个点后数据,如果首符是.则加为0.
  115. value = Z.S.prefixZeroRemove(value);
  116. value = Z.S.removeSecondDot(value);
  117. if (value.length > 0 && value.charAt(0) == '.'){
  118. value = "0" + value;
  119. }
  120. this.inputMax(value);
  121. this.$elem.val(value);
  122. },
  123. /************************************************/
  124. //字母型判断,替换和粘贴
  125. /************************************************/
  126. onAlphabetic: function(e)
  127. {//处理非字母型数据
  128. var value = this.$elem.val();
  129. if (!/^[a-zA-Z]*$/.test(value))
  130. {
  131. value = value.replace(/[^a-zA-Z]/g, "");
  132. this.$elem.val(value);
  133. }
  134. },
  135. /************************************************/
  136. //字母数值型判断,替换和粘贴
  137. /************************************************/
  138. onAlphabeticNumeric: function(e)
  139. {//处理非字母型数据
  140. var value = this.$elem.val();
  141. if (!/^[0-9a-zA-Z]*$/.test(value))
  142. {
  143. value = value.replace(/[^0-9a-zA-Z]/g, "");
  144. this.$elem.val(value);
  145. }
  146. },
  147. /************************************************/
  148. //2位小数的金额判断,替换和粘贴
  149. /************************************************/
  150. onAmount2R: function(e)
  151. {
  152. var value = this.$elem.val();
  153. if (!/^[0-9.]*$/.test(value)){
  154. value = value.replace(/[^0-9.]/g, "");
  155. }
  156. //删除前缀0,第二个点后数据,如果首符是.则加为0.
  157. value = Z.S.prefixZeroRemove(value);
  158. value = Z.S.removeSecondDot(value);
  159. if (value.length > 0 && value.charAt(0) == '.'){
  160. value = "0" + value;
  161. }
  162. //金额还要增加2位小数限制
  163. var ind = value.indexOf(".");
  164. if (ind != -1 && ind <= value.length-1-2){
  165. value = value.substring(0, ind+1+2);
  166. }
  167. this.inputMax(value);
  168. this.$elem.val(value);
  169. },
  170. /************************************************/
  171. //折扣(0.01-10)判断,替换和粘贴
  172. /************************************************/
  173. onDiscount: function(e)
  174. {
  175. var value = this.$elem.val();
  176. if (!/^[0-9.]*$/.test(value)){
  177. value = value.replace(/[^0-9.]/g, "");
  178. }
  179. //删除前缀0,第二个点后数据,如果首符是.则加为0.
  180. value = Z.S.prefixZeroRemove(value);
  181. value = Z.S.removeSecondDot(value);
  182. if (value.length > 0 && value.charAt(0) == '.'){
  183. value = "0" + value;
  184. }
  185. //折扣还要增加2位小数限制
  186. var ind = value.indexOf(".");
  187. if (ind != -1 && ind <= value.length-1-2){
  188. value = value.substring(0, ind+1+2);
  189. }
  190. //再比较不允许大于10,大于10则置空
  191. this.$elem.val((parseFloat(value) > 10)?"":value);
  192. },
  193. /************************************************/
  194. //日期(yyyy-MM-dd)判断,替换和粘贴
  195. /************************************************/
  196. onDate: function(e)
  197. {
  198. var value = this.$elem.val();
  199. if (!/^[0-9\-]*$/.test(value))
  200. value = value.replace(/[^0-9\-]/g, "");
  201. //再比较是否有效,有效则加入,否则置空
  202. var regexp = null;
  203. switch(value.length)
  204. {
  205. case 1:regexp = /^[0-9]$/;break;
  206. case 2:regexp = /^[0-9]{2}$/;break;
  207. case 3:regexp = /^[0-9]{3}$/;break;
  208. case 4:regexp = /^[0-9]{4}$/;break;
  209. case 5:regexp = /^[0-9]{4}\-$/;break;
  210. case 6:regexp = /^[0-9]{4}\-[0-1]$/;break;
  211. case 7:regexp = /^[0-9]{4}\-(0[1-9]|1[0-2])$/;break;
  212. case 8:regexp = /^[0-9]{4}\-(0[1-9]|1[0-2])\-$/;break;
  213. case 9:regexp = /^[0-9]{4}\-(0[1-9]|1[0-2])\-[0-3]$/;break;
  214. case 10:regexp = Z.R.DATE;break;
  215. }
  216. //再比较是否有效,有效则加入,否则置空
  217. this.$elem.val((!regexp || !regexp.test(value))?"":value);
  218. },
  219. /************************************************/
  220. //小时分钟(00:00)判断,替换和粘贴
  221. /************************************************/
  222. onHourMinute: function(e)
  223. {
  224. var value = this.$elem.val();
  225. if (!/^[0-9:]*$/.test(value))
  226. value = value.replace(/[^0-9:]/g, "");
  227. //再比较是否有效,有效则加入,否则置空
  228. var regexp = null;
  229. switch(value.length)
  230. {
  231. case 1:regexp = /^[0-2]$/;break;
  232. case 2:regexp = /^([0-1][0-9]|[2][0-3])$/;break;
  233. case 3:regexp = /^([0-1][0-9]|[2][0-3]):$/;break;
  234. case 4:regexp = /^([0-1][0-9]|[2][0-3]):([0-5])$/;break;
  235. case 5:regexp = /^([0-1][0-9]|[2][0-3]):([0-5][0-9])$/;break;
  236. }
  237. //再比较是否有效,有效则加入,否则置空
  238. this.$elem.val((!regexp || !regexp.test(value))?"":value);
  239. }
  240. }
  241. Z.Input.load = function(target)
  242. {//加载函数
  243. //如果传入了目标,则在目标中查找,否则查找全部
  244. Z.$selector("input", target).each(function(elem)
  245. {
  246. if (Z.B.msie)
  247. {//IE处理成灰色和主流一致
  248. Z.placeholder(elem);
  249. }
  250. if (Z.EL.get(elem, "readonly") != null)
  251. {//如果有只读属性时不响应回退等按键,注意element里有readonly属性,默认=null
  252. Z.E.add(elem, "keydown", Z.E.forbidden);
  253. return;
  254. }
  255. if (!Z.EL.has(elem, "data-options"))
  256. {
  257. //email、number 特殊处理
  258. var inputType = Z.EL.get(elem, "type");
  259. if (Z.AR.contains(Z.Input.speTypes, inputType))
  260. {
  261. if (Z.EL.get(elem, "max") != null || Z.EL.get(elem, "maxlength") != null)
  262. return new Z.Input({elem: elem});
  263. }
  264. return;
  265. }
  266. //解析表达式并放置到哈唏表中
  267. var expression = Z.EL.get(elem, "data-options");
  268. var options = Z.AR.toObject(expression, ";");
  269. if (!options.type || !Z.AR.contains(Z.Input.types, options.type))
  270. {//不支持的类型不处理
  271. return;
  272. }
  273. //关闭输入法,chrome不支持,ie和firefox支持
  274. Z.EL.addClass(elem, "z-ime-disabled");
  275. new Z.Input({elem: elem, options: options});
  276. });
  277. };
  278. Z.onload(Z.Input.load);
  279. /****************************************/
  280. //“数量修改输入框”
  281. /****************************************/
  282. Z.NumInput = {};
  283. Z.NumInput.load = function(target)
  284. {
  285. Z.$selector("[data-role=z-numInput]", target).each(function(elem)
  286. {//遍历目标范围内
  287. var $minus = Z(elem).find(".z-btn-minus");
  288. var $plus = Z(elem).find(".z-btn-plus");
  289. var $input = Z(elem).find("input[type=text]");
  290. if (!$minus[0] || !$plus[0] || !$input[0]){
  291. return false;
  292. };
  293. $input.off("input",Z.NumInput.numInput).on("input",Z.NumInput.numInput);
  294. $plus.off("touchend",Z.NumInput.numPlus).on("touchend",Z.NumInput.numPlus);
  295. $minus.off("touchend",Z.NumInput.numMinus).on("touchend",Z.NumInput.numMinus);
  296. });
  297. }
  298. Z.NumInput.numInput = function(ev)
  299. {//输入框 input 事件
  300. var $input = Z(this);
  301. var val = $input.val();
  302. var min = parseInt($input.attr("data-min")) || 1;
  303. val = val.replace(/[^\d]/g,"");
  304. while (val.charAt(0) == "0" && val.length > 1){
  305. val = val.substring(1);
  306. }
  307. if (val == ""){
  308. val = min;
  309. }
  310. $input.val(val);
  311. }
  312. Z.NumInput.numPlus = function(ev)
  313. {//数值累加
  314. Z.E.forbidden(ev);
  315. var $plus = Z(this);
  316. var $input = $plus.parent().find("input[type=text]");
  317. var val = parseInt($input.val());
  318. val++;
  319. $input.val(val);
  320. }
  321. Z.NumInput.numMinus = function(ev)
  322. {//数值递减
  323. Z.E.forbidden(ev);
  324. var $minus = Z(this);
  325. var $input = $minus.parent().find("input[type=text]");
  326. var min = parseInt($input.attr("data-min")) || 1;
  327. var val = parseInt($input.val());
  328. val--;
  329. val = (val < min)?min:val;
  330. $input.val(val);
  331. }
  332. /******************************************************/
  333. //支持form使用iframe调用
  334. /******************************************************/
  335. Z.CallFrame = {};
  336. Z.CallFrame.load = function()
  337. {
  338. Z("form[data-role=z-call-frame]").each(function(form)
  339. {
  340. //1.先判断是否存在<iframe name="zCallFrame"></iframe>
  341. var $frame = Z('iframe[name="zCallFrame"]');
  342. if ($frame.length == 0)
  343. $frame = Z('<iframe name="zCallFrame" style="display:none;"></iframe>').prependTo("body");
  344. //2.设置form的target
  345. form.target = "zCallFrame";
  346. //3.设置zFormIndex
  347. if (!form.zFormIndex)
  348. {
  349. var zFormIndex = document.createElement("input");
  350. zFormIndex.name = "zFormIndex";
  351. zFormIndex.type = "hidden";
  352. form.insertBefore(zFormIndex, form.firstNode);
  353. }
  354. var ind = -1;
  355. for (var i=0;i<document.forms.length;i++)
  356. {
  357. if (form == document.forms[i])
  358. {
  359. ind = i;
  360. break;
  361. }
  362. }
  363. form.zFormIndex.value = ind;
  364. //4.设置zCallFrame
  365. if (!form.zCallFrame)
  366. {
  367. var zCallFrame = document.createElement("input");
  368. zCallFrame.name = "zCallFrame";
  369. zCallFrame.type = "hidden";
  370. form.insertBefore(zCallFrame, form.firstNode);
  371. }
  372. form.zCallFrame.value = "true";
  373. });
  374. };
  375. Z.onload(Z.CallFrame.load);
  376. /*************************************************************************************/
  377. //描述对象
  378. /*************************************************************************************/
  379. Z.placeholder = function(elem)
  380. {
  381. var $elem = Z.$elem(elem);
  382. var ph = $elem.attr("placeholder");
  383. if (Z.V.isEmptyBlank(ph))
  384. return;
  385. $elem.removeAttr("placeholder");
  386. var width = $elem.offsetWidth();
  387. var height = $elem.offsetHeight();
  388. //创建一个封套把input/textarea和placeholder包含在一起
  389. var $cover = Z.$cover($elem);
  390. //创建描述对象
  391. var $placeholder = Z('<div class="z-placeholder">'+ph+'</div>');
  392. $placeholder.appendTo($cover)
  393. .opacity(0.8)
  394. .css({width: width, height: height})
  395. .cssMaybe("padding-left", $elem.cssNum("paddingLeft")+2)//保留光标2像素位置
  396. .cssMaybe("padding-right", $elem.css("paddingRight"))
  397. .cssMaybe("padding-top", $elem.css("paddingTop"))
  398. .cssMaybe("padding-bottom", $elem.css("paddingBottom"))
  399. .cssMaybe("font-family", $elem.css("fontFamily"))
  400. .cssMaybe("font-size", $elem.css("fontSize"))
  401. .cssMaybe("line-height", $elem.css("lineHeight"))
  402. .cssMaybe("text-indent", $elem.css("textIndent"));
  403. if ($elem.val().length > 0){
  404. $placeholder.hide();
  405. }
  406. //事件隐藏和显示描述
  407. $elem.keydown(function(){$placeholder.hide();});
  408. $elem.keyup(function()
  409. {
  410. if ($elem.val().length > 0)
  411. $placeholder.hide();
  412. else
  413. $placeholder.show();
  414. });
  415. }
  416. /*************************************************************************************/
  417. //<pre>对象
  418. /*************************************************************************************/
  419. Z.preRemoveBR = function()
  420. {//定义了.z-text-prewrap和.z-text-preline样式且不是pre标签的首字符\n删除
  421. Z(".z-text-preline:not(pre),.z-text-prewrap:not(pre)").each(function(elem)
  422. {
  423. var $elem = Z(elem);
  424. var html = $elem.html();
  425. if (Z.V.isEmpty(html))
  426. return;
  427. if (html.charAt(0) == '\n'){
  428. $elem.html(html.substring(1));
  429. }
  430. });
  431. }
  432. Z.onload(Z.preRemoveBR);
  433. //END
  434. })(zhiqim);