支付宝小程序自定义键盘-车牌号键盘

小程序原生写法手写自定义键盘,订制车牌号输入键盘

前段时间接了个ETC的 支付宝小程序 项目。流程中用到了车牌号输入键盘,由于小程序没有相应的扩展组件,只能手写一个自定义的键盘。

键盘的逻辑根据需求控制

  1. 点击键盘区域触发弹出自定义键盘,第一步要求必须输入简称,
  2. 当车牌号为空时只允许用户输入省份简称,输入第一位简称后无需点击下一步操作自动切换到数字字母键盘,
  3. 规定第二位必须为字母,判断此时只能输入至少一位字母,数字键盘默认不可点击,
  4. 当用户第二位输入字母后将数字设置为可以点击,
  5. 本次客户需求只考虑7位车牌,输入满七位后不可再输入,返回按钮切换为完成按钮,点击关闭键盘,

先看效果

选择省份简称
输入省份简称

输入数字字母,第二位必须为字母
输入数字字母

最多输入七位车牌号,da输入七位后显示完成按钮最多输入七位车牌

输滑动屏幕或点击空白收起键盘滑动或点击空白区域隐藏键盘

输入键盘+车牌颜色选择 完整代码

AXML页面结构 keyboard.axml.

<view class="add-car-container">
  <view class="add-list-box">
    <view class="card-num-con">
      <text>
       车牌号码
      </text>
      <view class='carnum' onTap="backKeyboard" disabled="{{canNotChange}}">
        <block a:for="{{7}}">
          <text class="{{carnum.length==index?'carnum-blue':''}}">{{carnum.split('')[index]}}</text>
        </block>
      </view>
    </view>
    <view class="chose-color">
      <text>
       车辆颜色
      </text>
      <radio-group class="radio-group" onChange="radioChange">
        <label a:for="{{items}}" class="radio {{item.name}}">
          <radio value="{{item.key}}"  checked="{{item.checked}}" class="unchose" />
          <icon a:if="{{item.checked}}" type="success" size="20"/>
          <text>{{item.value}}</text>
        </label>
      </radio-group>
    </view>
  </view>
</view>


<!-- 键盘结构 -->
<view class="keyboard" hidden="{{hiddenPro&&hiddenStr}}" catchTap="stopPropagation">
  <view class="keyboard-mini" >
    <!-- 限制键盘 -->
    <!-- 省键盘 -->
    <view class="provinces" hidden="{{hiddenPro}}">
      <view class="pro-li fl" a:for="{{provinceArr}}" catchTap="proTap" data-province="{{item}}">{{item}}</view>
    </view>
    <!-- 号码键盘	 -->
    <view class="keyNums" hidden="{{hiddenStr}}">
      <view 
        class="pro-li fl" 
        a:for="{{strArr}}" 
        :key="{{index}}" 
        catchTap="strTap" 
        disabled="{{strDisabled||(notNum&&index<10)}}" 
        data-str="{{item}}">
          {{item}}
      </view>
      <view class="bot fl">
        <view class="kb-icon kb-hide fl pro-li" catchTap="backSpace">删除</view>
        <view class="kb-icon kb-hide fl pro-li {{downBtn=='完成'?'down-blue':''}}" catchTap="applyNum" >{{downBtn}}</view>
      </view>
    </view>
  </view>


</view>;

