preface

Hahaha, new article. It has not been updated for a long time, today I will take a rest to summarize the previous use of the custom keyboard to enter the vehicle license plate wechat components. The following is the effect, please enjoy:

background

Recently, I have done a project related to cars. If there is a car, there must be a license plate. We all know that license plates have certain rules. When I was a kid, my programming teacher told me not to trust anything the user typed. Uh huh! Now think about it is really so, there are always some unique users like the reverse, do not know is really do not understand or destroy ha. There is a teacher told me to always put the user when SB, although he is also a user, feel bad, but coarse but not coarse ah, because you never know what to use what you write… (Or even a person). In this context, you say to let the user input a correct license plate number, that is really more than heaven, too south, I can not do ah.

Big guess

In this case, we also come when a user to see what the situation is probably ha, come, don’t go away oh, the following is to play the user’s imagination.

  • I a. 12345
  • Hubei Anderson i111
  • Xa.6666666
  • Za. Hahahaha
  • .

Wow, it is estimated to write a day can not finish it, look at the back of everyone, here is a premise that WE do not consider the English beginning of the license plate, if you need to consider you can draw inferno.

Looking for a regular

Do not have what rule to be able to look for actually, go up directly baidu a search to know the rule of license plate. The first is the abbreviation of the province, the second is the letter, followed by a mixture of letters and numbers, here are a few special coaches, Hong Kong and Macao car into the mainland, consulate car. In addition, the letters and the letters o and the numbers 1 and 0 are difficult to read, so the letters I and O are removed, and finally the pattern is established.

Structure and style

Once you know the rules, you can start to work on them. First look at the layout of the keyboard in the design:The picture above is the keyboard layout for provincial abbreviationThe image above shows the second letter keyboard layoutThe above picture shows the keyboard layout for the latter few digits

Here’s how to write the structure according to these layouts:

<view class="keyboard" wx:if="{{isShow}}">
    <view class="item">
        <view wx:for="{{dataArr1}}" wx:key="unique" bindtap="inputKey" data-value="{{item}}">{{item}}</view>
    </view>
    <view class="item">
        <view wx:for="{{dataArr2}}" wx:key="unique" bindtap="inputKey" data-value="{{item}}">{{item}}</view>
    </view>
    <view class="item">
        <view wx:for="{{dataArr3}}" wx:key="unique" bindtap="inputKey" data-value="{{item}}">{{item}}</view>
    </view>
    <view class="item" wx:if="{{dataArr4.length}}">
        <view wx:for="{{dataArr4}}" wx:key="unique" bindtap="inputKey" data-value="{{item}}">{{item}}</view>
    </view>
    <view class="delbtn" bindtap="delKey" wx:if="{{keyType == 'carlicense'}}"><image src="./icon_del.png"></image></view>
</view>
<view class="mask" bindtap="hideKeyBoard" wx:if="{{isShow}}"></view>
Copy the code

Put the data into four arrays, one row less because the second one is missing, a delete button, and finally a mask layer for clicking elsewhere to close the keyboard

Let’s add some test data and write down the basic colors:

data: {dataArr1: [" Beijing ", "Shanghai", "yue", "jin", "ji", "jin", "liao", ""," black ", "auspicious"], dataArr2: [" su ", "zhejiang", "anhui", "min", "jiangxi", "lu", "yu", "e", "xiang"]. DataArr3: [" sichuan ", "expensive", "cloud", "chongqing", "guangxi", "Joan", "hidden", "shan"], dataArr4: [" f ", "green", "better", "new", "Taiwan"]}Copy the code

Take the input province as an example

The next step is to add our style to see the effect:

.keyboard {
    position: fixed;
    left: 0;
    bottom: 0;
    z-index: 99999;
    width: 100%;
    background: #d1d6d9;
    padding: 20rpx 10rpx 0;
    padding-bottom:calc(30px + env(safe-area-inset-bottom)/2);
    box-sizing: border-box;
}

.keyboard .item {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 20rpx;
}

.keyboard .item view {
    width: 9%;
    height: 70rpx;
    line-height: 70rpx;
    text-align: center;
    margin-right: 10rpx;
    background: #ffffff;
    border-radius: 10rpx;
    font-size: 28rpx;
}

.keyboard .item view:last-child {
    margin-right: 0;
}

.keyboard .delbtn {
    position: fixed;
    right: 10rpx;
    bottom: calc(40px + env(safe-area-inset-bottom)/2);
    height: 70rpx;
    width: 18%;
    z-index: 999999;
    background: #adb3bd;
    border-radius: 10rpx;
    display: flex;
    align-items: center;
    justify-content: center;
}

