├── input
├── input.json
├── data.js
├── input.wxss
├── input.wxml
├── properties.js
├── input.js
└── validate.js
└── README.md
/input/input.json:
--------------------------------------------------------------------------------
1 | {
2 | "component":true
3 | }
--------------------------------------------------------------------------------
/input/data.js:
--------------------------------------------------------------------------------
1 | export default {
2 | value: '',
3 | error:false
4 | }
--------------------------------------------------------------------------------
/input/input.wxss:
--------------------------------------------------------------------------------
1 | /* valid input css */
2 |
3 | .flex{
4 | display:flex;
5 | align-items: center;
6 | }
7 | .flex-center{
8 | justify-content: center;
9 | }
10 | .flex-start{
11 | justify-content: flex-start;
12 | }
13 | .flex-between{
14 | justify-content: space-between;
15 | }
16 | .flex-around{
17 | justify-content: space-around;
18 | }
19 |
20 | .valid_input_content{
21 | width:100%;
22 | padding:4px 24rpx;
23 | box-sizing: border-box;
24 | font-size: 24rpx;
25 | }
26 |
27 | .valid_input{
28 | width:80%;
29 | height: 65rpx;
30 | transition: border .3s linear,box-shadow .3s linear;
31 | }
32 |
33 | .valid_error_tip{
34 | box-shadow: 0px 0px 3px 1px red;
35 | }
--------------------------------------------------------------------------------
/input/input.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/input/properties.js:
--------------------------------------------------------------------------------
1 | export default {
2 | flex:{ // 弹性布局方式
3 | type:String,
4 | value:'flex-start'
5 | },
6 | placeHolder:{
7 | type:String, // 提示语
8 | value:'请输入您的数据'
9 | },
10 | validType:{
11 | type:String, // 验证类型
12 | value:''
13 | },
14 | type:{ // 输入框类型
15 | type:String,
16 | value:'text'
17 | },
18 | validTime:{
19 | type:String,
20 | value: 'blur'
21 | },
22 | validToast:{ // 验证错误提示
23 | type:String,
24 | value:''
25 | },
26 | initValue:{ // 初始值
27 | type:String,
28 | value:''
29 | },
30 | maxLength:{ // 最大长度
31 | type:Number,
32 | value:140
33 | },
34 | adjustPosition:{ // 是否上推页面
35 | type:Boolean,
36 | value:true
37 | },
38 | confirmType:{ // 确认按钮类型
39 | type:String,
40 | value: 'done'
41 | },
42 | focus:{ // 是否自动聚焦
43 | type:Boolean,
44 | value:false
45 | },
46 | placeholderClass:{ // 提示信息样式
47 | type:String,
48 | value:'input-placeholder'
49 | },
50 | errorBorder:{ // 验证错误时是否进行border边框展示(红色)
51 | type:Boolean,
52 | value:true
53 | },
54 | password:{ // 是否为密码类型
55 | type:Boolean,
56 | value:false
57 | },
58 | disabled:{ // 是否禁用
59 | type:Boolean,
60 | value:false
61 | },
62 | name:{ // 作为表单提交时获取name
63 | type:String,
64 | value:''
65 | }
66 | };
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # wx-validInput
2 | 微信小程序校验输入框组件
3 |
4 | ## 主要使用方法
5 | > 将validInput组件下载下来,在要使用的页面的json文件中加入下面代码
6 |
7 | ```json
8 | "usingComponents": {
9 | "validInput": "/你的路径/input/input"
10 | }
11 | ```
12 |
13 | > 在对应的wxml页面
14 |
15 | ```html
16 |
28 |
29 | ```
30 |
31 | ## 校验类型
32 | | 校验类型 | 参数名 |
33 | |:-------:|:-------:|
34 | | 姓名 | name |
35 | | 手机号 | tel |
36 | | 银行卡号 | bankCard |
37 | | 身份证号 | idCard |
38 | | QQ | QQ |
39 | | 日期 | date |
40 | | email | email |
41 | | 邮编 | ecode |
42 |
43 |
44 | ## props(这里只列出和input组件中不同的参数,其余未提出的input属性可直接使用)
45 | | props | 参数名 | 参数类型 | 默认值 |
46 | |:-------:|:-------:|:-------:|:-------:|
47 | | 提示信息 | place-holder | String | 请输入您的数据 |
48 | | 验证类型 | valid-type | String | |
49 | | 验证时机 | valid-time | String | blur |
50 | | 验证错误提示 | valid-toast | String | |
51 | | 初始值 | init-value | String | |
52 | | 最大长度 | max-length | Number | 140 |
53 | | 错误红色阴影提示 | error-border | Boolean | true |
54 |
55 |
--------------------------------------------------------------------------------
/input/input.js:
--------------------------------------------------------------------------------
1 | let properties = require('./properties').default;
2 | let data = require('./data').default;
3 | let validate = require('./validate').default;
4 |
5 | Component({
6 | behaviors: ['wx://form-field'], // 获取form表单提交能力
7 | options: {
8 | multipleSlots: true
9 | },
10 | properties,
11 | data,
12 | // 当组件节点准备好时,进行初始vendor
13 | ready(){
14 | let { initValue } = this.data;
15 | initValue ? this.setData({value:initValue}) : void(0);
16 | },
17 | methods: {
18 | checkFunction(handler){
19 | return Object.prototype.toString.call(handler) == "[Object,Object]";
20 | },
21 | input(event){
22 | let { value } = event.detail;
23 | this.change(event);
24 | this.triggerEvent('input', event, event);
25 | this.setData({value:validate.trims(value,'g')})
26 | this.timeToValid('input',event);
27 |
28 | },
29 | focus(event){
30 | this.triggerEvent('focus', event, event);
31 | this.timeToValid('focus',event);
32 | },
33 | change(event){
34 | this.triggerEvent('change', event, event);
35 | this.timeToValid('change',event);
36 | },
37 | blur(event){
38 | let { detail:{ value } } = event;
39 | this.setData({value})
40 | this.triggerEvent('blur', event, event);
41 | this.timeToValid('blur',event);
42 | },
43 | confirm(event){
44 | this.triggerEvent('confirm', event, event);
45 | this.timeToValid('confirm',event);
46 | },
47 | submit(event){
48 | console.log(11111)
49 | },
50 | // 校验函数
51 | valid(event){
52 | let { type , detail , currentTarget} = event;
53 |
54 | // 解析value和自定义验证时间进行相应验证类型的验证
55 | let { value } = detail,
56 | /* 这里解释一下为什么不从this.data上结构value,因为在输入过程中value并不会双向响应 */
57 | { validtype, validtoast } = currentTarget.dataset;
58 | /*
59 | * 验证过程逻辑分析
60 | * 1. 是否存在验证事件类型
61 | * 2. 是否存在验证类型
62 | * 3. 是否存在value
63 | * 4. 是否toast提示
64 | */
65 | var validEventArray = ['input','change','blur'];
66 | if(validEventArray.includes(type) && validate.hasOwnProperty(validtype)){
67 | console.log(this.data)
68 | var reg = validate[validtype];
69 | if(!reg(value)){
70 | this.showToast(validtype,validtoast);
71 | }else{
72 | this.setData({error: false})
73 | }
74 | }
75 | },
76 | showToast(validtype,validtoast=''){
77 | /* 这里需要整合提示,如果你每次都输入提示的话可以将此处的对象删除 */
78 | let prefix = '您输入的',
79 | endfix = '格式不正确';
80 | let toastmsg = {
81 | 'tel': '手机号',
82 | 'bankCard': '银行卡号',
83 | 'idCard': '身份证号',
84 | 'phone': '座机号码',
85 | 'date' : '时间',
86 | 'email': '邮箱地址',
87 | 'QQ': 'QQ',
88 | 'name': '姓名',
89 | 'ecode': '邮编'
90 | };
91 | validtoast = validtoast ? validtoast : `${prefix}${toastmsg[validtype]}${endfix}`;
92 | let { errorBorder } = this.data;
93 | if(errorBorder){this.setData({error: true});}
94 | wx.showToast({mask:true,title:validtoast,icon:'none'})
95 | },
96 | /* 启用那个函数进行错误处理 */
97 | timeToValid(type,event){
98 | let {validTime} = this.data;
99 | type == validTime ? this.valid(event) : void(0);
100 |
101 | }
102 | },
103 | externalClasses:['valid_input_selfclass']
104 | })
--------------------------------------------------------------------------------
/input/validate.js:
--------------------------------------------------------------------------------
1 | /* 去除所有空格 */
2 | function trimAll(value,all=''){
3 | var result;
4 | result = value.replace(/(^\s+)|(\s+$)/g,"");
5 | if(all.toLowerCase()=="g")result = value.replace(/\s/g,"");
6 | return result;
7 | }
8 |
9 | /* 验证手机号 */
10 | function phone_check(pp){
11 | if((/^[1][0123456789]+\d{9}$/.test(pp)) && pp.length == 11 && pp.slice(0, 1) == 1){
12 | return true;
13 | }
14 | return false;
15 | }
16 |
17 | /*验证银行卡号码*/
18 | var checkUcredit = function (no) {
19 | if (no.length < 16 || no.length > 19) {
20 | //$("#noInfo").html("银行卡号长度必须在16到19之间");
21 | return false;
22 | }
23 | var num = /^\d*$/; //全数字
24 | if (!num.exec(no)) {
25 | //$("#noInfo").html("银行卡号必须全为数字");
26 | return false;
27 | }
28 | //开头6位
29 | var strBin = "10,18,30,35,37,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,58,60,62,65,68,69,84,87,88,94,95,98,99";
30 | if (strBin.indexOf(no.substring(0, 2)) == -1) {//银行卡号开头6位不符合规范
31 | return false;
32 | }
33 | var lastNum = no.substr(no.length - 1, 1); //取出最后一位(与luhm进行比较)
34 |
35 | var first15Num = no.substr(0, no.length - 1); //前15或18位
36 | var newArr = new Array();
37 | for (var i = first15Num.length - 1; i > -1; i--) { //前15或18位倒序存进数组
38 | newArr.push(first15Num.substr(i, 1));
39 | }
40 | var arrJiShu = new Array(); //奇数位*2的积 <9
41 | var arrJiShu2 = new Array(); //奇数位*2的积 >9
42 |
43 | var arrOuShu = new Array(); //偶数位数组
44 | for (var j = 0; j < newArr.length; j++) {
45 | if ((j + 1) % 2 == 1) { //奇数位
46 | if (parseInt(newArr[j]) * 2 < 9)
47 | arrJiShu.push(parseInt(newArr[j]) * 2);
48 | else
49 | arrJiShu2.push(parseInt(newArr[j]) * 2);
50 | } else //偶数位
51 | arrOuShu.push(newArr[j]);
52 | }
53 |
54 | var jishu_child1 = new Array(); //奇数位*2 >9 的分割之后的数组个位数
55 | var jishu_child2 = new Array(); //奇数位*2 >9 的分割之后的数组十位数
56 | for (var h = 0; h < arrJiShu2.length; h++) {
57 | jishu_child1.push(parseInt(arrJiShu2[h]) % 10);
58 | jishu_child2.push(parseInt(arrJiShu2[h]) / 10);
59 | }
60 |
61 | var sumJiShu = 0; //奇数位*2 < 9 的数组之和
62 | var sumOuShu = 0; //偶数位数组之和
63 | var sumJiShuChild1 = 0; //奇数位*2 >9 的分割之后的数组个位数之和
64 | var sumJiShuChild2 = 0; //奇数位*2 >9 的分割之后的数组十位数之和
65 | var sumTotal = 0;
66 | for (var m = 0; m < arrJiShu.length; m++) {
67 | sumJiShu = sumJiShu + parseInt(arrJiShu[m]);
68 | }
69 |
70 | for (var n = 0; n < arrOuShu.length; n++) {
71 | sumOuShu = sumOuShu + parseInt(arrOuShu[n]);
72 | }
73 |
74 | for (var p = 0; p < jishu_child1.length; p++) {
75 | sumJiShuChild1 = sumJiShuChild1 + parseInt(jishu_child1[p]);
76 | sumJiShuChild2 = sumJiShuChild2 + parseInt(jishu_child2[p]);
77 | }
78 | //计算总和
79 | sumTotal = parseInt(sumJiShu) + parseInt(sumOuShu) + parseInt(sumJiShuChild1) + parseInt(sumJiShuChild2);
80 |
81 | //计算Luhm值
82 | var k = parseInt(sumTotal) % 10 == 0 ? 10 : parseInt(sumTotal) % 10;
83 | var luhm = 10 - k;
84 |
85 | if (lastNum == luhm) {
86 | return true;
87 | } else {
88 | return false;
89 | }
90 | }
91 |
92 | /* start 身份证号码 */
93 | var Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1]; // 加权因子
94 | var ValideCode = [1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2]; // 身份证验证位值.10代表X
95 | function IdCardValidate(idCard) {
96 | idCard = trim(idCard.replace(/ /g, "")); //去掉字符串头尾空格
97 | if (idCard.length == 15) {
98 | return isValidityBrithBy15IdCard(idCard); //进行15位身份证的验证
99 | } else if (idCard.length == 18) {
100 | var a_idCard = idCard.split(""); // 得到身份证数组
101 | if (isValidityBrithBy18IdCard(idCard) && isTrueValidateCodeBy18IdCard(a_idCard)) { //进行18位身份证的基本验证和第18位的验证
102 | return true;
103 | } else {
104 | return false;
105 | }
106 | } else {
107 | return false;
108 | }
109 | }
110 |
111 | /**
112 | * 判断身份证号码为18位时最后的验证位是否正确
113 | * @param a_idCard 身份证号码数组
114 | * @return
115 | */
116 | function isTrueValidateCodeBy18IdCard(a_idCard) {
117 | var sum = 0; // 声明加权求和变量
118 | if (a_idCard[17].toLowerCase() == 'x') {
119 | a_idCard[17] = 10; // 将最后位为x的验证码替换为10方便后续操作
120 | }
121 | for (var i = 0; i < 17; i++) {
122 | sum += Wi[i] * a_idCard[i]; // 加权求和
123 | }
124 | var valCodePosition = sum % 11; // 得到验证码所位置
125 | if (a_idCard[17] == ValideCode[valCodePosition]) {
126 | return true;
127 | } else {
128 | return false;
129 | }
130 | }
131 |
132 | /**
133 | * 验证18位数身份证号码中的生日是否是有效生日
134 | * @param idCard 18位书身份证字符串
135 | * @return
136 | */
137 | function isValidityBrithBy18IdCard(idCard18) {
138 | var year = idCard18.substring(6, 10);
139 | var month = idCard18.substring(10, 12);
140 | var day = idCard18.substring(12, 14);
141 | var temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day));
142 | // 这里用getFullYear()获取年份,避免千年虫问题
143 | if (temp_date.getFullYear() != parseFloat(year) || temp_date.getMonth() != parseFloat(month) - 1 || temp_date.getDate() != parseFloat(day)) {
144 | return false;
145 | } else {
146 | return true;
147 | }
148 | }
149 |
150 | /**
151 | * 验证15位数身份证号码中的生日是否是有效生日
152 | * @param idCard15 15位书身份证字符串
153 | * @return
154 | */
155 | function isValidityBrithBy15IdCard(idCard15) {
156 | var year = idCard15.substring(6, 8);
157 | var month = idCard15.substring(8, 10);
158 | var day = idCard15.substring(10, 12);
159 | var temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day));
160 | // 对于老身份证中的你年龄则不需考虑千年虫问题而使用getYear()方法
161 | if (temp_date.getYear() != parseFloat(year) || temp_date.getMonth() != parseFloat(month) - 1 || temp_date.getDate() != parseFloat(day)) {
162 | return false;
163 | } else {
164 | return true;
165 | }
166 | }
167 |
168 | //去掉字符串头尾空格
169 | function trim(str) {
170 | return str.replace(/(^\s*)|(\s*$)/g, "");
171 | }
172 | /*end 身份证*/
173 |
174 | /* 验证电话号(座机) */
175 | function checktel(tel){
176 | return /\d{3}-\d{8}|\d{4}-\d{7}/.test(tel);
177 | /* eg: 021-87888822 */
178 | }
179 |
180 | /* 验证日期格式 */
181 | function checkDate(date){
182 | return /^\d{4}-\d{1,2}-\d{1,2}/.test(date);
183 | /* eg: 2018-04-28 */
184 | }
185 |
186 | /* email地址 */
187 | function checkEmail(email){
188 | return /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(email);
189 | /* eg:www.wangyi@163.com || wangyi@163.com */
190 | }
191 |
192 | /* QQ号码 */
193 | function checkQQ(qq){
194 | return /[1-9][0-9]{4,}/.test(qq); // 从10000开始
195 | }
196 |
197 | /* 邮政编码 */
198 | function checkECode(ecode){
199 | return /[1-9]\d{5}(?!\d)/.test(ecode);
200 | }
201 |
202 | /* 姓名 */
203 | function checkName(name){
204 | return /^[\u4e00-\u9fa5]{2,6}$/.test(name); // 国家规定名字需要为两个以上,六个以下
205 | }
206 |
207 | /* */
208 |
209 | export default
210 | {
211 | 'trims': trimAll,
212 | 'tel': phone_check,
213 | 'bankCard': checkUcredit,
214 | 'idCard': IdCardValidate,
215 | 'phone': checktel,
216 | 'date' : checkDate,
217 | 'email': checkEmail,
218 | 'QQ': checkQQ,
219 | 'name': checkName,
220 | 'ecode': checkECode
221 | }
222 |
--------------------------------------------------------------------------------