acss页面样式 keyboard.acss.

 page {
   background-color: #f5f5f5;
   font-size: 34rpx;
 }

 .radio-group label {
   width: 160rpx;
   height: 55rpx;
   text-align: center;
   border-radius: 8rpx;
   vertical-align: middle;
   margin-left: 20rpx;
   line-height: 60rpx;
   display: inline-block;
 }

 .radio-group label radio {
   vertical-align: middle;
   transform: scale(0.8);
   height: 28rpx;
   line-height: 32rpx;
   vertical-align: top;
 }

 .radio-group label text {
   font-size: 32rpx;
   height: 60rpx;
   line-height: 60rpx;
   vertical-align: top;
   display: inline-block;
 }

 .iconShape {
   color: #108EE9;
   font-size: 32rpx;
   margin-right: 10rpx;
 }

 .radio-group .yellow {
   background-color: #FCEBC7;
 }

 .radio-group .blue {
   background-color: #CCE9FF;
 }

 .unchose {
   display: none;
 }

 .chose-color {
   display: flex;
   justify-content: space-between;
   padding: 22rpx 32rpx;
   border-bottom: 1px solid #eeeeee;
   line-height: 60rpx;
   background-color: #fff;
 }

 .changeInfoName input {
   width: 100%;
   height: 100%;
   padding: 0;
 }

 .radio-group label radio {
   vertical-align: middle;
   transform: scale(0.8);
   height: 32rpx;
   line-height: 32rpx;
   vertical-align: top;
   margin-top: 8rpx;
 }

 .radio-group .gray {
   background-color: #eeeeee;
 }

 .radio-group .blue {
   background-color: #CCE9FF;
 }

 .card-num-con {
   display: flex;
   -webkit-box-pack: justify;
   justify-content: space-between;
   padding: 16rpx 32rpx 16rpx 0;
   margin-left: 32rpx;
   border-bottom: 1px solid rgb(238, 238, 238);
   line-height: 0.7rem;
   width: 90%;
   background-color: rgb(255, 255, 255);
 }

 .add-list-box {
   background-color: #ffffff;
 }

 icon {
   height: 40rpx;
   margin: 8rpx;
 }

 /* 键盘样式开始 */

 /* 键盘 */

 .down-blue {
   background-color: #108EE9!important;
   color: #ffffff!important;
 }

 .fl {
   float: left;
 }

 .am-input-content {
   overflow: hidden;
   white-space: nowrap;
   text-overflow: ellipsis;
   color: #333333;
   padding-left: 0;
   font-size: 34rpx;
 }

 .carnum {
   display: flex;
   width: 490rpx;
   height: 70rpx;
   background-repeat: repeat-x;
   background-size: auto 100%;
 }

 .carnum text {
   display: inline-block;
   width: 50rpx;
   margin-left: 20rpx;
   line-height: 70rpx;
   text-align: center;
   height: 70rpx;
   background-color: #f5f5f5;
 }

 .carnum text.carnum-blue {
   background-color: #E3F3FF;
 }

 .keyboard {
   position: fixed;
   width: 100%;
   height: 100%;
   bottom: 0;
   z-index: 99;
 }

 .keyboard-mini {
   position: fixed;
   bottom: 0;
   z-index: 100;
   background-color: #D8D8D8;
 }

 .tel {
   border-bottom: 2rpx solid #ddd;
   height: 100rpx;
   line-height: 100rpx;
 }

 .chepai {
   height: 200rpx;
   line-height: 200rpx;
 }

 .provinces {
   overflow: hidden;
   display: flex;
   flex-wrap: wrap;
   padding-top: 10rpx;
 }

 .pro-li {
   font-size: 32rpx;
   color: #353535;
   height: 76rpx;
   width: 62rpx;
   line-height: 76rpx;
   text-align: center;
   margin: 0 6rpx;
   margin-bottom: 20rpx;
   background-color: #fff;
   box-shadow: 0 1rpx 2rpx 0 #CCD2E3;
   border-radius: 5rpx;
   -webkit-box-flex: 1;
   flex: 1 1 8%;
 }

 .keyNums .pro-li:nth-child(30) {
   opacity: 0;
   width: 10rpx;
 }

 .keyNums .pro-li:nth-child(21) {
   margin-left: 37rpx;
 }

 .pro-close {
   width: 100rpx;
   height: 70rpx;
   line-height: 70rpx;
   font-size: 32rpx;
   text-align: center;
   background-color: #fff;
   border: 2rpx solid #ddd;
   margin: 5rpx;
 }

 .pro-del {
   width: 100rpx;
   height: 70rpx;
   line-height: 70rpx;
   font-size: 32rpx;
   text-align: center;
   background-color: #fff;
   border: 2rpx solid #ddd;
   margin: 5rpx;
 }

 .keyNums {
   overflow: hidden;
   padding-left: 4rpx;
   padding-top: 10rpx;
 }

 .pro-ok {
   width: 100rpx;
   height: 70rpx;
   line-height: 70rpx;
   font-size: 32rpx;
   text-align: center;
   background-color: #fff;
   border: 2rpx solid #ddd;
   margin: 5rpx;
 }

 .pro-d {
   width: 100rpx;
   height: 70rpx;
   line-height: 70rpx;
   font-size: 32rpx;
   text-align: center;
   background-color: #fff;
   border: 2rpx solid #ddd;
   margin: 5rpx;
 }

 .keyNums .bot .kb-del {
   margin-left: 12rpx
 }

 .keyNums .bot .kb-icon {
   width: 102rpx;
   height: 76rpx;
   background: #ccc
 }

 .news-swiper-box {
   height: 72rpx;
 }

 /* 键盘样式结束 */