.keyboard .delbtn image{
    width: 60rpx;
    height: 60rpx;
}

.mask{
    position: fixed;
    left: 0;
    top: 113rpx;
    bottom: 0;
    right: 0;
    z-index: 99998;
}
Copy the code

Here style is not much to say, you can follow their own preferences to the line

Now you can see the effect, as shown here:

Component implementation

Component implementation is actually very simple, the main need to know the use of wechat component is OK.

parameter

Before we do that, let’s see what parameters we need, because the keyboard is definitely going to have to show and hide, so we need to have a show and hide parameter and we’re going to call it isShow. Now if we look at our style what if we input the second or the next number of arrays that we defined before we have to change the data? The question is when do we change it? If you want to open it at the point where you click on the input, you’ll know if you want to enter the province or the second or the next, so you need to have a parameter that tells you what type of keyboard you want to display, and I’ll call it keyType. So now that we have the parameters, let’s see if we need to set the default value, so for isShow it’s going to start with false which means it’s not going to be displayed, and for keyType it’s going to be whatever it is, but it’s going to be province by default. The arguments here are actually the arguments passed when the component is called, so these two arguments are set to properties of the component.

With the above analysis, the component is basically out. The code is as follows:

Component({ properties: { keyType:{ type:String, value:'province' }, isShow:{ type:Boolean, value:false } }, data: {dataArr1: [" Beijing ", "Shanghai", "yue", "jin", "ji", "jin", "liao", ""," black ", "auspicious"], dataArr2: [" su ", "zhejiang", "anhui", "min", "jiangxi", "lu", "yu", "e", "xiang"]. DataArr3: [" sichuan ", "expensive", "cloud", "chongqing", "guangxi", "Joan", "hidden", "shan"], dataArr4: [" f ", "green", "better", "new", "Taiwan"]}})Copy the code

Keyboard type

Ok, now that you’ve considered the keyboard parameters, you need to switch the values of different keyboard arrays based on the keyType passed in. In this case, you need to write a method inside the component method to switch.

Component({ properties: { keyType:{ type:String, value:'province' }, isShow:{ type:Boolean, value:false } }, data: { dataArr1:[], dataArr2:[], dataArr3:[], dataArr4:[] }, methods: { changeType(){ if(this.data.keyType == 'letter'){ this.setData({ dataArr1:["Q","W","E","R","T","Y","U","P","N","M"], dataArr2:["A","S","D","F","G","H","J","K","L"], dataArr3:["Z","X","C","V","B"], dataArr4:[] }) }else if(this.data.keyType == 'province'){ this.setData({ DataArr1: [" Beijing ", "Shanghai", "yue", "jin", "ji", "jin", "liao", ""," black ", "auspicious"], dataArr2: [" su ", "zhejiang", "anhui", "min", "jiangxi", "lu", "yu", "e", "xiang"]. DataArr3 :[" chuan "," GUI "," yun "," Yu "," GUI "," Qiong "," Zang "," Shan "], DataArr4: [" f ", "green", "better", "new", "Taiwan"]})} else if (this. Data. KeyType = = 'carlicense') {enclosing setData ({ dataArr1:["1","2","3","4","5","6","7","8","9","0"], dataArr2:["A","B","C","D","E","F","G","H","J","K"], DataArr3: [" L ", "M", "N", "P", "Q", "R", "S", "T", "U" and "V"], dataArr4: [" W ", "X", "Y", "Z", "Hong Kong", "Macao", "learning", "leading"]})}}}})Copy the code

Cutting method had, is now call this method when the initialization, modify the code is as follows:

Component({ properties: { keyType:{ type:String, value:'province' }, isShow:{ type:Boolean, value:false } }, data: { dataArr1:[], dataArr2:[], dataArr3:[], dataArr4:[] }, attached(){ this.changeType() }, methods: { changeType(){ if(this.data.keyType == 'letter'){ this.setData({ dataArr1:["Q","W","E","R","T","Y","U","P","N","M"], dataArr2:["A","S","D","F","G","H","J","K","L"], dataArr3:["Z","X","C","V","B"], dataArr4:[] }) }else if(this.data.keyType == 'province'){ this.setData({ DataArr1: [" Beijing ", "Shanghai", "yue", "jin", "ji", "jin", "liao", ""," black ", "auspicious"], dataArr2: [" su ", "zhejiang", "anhui", "min", "jiangxi", "lu", "yu", "e", "xiang"]. DataArr3 :[" chuan "," GUI "," yun "," Yu "," GUI "," Qiong "," Zang "," Shan "], DataArr4: [" f ", "green", "better", "new", "Taiwan"]})} else if (this. Data. KeyType = = 'carlicense') {enclosing setData ({ dataArr1:["1","2","3","4","5","6","7","8","9","0"], dataArr2:["A","B","C","D","E","F","G","H","J","K"], DataArr3: [" L ", "M", "N", "P", "Q", "R", "S", "T", "U" and "V"], dataArr4: [" W ", "X", "Y", "Z", "Hong Kong", "Macao", "learning", "leading"]})}}}})Copy the code

