概要
我们都知道车牌是有一定规律的,本文实现了微信小程序中实现车牌输入功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
描述
近期做了一个和车有关的小程序项目,有车肯定就有车牌,我们都知道车牌是有一定规律的,如果简单的给个输入框的话。就算通过正则取判断,但是用户体验不是很好,从小我的编程老师告诉我不要相信任何用户输入的东西。嗯嗯!还真是,之前作过一些项目,会被注入,还有个老师告诉我永远要把用户当SB,虽然自己也是用户,感觉不好,但是话糙理不糙啊,因为你永远不知道使用你写的东西的是什么。。。。。(甚至是不是人)。在这样的背景下你说要让用户输入一个正确的车牌号,那可真是比登天还难啊,太南了,臣妾做不到啊。
效果
组件代码
carinput/wxml
<view class="catinput">
<view class="con-query">
<mp-form>
<mp-cells>
<mp-cell class="form_item" prop="carnum" title="车牌号" >
<input bindtap="inputClick" data-field="carnum" class="weui-input" data-id="0" placeholder="请填写车牌号" value='{{carNum}}' disabled="{{true}}"/>
</mp-cell>
</mp-cells>
</mp-form>
</view>
<view class="keyboard" wx:if="{{isKeyboard}}" style="bottom:{{tabheight}}px">
<view class="kb_top">
<view class="plate-input-content plate-content-top">
<view class='plate-input-flag-top' bindtap='changeplate'>
<label class="radio" wx:if="{{isNewEnergy}}">
<radio value="r2" checked="true" />新能源
</label>
<label class="radio" wx:if="{{!isNewEnergy}}" >
<radio value="r2" />新能源
</label>
<text catchtap="tapSpecBtn" data-index="2"
style="position:absolute;right:0;display:block;height:74rpx;padding:0 34rpx; color:#FFB93F;line-height:74rpx; font-size: 30rpx;">取消</text>
</view>
</view>
<view class="plate-input-content">
<view class="{{inputOnFocusIndex=='0'?'plate-nums-foc':'plate-nums-first'}}">
<text bindtap="inputClick" class="plate-num-text" data-id="0">{{inputPlates.index0}}</text>
</view>
<view class="{{inputOnFocusIndex=='1'?'plate-nums-foc':'plate-nums-first'}}">
<text bindtap="inputClick" class="plate-num-text" data-id="1">{{inputPlates.index1}}</text>
</view>
<view style="width:8px;height:38px;border-bottom: 1px solid #707070;"></view>
<view class="{{inputOnFocusIndex=='2'?'plate-nums-foc':'plate-nums-first'}}">
<text bindtap="inputClick" class="plate-num-text" data-id="2">{{inputPlates.index2}}</text>
</view>
<view class="{{inputOnFocusIndex=='3'?'plate-nums-foc':'plate-nums-first'}}">
<text bindtap="inputClick" class="plate-num-text" data-id="3">{{inputPlates.index3}}</text>
</view>
<view class="{{inputOnFocusIndex=='4'?'plate-nums-foc':'plate-nums-first'}}">
<text bindtap="inputClick" class="plate-num-text" data-id="4">{{inputPlates.index4}}</text>
</view>
<view class="{{inputOnFocusIndex=='5'?'plate-nums-foc':'plate-nums-first'}}">
<text bindtap="inputClick" class="plate-num-text" data-id="5">{{inputPlates.index5}}</text>
</view>
<view class="{{inputOnFocusIndex=='6'?'plate-nums-foc':'plate-nums-first'}}">
<text bindtap="inputClick" class="plate-num-text" data-id="6">{{inputPlates.index6}}</text>
</view>
<view class="{{inputOnFocusIndex=='7'?'plate-nums-foc':'plate-nums-first'}}" wx:if="{{isNewEnergy}}">
<text bindtap="inputClick" class="plate-num-text" data-id="7">{{inputPlates.index7}}</text>
</view>
</view>
</view>
<view style="width:100%; text-align:center;" wx:if="{{isNumberKB}}">
<view style="width:99%;display:flex;text-align:center;margin:0 auto">
<view catchtap="tapKeyboard" class="td td_nor" data-index="{{idx}}" data-val="{{itemName}}" hoverClass="board_bg"
hoverStartTime="0" hoverStayTime="80" wx:if="{{idx<=9}}" wx:for="{{keyboard1}}" wx:for-index="idx"
wx:for-item="itemName" wx:key="{{itemName}}">
{{itemName}}
</view>
</view>
<view style="display:flex;text-align:center; width:90%;margin:0 auto">
<view catchtap="tapKeyboard" class="td td_nor" data-index="{{idx}}" data-val="{{itemName}}" hoverClass="board_bg"
hoverStartTime="0" hoverStayTime="80" wx:if="{{idx<=18&&idx>9}}" wx:for="{{keyboard1}}" wx:for-index="idx"
wx:for-item="itemName" wx:key="{{itemName}}">
{{itemName}}
</view>
</view>
<view style="display:flex;text-align:center; width:70%;margin:0 auto">
<view catchtap="tapKeyboard" class="td td_nor" data-index="{{idx}}" data-val="{{itemName}}" hoverClass="board_bg"
hoverStartTime="0" hoverStayTime="80" wx:if="{{idx<=25&&idx>18}}" wx:for="{{keyboard1}}" wx:for-index="idx"
wx:for-item="itemName" wx:key="{{itemName}}">
{{itemName}}
</view>
</view>
<view style="display:flex; width:50%;margin:0 auto;text-align:center;">
<view catchtap="tapKeyboard" class="td td_nor" data-index="{{idx}}" data-val="{{itemName}}" hoverClass="board_bg"
hoverStartTime="0" hoverStayTime="80" wx:if="{{idx>25}}" wx:for="{{keyboard1}}" wx:for-index="idx"
wx:for-item="itemName" wx:key="{{itemName}}">
{{itemName}}
</view>
</view>
<view bindtap="tapSpecBtn" class="del-first" data-index="0" hoverClass="del-hover" hoverStartTime="0"
hoverStayTime="80">
删除
</view>
<view catchtap="tapSpecBtn" class="del-sed" data-index="1" hoverClass="del-hover" hoverStartTime="0"
hoverStayTime="80">
完成
</view>
</view>
<view style="width:100%; text-align:center;" wx:if="{{!isNumberKB}}">
<view style="width:99%;display:flex;text-align:center;margin:0 auto">
<view class="td td_num board_bg" wx:if="{{!tapNum&&idx<=9}}" wx:for="{{keyboardNumber}}" wx:for-index="idx"
wx:for-item="itemName" wx:key="{{itemName}}">
{{itemName}}
</view>
</view>
<view style="width:99%;display:flex;text-align:center;margin:0 auto">
<view catchtap="tapKeyboard" class="td td_num" data-index="{{idx}}" data-val="{{itemName}}" hoverClass="board_bg"
hoverStartTime="0" hoverStayTime="80" wx:if="{{tapNum&&idx<=9}}" wx:for="{{keyboardNumber}}" wx:for-index="idx"
wx:for-item="itemName" wx:key="{{itemName}}">
{{itemName}}
</view>
</view>
<view style="width:99%;display:flex;text-align:center;margin:0 auto">
<view catchtap="tapKeyboard" class="td td_num" data-index="{{idx}}" data-val="{{itemName}}" hoverClass="board_bg"
hoverStartTime="0" hoverStayTime="80" wx:if="{{idx>9&&idx<=17}}" wx:for="{{keyboardNumber}}" wx:for-index="idx"
wx:for-item="itemName" wx:key="{{itemName}}">
{{itemName}}
</view>
<view catchtap="tapKeyboard" class="td td_num" data-index="{{idx}}" data-val="{{itemName}}" hoverClass="board_bg"
hoverStartTime="0" hoverStayTime="80" wx:if="{{tapNum&&18<=idx&&idx<=19}}" wx:for="{{keyboardNumber}}" wx:for-index="idx"
wx:for-item="itemName" wx:key="{{itemName}}">
{{itemName}}
</view>
<view class="td td_num board_bg" wx:if="{{!tapNum&&18<=idx&&idx<=19}}" wx:for="{{keyboardNumber}}" wx:for-index="idx"
wx:for-item="itemName" wx:key="{{itemName}}">
{{itemName}}
</view>
</view>
<view style="width:99%;display:flex;text-align:center;margin:0 auto">
<view catchtap="tapKeyboard" class="td td_num" data-index="{{idx}}" data-val="{{itemName}}" hoverClass="board_bg"
hoverStartTime="0" hoverStayTime="80" wx:if="{{idx>19&&idx<=28}}" wx:for="{{keyboardNumber}}" wx:for-index="idx"
wx:for-item="itemName" wx:key="{{itemName}}">
{{itemName}}
</view>
<view catchtap="tapKeyboard" class="td td_num" data-index="{{idx}}" data-val="{{itemName}}" hoverClass="board_bg"
hoverStartTime="0" hoverStayTime="80" wx:if="{{tapNum&&29==idx}}" wx:for="{{keyboardNumber}}" wx:for-index="idx"
wx:for-item="itemName" wx:key="{{itemName}}">
{{itemName}}
</view>
<view class="td td_num board_bg" wx:if="{{!tapNum&&29==idx}}" wx:for="{{keyboardNumber}}" wx:for-index="idx"
wx:for-item="itemName" wx:key="{{itemName}}">
{{itemName}}
</view>
</view>
<view style="width:69%;display:flex;text-align:left; margin-left:5rpx;">
<view catchtap="tapKeyboard" class="td td_num" data-index="{{idx}}" data-val="{{itemName}}" hoverClass="board_bg"
hoverStartTime="0" hoverStayTime="80" wx:if="{{idx>29}}" wx:for="{{keyboardNumber}}" wx:for-index="idx"
wx:for-item="itemName" wx:key="{{itemName}}">
{{itemName}}
</view>
</view>
<view bindtap="tapSpecBtn" class="del-first" data-index="0" hoverClass="del-hover" hoverStartTime="0"
hoverStayTime="80">
删除
</view>
<view catchtap="tapSpecBtn" class="del-sed" data-index="1" hoverClass="del-hover" hoverStartTime="0"
hoverStayTime="80">
完成
</view>
</view>
</view>
</view>
carinput/json
需要提前引入weui 库
{
"usingComponents": {
"mp-form": "weui-miniprogram/form/form",
"mp-cells": "weui-miniprogram/cells/cells",
"mp-cell": "weui-miniprogram/cell/cell"
},
"component": true
}
carinput/js
Component({
/**
* 组件的属性列表
*/
properties: {
carNum: {
type: String,
value:'',
},
isNewEnergy: {
type: Boolean,
value:false,
},
inputPlates: {
type: Object,
value:{
index0: "",
index1: "",
index2: "",
index3: "",
index4: "",
index5: "",
index6: "",
index7: ""
}
},
},
/**
* 组件的初始数据
*/
data: {
isLoading:false,
appUserId: "",
escapeOrderList: [],
carNumList: [],
hasOrder: false,
isKeyboard: false,
isNumberKB: true,
tapNum: false,
disableKey: "1234567890港澳学",
// keyboardNumber: "1234567890ABCDEFGHJKLMNPQRSTUVWXYZ港澳学",
keyboardNumber: "1234567890QWERTYUP港澳ASDFGHJKL学ZXCVBNM",
keyboard1: "渝川京沪粤津冀晋蒙辽吉黑苏浙皖闽赣鲁豫鄂湘桂琼贵云藏陕甘青宁新",
inputPlates: {
index0: "",
index1: "",
index2: "",
index3: "",
index4: "",
index5: "",
index6: "",
index7: ""
},
inputOnFocusIndex: "",
isNewEnergy: false,
carNum: "",
tabheight:48,
},
attached() {
let tabheight = wx.getStorageSync('tabheight')
this.setData({
tabheight:tabheight,
});
},
methods: {
changeplate: function () {
var that = this;
that.setData({
isNewEnergy:!that.data.isNewEnergy,
});
this.checkCarNum();
},
//切换车牌
changeplate1: function () {
var that = this;
that.setData({
flag: true,
inputPlates: {
index0: "",
index1: "",
index2: "",
index3: "",
index4: "",
index5: "",
index6: "",
index7: ""
},
})
},
inputClick: function (t) {
var that = this;
let tabheight = wx.getStorageSync('tabheight')
that.setData({
tabheight:tabheight,
});
console.log('输入框:', t);
console.log('输入框:', t.target.dataset.id);
if (t.target.dataset.id == 0) {
that.setData({
inputOnFocusIndex: t.target.dataset.id,
isNumberKB: true,
isKeyboard: true,
tapNum: false,
})
};
if (t.target.dataset.id == 1) {
that.setData({
inputOnFocusIndex: t.target.dataset.id,
isNumberKB: false,
isKeyboard: true,
tapNum: false,
})
}
if (t.target.dataset.id > 1) {
that.setData({
inputOnFocusIndex: t.target.dataset.id,
isNumberKB: false,
isKeyboard: true,
tapNum: true,
})
}
},
//键盘点击事件
tapKeyboard: function (t) {
t.target.dataset.index;
var a = t.target.dataset.val;
//console.log("data",this.data);
//console.log('键盘:',a);
//console.log("index",t.target.dataset.index);
//console.log("focus",this.data.inputOnFocusIndex);
switch (parseInt(this.data.inputOnFocusIndex)) {
case 0:
this.setData({
"inputPlates.index0": a,
inputOnFocusIndex: "1"
});
break;
case 1:
this.setData({
"inputPlates.index1": a,
inputOnFocusIndex: "2"
});
break;
case 2:
this.setData({
"inputPlates.index2": a,
inputOnFocusIndex: "3"
});
break;
case 3:
this.setData({
"inputPlates.index3": a,
inputOnFocusIndex: "4"
});
break;
case 4:
this.setData({
"inputPlates.index4": a,
inputOnFocusIndex: "5"
});
break;
case 5:
this.setData({
"inputPlates.index5": a,
inputOnFocusIndex: "6"
});
break;
case 6:
this.setData({
"inputPlates.index6": a,
inputOnFocusIndex: "7"
});
break;
case 7:
this.setData({
"inputPlates.index7": a,
inputOnFocusIndex: "7"
});
}
var n = this.data.inputPlates.index0 + this.data.inputPlates.index1 + this.data.inputPlates.index2 + this.data.inputPlates.index3 + this.data.inputPlates.index4 + this.data.inputPlates.index5 +
this.data.inputPlates.index6 + this.data.inputPlates.index7
console.log('车牌号:', n);
this.data.carNum = n;
this.checkedSubmitButtonEnabled();
this.checkCarNum();
},
//键盘关闭按钮点击事件
tapSpecBtn: function (t) {
var a = this,
e = t.target.dataset.index;
if (0 == e) {
switch (parseInt(this.data.inputOnFocusIndex)) {
case 0:
this.setData({
"inputPlates.index0": "",
inputOnFocusIndex: "0"
});
break;
case 1:
this.setData({
"inputPlates.index1": "",
inputOnFocusIndex: "0"
});
break;
case 2:
this.setData({
"inputPlates.index2": "",
inputOnFocusIndex: "1"
});
break;
case 3:
this.setData({
"inputPlates.index3": "",
inputOnFocusIndex: "2"
});
break;
case 4:
this.setData({
"inputPlates.index4": "",
inputOnFocusIndex: "3"
});
break;
case 5:
this.setData({
"inputPlates.index5": "",
inputOnFocusIndex: "4"
});
break;
case 6:
this.setData({
"inputPlates.index6": "",
inputOnFocusIndex: "5"
});
break;
case 7:
this.setData({
"inputPlates.index7": "",
inputOnFocusIndex: "6"
});
}
this.checkedSubmitButtonEnabled();
var n = this.data.inputPlates.index0 + this.data.inputPlates.index1 + this.data.inputPlates.index2 + this.data.inputPlates.index3 + this.data.inputPlates.index4 + this.data.inputPlates.index5 +
this.data.inputPlates.index6 + this.data.inputPlates.index7
//console.log('车牌号:', n);
this.data.carNum = n;
var res = this.checkCarNum();
} else if (1 == e){
this.checkedSubmitButtonEnabled();
var n = this.data.inputPlates.index0 + this.data.inputPlates.index1 + this.data.inputPlates.index2 + this.data.inputPlates.index3 + this.data.inputPlates.index4 + this.data.inputPlates.index5 +
this.data.inputPlates.index6 + this.data.inputPlates.index7
//console.log('车牌号:', n);
this.data.carNum = n;
var res = this.checkCarNum();
if(res===false){
wx.showToast({
title: '请输入完整的车牌号',
icon:'none'
})
return false;
}
a.setData({
isKeyboard: !1,
isNumberKB: !1,
inputOnFocusIndex: ""
})
}else if (2 == e){
a.setData({
isKeyboard: !1,
isNumberKB: !1,
inputOnFocusIndex: "",
inputPlates: {
index0: "",
index1: "",
index2: "",
index3: "",
index4: "",
index5: "",
index6: "",
index7: ""
},
inputOnFocusIndex: "",
isNewEnergy: false,
carNum: ""
})
}
},
//键盘切换
checkedKeyboard: function () {
var t = this;
//console.log("键盘切换", this.data.inputOnFocusIndex);
if (this.data.inputOnFocusIndex == 0) {
t.setData({
tapNum: false,
isNumberKB: true
})
}
if (this.data.inputOnFocusIndex == 1) {
t.setData({
tapNum: false,
isNumberKB: false
})
}
if (this.data.inputOnFocusIndex > 1) {
t.setData({
tapNum: true,
isNumberKB: false
})
}
},
checkedSubmitButtonEnabled: function () {
this.checkedKeyboard();
var t = !0;
for (var a in this.data.inputPlates)
if ("index7" != a && this.data.inputPlates[a].length < 1) {
t = !1;
break;
}
},
//校验车牌号-车牌输入限制了正确格式只判断车牌位数
checkCarNum: function () {
if (this.data.isNewEnergy && this.data.carNum.length < 8) {
let res={
carNum:this.data.carNum,
isPlate:false,
isNewEnergy:this.data.isNewEnergy,
inputPlates:this.data.inputPlates,
}
this.setData({
carNum:this.data.carNum,
})
this.triggerEvent("setCarNum",res);
return false
}
if (!this.data.isNewEnergy) {
if (this.data.carNum.length < 7) {
let res={
carNum:this.data.carNum,
isPlate:false,
inputPlates:this.data.inputPlates,
isNewEnergy:this.data.isNewEnergy,
}
this.setData({
carNum:this.data.carNum,
})
this.triggerEvent("setCarNum",res);
return false
} else {
var carNum = this.data.carNum.substr(0, 7);
let res={
carNum:carNum,
isPlate:true,
inputPlates:this.data.inputPlates,
isNewEnergy:this.data.isNewEnergy,
}
this.setData({
carNum:carNum,
})
this.triggerEvent("setCarNum",res);
return true;
}
}
let res={
carNum:this.data.carNum,
isPlate:true,
isNewEnergy:this.data.isNewEnergy,
inputPlates:this.data.inputPlates,
}
this.setData({
carNum:this.data.carNum
})
this.triggerEvent("setCarNum",res);
return true;
}
}
})
carinput/wxss
.con-query {
width:100%;
border-radius: 8px;
background-color: #FFF;
}
.pages_header {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.pages_header_top {
width: 33.3%;
height: 60rpx;
border-left: 5px solid green;
border-right: 5px solid green;
}
.pages_header_btm {
width: 70%;
background: green;
height: 120rpx;
line-height: 120rpx;
text-align: center;
color: white;
border-radius: 10rpx;
font-weight: normal;
font-size: 16pt;
}
.tips {
text-align: center;
margin: 60rpx 0;
font-size: 12pt;
color: #888888;
}
.plate-input-text{
text-align: center;
line-height: 90rpx;
color: #f39900;
}
.plate-input-flag {
float: right;
margin-right: 8%;
font-size: 14PX;
}
.plate-input-flag .new-energy{
color: #14c414;
}
.plate-input-body {
/*border: 1px solid red;*/
height: 80rpx;
width: 100%;
}
.plate-input-content {
display: flex;
flex-direction: row;
height: 80rpx;
}
.plate-nums-foc {
flex: 1;
border: 2rpx solid #FFB93F;
margin: 0 5rpx 0 5rpx;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
height: 100%;
box-sizing: border-box;
border-radius: 4rpx;
}
.plate-input-flag-top{
float: right;
margin-right:18%;
font-size: 14PX;
display: flex;
align-items: center;
justify-content: center;
}
.plate-nums-first{
flex: 1;
border: 1rpx solid #CCCCCC;
margin: 0 5rpx 0 5rpx;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
height: 100%;
box-sizing: border-box;
}
.plate-num-text {
flex: 1;
line-height: 80rpx;
height: 100%;
box-sizing: border-box;
font-size: 40rpx;
font-weight: 300;
}
.new-plate-input-content{
display: flex;
flex-direction: row;
height: 100rpx;
}
.plate-content-top{
justify-content: flex-end;
}
.kb_bot {
align-content: relative;
width: 100%;
height: 74rpx;
background: #fff;
border-top: solid #ebebeb 2rpx;
border-bottom: 15rpx solid #F4F4F4;
}
.kb_top
{
align-content: relative;
width: 100%;
height: 162rpx;
background: #fff;
border-top: solid #ebebeb 2rpx;
border-bottom: 15rpx solid #F4F4F4;
}
.keyboard {
z-index: 9999;
position: fixed;
bottom:0;
left: 0;
width: 100%;
height: auto;
background: #F4F4F4;
display: flex;
flex-wrap: wrap;
border-bottom: 15rpx solid #F4F4F4;
}
.td {
font-family: "微软雅黑";
flex-grow: 1;
text-align: center;
font-size: 34rpx;
height: 86rpx;
line-height: 80rpx;
background: #fff;
margin: 10rpx 5rpx;
color: #333;
border-radius: 2rpx;
box-shadow: 0rpx 2rpx 0rpx #a9a9a9;
}
.td_nor {
flex: 1 1 6%;
}
.td_num {
flex: 1 1 8%;
}
.td_spec {
flex: 1 1 12%;
}
.board_bg {
box-shadow: 0 0 0 #e5e5e5;
background: #e5e5e5;
}
.del-first {
position: absolute;
bottom: 10rpx;
right: 100rpx;
width: 80rpx;
height: 86rpx;
background-color: #fff;
box-shadow: 0rpx 2rpx 0rpx #a9a9a9;
display: flex;
align-items: center;
justify-content: center;
border-radius: 10rpx;
}
.del-sed{
position: absolute;
bottom: 10rpx;
right: 10rpx;
width: 80rpx;
height: 86rpx;
background-color: #fff;
box-shadow: 0rpx 2rpx 0rpx #a9a9a9;
display: flex;
align-items: center;
justify-content: center;
border-radius: 10rpx;
}
.del-hover {
position: absolute;
bottom: 10rpx;
right: 10rpx;
width: 137rpx;
height: 86rpx;
background-color: #e5e5e5;
display: flex;
align-items: center;
justify-content: center;
border-radius: 10rpx;
box-shadow: 0 0 0 #e5e5e5;
}
.del-img {
display: block;
width: 46rpx;
height: 38rpx;
}
.color-white{
color: #FFFFFF;
}
.color-red{
color: #ff0000;
}
.bule{
color: #0000ff;
}
引入
在需要调用的页面 usingComponents 中引入 “car-input”: “/components/car-input/index”
{
"usingComponents": {
"mp-form-page": "weui-miniprogram/form-page/form-page",
"mp-form": "weui-miniprogram/form/form",
"carinput": "/components/car-input/index"
}
}
在页面中调用
<car-input bind:setCarNum="getCarNum" car-num="{{carinfo.carNum}}" is-new-energy="{{carinfo.isNewEnergy}}" input-plates="{{carinfo.inputPlates}}"></car-input>
设置事件
getCarNum(e){
let carinfo = {}
carinfo.carNum =e.detail.carNum
carinfo.inputPlates =e.detail.inputPlates
carinfo.isPlate = e.detail.isPlate
carinfo.isNewEnergy = e.detail.isNewEnergy
this.setData({
carinfo
})
}