JS文件(键盘模块不需要用到.json配置) keyboard.js.

Page({
  data: {
    notNum: true,
    vehicleColor: '1',
    strDisabled: false,
    checked: false,
    // 键盘
    provinceArr: ["粤", "京", "津", "渝", "沪", "冀", "晋", "辽", "吉", "黑", "苏", "浙", "皖", "闽", "赣", "鲁", "豫", "鄂", "湘", "琼", "川", "贵", "云", "陕", "甘", "青", "蒙", "桂", "宁", "新", "藏", "使", "领", "警", "学", "港", "澳"],
    strArr: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "A", "S", "D", "F", "G", "H", "J", "K", "L", "", "Z", "X", "C", "V", "B", "N", "M"],
    hiddenPro: true,// 隐藏省份键盘
    hiddenStr: true,// 隐藏数字字母键盘
    carnum: '', //车牌号码
    downBtn: '返回',
  },
  onLoad: function(options) {
    let _this = this;
    _this.setData({
      items: [
        { name: 'yellow', value: '黄色', checked: !this.data.checked, key: "1" },
        { name: 'blue', value: '蓝色', checked: this.data.checked, key: "0" }
      ],
    })
  },
  onPageScroll: function(e) {
    this.stopPropagation()//滑动页面隐藏键盘
  },
  stopPropagation() {//隐藏键盘方法
    this.setData({
      hiddenPro: true,
      hiddenStr: true,
    })
  },
  radioChange: function(e) {//切换车牌颜色
    let vehicleColorValue = e.detail.value;
    this.setData({
      checked: !this.data.checked,
      vehicleColor: vehicleColorValue
    })
    this.setData({
      items: [
        { name: 'yellow', value: '黄色', checked: !this.data.checked, key: "1" },
        { name: 'blue', value: '蓝色', checked: this.data.checked, key: "0" }
      ]
    })
  },

  // 键盘函数开始
  proTap(e) {//点击省份
    let that = this;
    let province = e.currentTarget.dataset.province;
    let carnum = this.data.carnum;
    if (carnum.length < 1) {//避免连续点击
      carnum += province;
    }
    this.setData({
      carnum: carnum,
      hiddenPro: true,
      hiddenStr: false,
    })
  },
  strTap(e) {//点击字母数字
    let that = this;
    this.setData({
      waiting: true
    })
    let province = e.currentTarget.dataset.str;
    let carnum = this.data.carnum;
    if (carnum.length < 7) {//避免连续点击
      carnum += province;
    }
    this.setData({
      notNum: false,
      carnum: carnum,
    })
    this.setData({
      notNum: false,
      carnum: carnum,
    })
    setTimeout(() => {
      that.setData({
        waiting: false
      })
    }, 100);
    if (carnum.length > 6) {
      this.setData({
        downBtn: '完成',
        strDisabled: true,
      })
      this.searchCardInfo()
      return;// 车牌长度最多为7个
    }
  },
  backSpace() {//退格
    this.setData({
      downBtn: '返回',
      strDisabled: false,
    })
    let carnum = this.data.carnum;
    var arr = carnum.split('');
    arr.splice(-1, 1)
    console.log(arr)
    var str = arr.join('')
    if (arr.length < 2) {
      this.setData({
        notNum: true
      })
    }
    if (str == '') {
      this.setData({
        hiddenPro: false,
        hiddenStr: true
      })
    }
    this.setData({
      carnum: str
    })
  },
  backKeyboard() {//返回省份键盘
    if (this.data.carnum.length > 6) {
      this.setData({
        downBtn: '完成',
        hiddenPro: true,
        hiddenStr: false
      })
    } else if (this.data.carnum.length > 0) {
      this.setData({
        hiddenPro: true,
        hiddenStr: false
      })
    } else {
      this.setData({
        hiddenPro: false,
        hiddenStr: true
      })
    }
  },
  applyNum() {
    this.setData({
      hiddenPro: true,
      hiddenStr: true,
    })
  }
  // 键盘函数结束
});

一个简单的车牌号自定义键盘就好了

可以根据自身需求做一定优化,有好的优化建议欢迎指教!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值