At this point, the basic functionality of the component is complete, but when we click on the content on the keyboard, you will notice that there is no response. There seems to be something missing here, and since it’s a keyboard you have to get the input.

Get input

To obtain the input content of the keyboard, it is necessary to add new events to each key of the keyboard to obtain the input content, and add new events to the previous structure. For details, please refer to the code in the first paragraph of this article. The specific implementation code is as follows:

methods: {
  inputKey(e){
    console.log(e.currentTarget.dataset.value)
  },
  delKey(e){
    console.log(e.currentTarget.dataset.value)
  },
  hideKeyBoard(){
    this.setData({
        isShow:false
    })
  }
}
Copy the code

The time to delete and close the keyboard has also been added, and you can get the input value through the above two methods. When we click on a character, the control panel will print out the selected value.However, I need to not print the value, but need to display the value on the page, here need to build the value to the page that calls the shuffle. how to pass to the page that calls the component?

Component and the cords

Here we can go to the official document of wechat small program to see, after all, the official document is a good thing, find the place shown in the following picture:We use here is the component communication of the second point event, can pass arbitrary data, so according to the official documentation I believe you know how to use, the code is as follows:

methods: {
  inputKey(e){
    this.triggerEvent('inputword', {type:'input',value:e.currentTarget.dataset.value})
  },
  delKey(e){
    this.triggerEvent('inputword', {type:'del'})
  },
  hideKeyBoard(){
    this.setData({
        isShow:false
    })
    this.triggerEvent('inputword', {type:'blur'})
  }
}
Copy the code

Instead, all operations are passed through an event, and a type is added to determine whether to enter, delete, or close the keyboard.

Components use

HMM, not easy ah, finally it’s time to use the component, here according to the wechat component usage as follows:

  • Import the component address into the page configuration file
  • Adds a label for the component to the page
  • Add parameters and events that need to be passed to the added tag

The relevant code is as follows:

{"navigationBarTitleText": "New vehicle ", "usingComponents": {" Keyboard ":".. /.. /components/keyboard/index" } }Copy the code

Add the code above to the configuration file for the page that needs the reorganization

<view class="bind-car"> <view class="car-province {{focusProvince? 'active':''}}"> <view bindtap="chooseProvinceCn">{{provinceCn}}</view> <view bindtap="chooseProvinceCode">{{provinceCode}}</view> </view> <view class="car-number {{focusCode? 'active':''}}" bindtap="chooseCarCode">{{carCode}}</view> </view> <keyboard bindinputword="inputWord" keyType="{{setKeyType}}" isShow="{{showKeyBoard}}"></keyboard>Copy the code

Add the last line of code above to the page you are using, and add the parameters and events you believe

The next step is to process the corresponding parameters and events in the page js, the specific code is as follows:

Page({
  data: {
    focusProvince:false,
    focusCode:false,
    setKeyType:'province',
    showKeyBoard:false,
    keyIndex:0,
    provinceCn:'',
    provinceCode:'',
    carCode:''
  },
  inputWord(e){
    if(e.detail.type == 'input'){
      if(this.data.keyIndex == 0){
        this.setData({
          provinceCn:e.detail.value
        })
      }else if(this.data.keyIndex == 1){
        this.setData({
          provinceCode:e.detail.value
        })
      }else if(this.data.keyIndex == 2){
        if(this.data.carCode.length < 6){
          this.setData({
            carCode:this.data.carCode + e.detail.value
          })
        }
      }
    }else if(e.detail.type == 'del'){
      if(this.data.carCode){
        this.setData({
          carCode:this.data.carCode.substr(0, this.data.carCode.length - 1)
        })
      }
    }else if(e.detail.type == 'blur'){
      this.setData({
        focusCode:false,
        focusProvince:false
      })
    }
  },
  chooseProvinceCn(){
    this.setData({
      setKeyType:'province',
      showKeyBoard:true,
      keyIndex:0,
      focusProvince:true,
      focusCode:false
    })
  },
  chooseProvinceCode(){
    this.setData({
      setKeyType:'letter',
      showKeyBoard:true,
      keyIndex:1,
      focusProvince:true,
      focusCode:false
    })
  },
  chooseCarCode(){
    this.setData({
      setKeyType:'carlicense',
      showKeyBoard:true,
      keyIndex:2,
      focusCode:true,
      focusProvince:false
    })
  }
})
Copy the code

The inputWord in the page is the event that we finally need to deal with, and the other few are the switches that control the focus and display the corresponding red box after input

test

This step is the program little brother little sister more afraid of, the test of the little brother little sister that zha write their own code kept messing around with a, ha ha ha, the last bone in the nitpick. In this case, when we select different types of input, we find that the content of the keyboard does not change, so I wrote a bug to myself.

Fixed a bug with keyboard type determination

The keyType that is passed to the component is cached every time the component is displayed, so you need to listen for changes in the property declaration of the component, just do it, and get off work immediately.

Component({
  properties: {
    keyType:{
      type:String,
      value:'letter',
      observer:function(newVal,oldVal){
          this.changeType()
      }
    },
    isShow:{
      type:Boolean,
      value:false
    }
  }
})
Copy the code

Add an observer function to the property and call the type-determining function when there is a change. So it can be used happily. Finally I clocked in and left my backpack… Wait, there’s more to come

conclusion

At present, this component is only written to fulfill the requirements. There may be a lot of problems during the actual use. Welcome to raise oh. Finally, put the complete code for each file

Component code

WXML

<view class="keyboard" wx:if="{{isShow}}">
    <view class="item">
        <view wx:for="{{dataArr1}}" wx:key="unique" bindtap="inputKey" data-value="{{item}}">{{item}}</view>
    </view>
    <view class="item">
        <view wx:for="{{dataArr2}}" wx:key="unique" bindtap="inputKey" data-value="{{item}}">{{item}}</view>
    </view>
    <view class="item">
        <view wx:for="{{dataArr3}}" wx:key="unique" bindtap="inputKey" data-value="{{item}}">{{item}}</view>
    </view>
    <view class="item" wx:if="{{dataArr4.length}}">
        <view wx:for="{{dataArr4}}" wx:key="unique" bindtap="inputKey" data-value="{{item}}">{{item}}</view>
    </view>
    <view class="delbtn" bindtap="delKey" wx:if="{{keyType == 'carlicense'}}"><image src="./icon_del.png"></image></view>
</view>
<view class="mask" bindtap="hideKeyBoard" wx:if="{{isShow}}"></view>
Copy the code

WXSS

.keyboard {
    position: fixed;
    left: 0;
    bottom: 0;
    z-index: 99999;
    width: 100%;
    background: #d1d6d9;
    padding: 20rpx 10rpx 0;
    padding-bottom:calc(30px + env(safe-area-inset-bottom)/2);
    box-sizing: border-box;
}

.keyboard .item {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 20rpx;
}

.keyboard .item view {
    width: 9%;
    height: 70rpx;
    line-height: 70rpx;
    text-align: center;
    margin-right: 10rpx;
    background: #ffffff;
    border-radius: 10rpx;
    font-size: 28rpx;
}

.keyboard .item view:last-child {
    margin-right: 0;
}

.keyboard .delbtn {
    position: fixed;
    right: 10rpx;
    bottom: calc(40px + env(safe-area-inset-bottom)/2);
    height: 70rpx;
    width: 18%;
    z-index: 999999;
    background: #adb3bd;
    border-radius: 10rpx;
    display: flex;
    align-items: center;
    justify-content: center;
}

.keyboard .delbtn image{
    width: 60rpx;
    height: 60rpx;
}
.mask{
    position: fixed;
    left: 0;
    top: 113rpx;
    bottom: 0;
    right: 0;
    z-index: 99998;
}
Copy the code

JS

Component({ properties: { keyType:{ type:String, value:'letter', observer:function(newVal,oldVal){ this.changeType() } }, isShow:{ type:Boolean, value:false } }, data: { dataArr1:[], dataArr2:[], dataArr3:[], dataArr4:[] }, attached(){ this.changeType() }, methods: { changeType(){ if(this.data.keyType == 'letter'){ this.setData({ dataArr1:["Q","W","E","R","T","Y","U","P","N","M"], dataArr2:["A","S","D","F","G","H","J","K","L"], dataArr3:["Z","X","C","V","B"], dataArr4:[] }) }else if(this.data.keyType == 'province'){ this.setData({ DataArr1: [" Beijing ", "Shanghai", "yue", "jin", "ji", "jin", "liao", ""," black ", "auspicious"], dataArr2: [" su ", "zhejiang", "anhui", "min", "jiangxi", "lu", "yu", "e", "xiang"]. DataArr3 :[" chuan "," GUI "," yun "," Yu "," GUI "," Qiong "," Zang "," Shan "], DataArr4: [" f ", "green", "better", "new", "Taiwan"]})} else if (this. Data. KeyType = = 'carlicense') {enclosing setData ({ dataArr1:["1","2","3","4","5","6","7","8","9","0"], dataArr2:["A","B","C","D","E","F","G","H","J","K"], DataArr3: [" L ", "M", "N", "P", "Q", "R", "S", "T", "U" and "V"], dataArr4: [" W ", "X", "Y", "Z", "Hong Kong", "Macao", "learning", "leading"]})}}, inputKey(e){ this.triggerEvent('inputword', {type:'input',value:e.currentTarget.dataset.value}) }, delKey(e){ this.triggerEvent('inputword', {type:'del'}) }, hideKeyBoard(){ this.setData({ isShow:false }) this.triggerEvent('inputword', {type:'blur'}) } } })Copy the code

Using page code

JSON

{"navigationBarTitleText": "New vehicle ", "usingComponents": {" Keyboard ":".. /.. /components/keyboard/index" } }Copy the code

WXML

<view class="bind-car"> <view class="car-province {{focusProvince? 'active':''}}"> <view bindtap="chooseProvinceCn">{{provinceCn}}</view> <view bindtap="chooseProvinceCode">{{provinceCode}}</view> </view> <view class="car-number {{focusCode? 'active':''}}" bindtap="chooseCarCode">{{carCode}}</view> </view> <keyboard bindinputword="inputWord" keyType="{{setKeyType}}" isShow="{{showKeyBoard}}"></keyboard>Copy the code

WXSS

.bind-car {
    display: flex;
    align-items: center;
    background: #FFFFFF;
    padding: 25rpx 30rpx;
}

.bind-car .car-province {
    margin-right: 30rpx;
    width: 170rpx;
    height: 88rpx;
    border: 1rpx solid #999999;
    border-radius: 4rpx;
    display: flex;
}

.bind-car .car-province view {
    width: 86rpx;
    height: 88rpx;
    line-height: 88rpx;
    text-align: center;
    font-size: 34rpx;
    font-weight: 500;
    color: #333333;
}

.bind-car .car-province view:first-child {
    position: relative;
}

.bind-car .car-province view:first-child::after {
    content: '';
    position: absolute;
    right: 0;
    top: 50%;
    width: 1rpx;
    height: 40rpx;
    background: #999999;
    margin-top: -20rpx;
}

.bind-car .car-province.active {
    border-color: #FF5152;
}

.bind-car .car-province.active view:first-child::after {
    background: #E83333;
}

.car-number {
    width: 100%;
    height: 88rpx;
    line-height: 88rpx;
    border: 1rpx solid #999999;
    border-radius: 4rpx;
    font-size: 34rpx;
    font-weight: 500;
    color: #333333;
    text-align: center;
}

.car-number.active {
    border-color: #E83333;
}
Copy the code

JS

Page({
    data: {
        focusProvince:false,
        focusCode:false,
        setKeyType:'province',
        showKeyBoard:false,
        keyIndex:0,
        provinceCn:'',
        provinceCode:'',
        carCode:''
    },
    inputWord(e){
        if(e.detail.type == 'input'){
            if(this.data.keyIndex == 0){
                this.setData({
                    provinceCn:e.detail.value
                })
            }else if(this.data.keyIndex == 1){
                this.setData({
                    provinceCode:e.detail.value
                })
            }else if(this.data.keyIndex == 2){
                if(this.data.carCode.length < 6){
                    this.setData({
                        carCode:this.data.carCode + e.detail.value
                    })
                }
            }
        }else if(e.detail.type == 'del'){
            if(this.data.carCode){
                this.setData({
                    carCode:this.data.carCode.substr(0, this.data.carCode.length - 1)
                })
            }
        }else if(e.detail.type == 'blur'){
            this.setData({
                focusCode:false,
                focusProvince:false
            })
        }
    },
    chooseProvinceCn(){
        this.setData({
            setKeyType:'province',
            showKeyBoard:true,
            keyIndex:0,
            focusProvince:true,
            focusCode:false
        })
    },
    chooseProvinceCode(){
        this.setData({
            setKeyType:'letter',
            showKeyBoard:true,
            keyIndex:1,
            focusProvince:true,
            focusCode:false
        })
    },
    chooseCarCode(){
        this.setData({
            setKeyType:'carlicense',
            showKeyBoard:true,
            keyIndex:2,
            focusCode:true,
            focusProvince:false
        })
    }
})
Copy the code