自定义多选组件

一.业务场景

选择用印公司时,需要选择多个公司,一个公司对应一个实际使用人

点击用印单位,弹出选择公司窗口,选择使用人,同时带上公司ID,点击确定按钮,将公司和使用人回显在用印单位上

二.上代码

wxml代码:

<view class="list">
      <view class="multiple">
        <view>
          <image slot="icon" class="icon" src="https://636c-cloud1-5gs8rk3873885f1e-1313217433.tcb.qcloud.la/InternalOffice/uyintong/home/1.2.0/useSealCompany.png?sign=f1579b5c5d469bba9543007030dde831&t=1720426665"></image>
        </view>
        <view>
          <view class="title">{{applyType==1?'用印单位':(applyType==2?'用盾单位':'用证单位')}}<text>(必填)</text></view>
          <view slot="label" class="lable">
            <view wx:if="{{item.useSealCompanyList==null}}">{{applyType==1?'请选择用印单位':(applyType==2?'请选择用盾单位':'请选择用证单位')}}</view>
            <view wx:for="{{item.useSealCompanyList}}">
              <view class="company">
                <view>{{item.useSealCompany}}-{{item.actualUser}}</view>
                <view bind:tap="deleteCompany" data-company="{{item.useSealCompanyId}}" class="delete"><van-icon name="close"/></view>
              </view>
            </view>
          </view>
        </view>
        <view bind:tap="openShowPopup0" data-index="{{index}}" class="arrow"><van-icon name="arrow" color="#999999"/></view>
      </view>
      <view class="line"></view>
    </view>

<!-- 用印单位列表弹框 -->
<van-popup custom-class="yongyindanweilistpage" show="{{ showYongyinDanwei0 }}" position="left" custom-style="height:100%;width:100%">
  <view class="searchbar">
    <view class="search">
      <van-search
        value="{{ value }}"
        placeholder="请输入搜索关键词"
        show-action
        bind:change="yongyindanweitopSearchFun"
        bind:cancel="onClickLeftYongyinDanwei0"
      />
    </view>
    <view bind:tap="confirmCompany" class="btn">确定</view>
  </view>
  <view class="Oul" wx:if="{{cities.length!=0}}">
    <van-checkbox-group value="{{ objlist[currentIndex].useSealCompany }}">
      <van-cell-group>
        <view class="cityList" wx:for="{{cities}}" wx:key="index">
          <view class="letter" wx:if="{{item.list.length!=0}}">{{item.key}}</view>
          <view wx:for="{{item.list}}" wx:key="index1">
            <view class="company">
              <view class="name">{{item.companyName}}</view>
              <view data-select="{{ item }}" bind:tap="selectCity">
                <van-icon name="arrow-up" wx:if="{{item.showUp == null ? true : item.showUp}}"/>
                <van-icon name="arrow-down" wx:if="{{item.showDown || false}}"  bind:tap="hideDown"/>
              </view>
            </view>
            <view wx:if="{{item.check}}" class="text">
              <van-radio-group value="{{ item.selectUser }}" bind:change="userChange">
                <view wx:for="{{users}}">
                  <van-radio name="{{item.realName}}" custom-class="radio1">{{item.realName}}</van-radio>
                </view>
              </van-radio-group>
            </view>
          </view>
        </view>
      </van-cell-group>
    </van-checkbox-group>
  </view>
  <view class="isnonebox" wx:else>
    <view class="custom-text">用印单位列表为空</view>
  </view>
</van-popup>

scss代码:

.list {
    position: relative;
    .line {
      width: 688rpx;
      height: 0.5rpx;
      background: #f4f5f7;
      margin-left: 32rpx;
      margin-top: 12rpx;
    }
    .multiple {
      display: flex;
      padding-left: 31rpx;
      padding-top: 20rpx;
      .arrow {
        margin-left: auto;
        padding-right: 34rpx;
      }
      .title {
        font-weight: bold;
        font-size: 30rpx;
        color: #4D4D4D;
        text {
          color: #FE2B27;
          font-size: 12px;
        }
      }
      .lable {
        font-weight: 400;
        font-size: 26rpx;
        color: #999999;
        .company {
          display: flex;
          width: 100%;
          .delete {
            margin-left: auto;
            padding-left: 91rpx;
          }
        }
      }
    }
}


.yongyindanweilistpage {
  .searchbar {
    padding-right: 20rpx;
    display: flex;
    .search {
      width: 90%;
    }
    .btn {
      padding-top: 8rpx;
      width: 104rpx;
      height: 37rpx;
      border-radius: 22rpx 22rpx 22rpx 22rpx;
      background: #E9F1FF;
      border: 1rpx solid #659EFF;
      font-weight: 400;
      font-size: 27rpx;
      color: #659EFF;
      line-height: 32rpx;
      text-align: center;
      margin-top: 29rpx;
    }
  }
  .Oul {
    .cityList {
      .letter {
        padding: 0 16px;
        height: 20px;
        background: #F4F4F4;
        font-size: 12px;
        font-weight: 400;
        color: #C9C9C9;
        line-height: 20px;
      }
      .company {
        display: flex;
        padding-left:26rpx;
        .name {
          width: 91%;
          font-weight: 400;
          font-size: 28rpx;
          color: #333333;
          height: 73rpx;
          line-height: 66rpx;
        }
      }
      .text {
        font-weight: 400;
        font-size: 24rpx;
        color: #333333;
        padding-left:26rpx;
        .radio1 {
          padding-top:10rpx;
        }
      }

    }

  }

  .isnonebox {
    margin-top: 110px;

    .custom-image {
      width: 225px;
      height: 185px;
      display: block;
      margin: 0 auto;
    }

    .custom-text {
      font-size: 14px;
      font-family: PingFang SC;
      font-weight: 400;
      line-height: 18px;
      color: #BABFC9;
      text-align: center;
      margin-top: -42px;
    }
  }
}

js代码:

Page({
data: {
    //用印单位
    yongyindanweiSearchValue: '',
    useSealCompanyId: 0,
    useSealCompany: "",
    useSealCompanyList:[],
    //印章实际使用人
    actualUser: 0,
    // 当前选中卡片
    currentIndex: "",
    showYongyinDanwei0: false,
    // 以字母形式排列
    cities: [], 
    showActualUser: false,
    users:[],
    objlist: [],
    showUp: true,
    showDown: false
  },
  deleteCompany(event) {
    let that = this
    let companyId = event.currentTarget.dataset.company;
    that.data.cities.forEach(function (item, index) {
      item.list.forEach(function (sub, index) {
        if(that.data.useSealCompanyId == sub.id) {
          sub.selectUser = 0
        }
      })
    })
    that.setData({
      cities: that.data.cities,
    })
    let map = new Map();
    for(let item of that.data.useSealCompanyList) {
      map.set(item.useSealCompanyId,item);
    }
    map.delete(companyId)
    that.conventMapToArray(map)
    console.log("useSealCompanyList:",that.data.useSealCompanyList)
  },
  conventMapToArray(map) {
    let that = this
    const array = Array.from(map.values());
    console.log("array:",array)
    let up = "objlist["+this.data.currentIndex+"].useSealCompanyList";
    that.setData({
      [up]: array,
      useSealCompanyList: array
    })
  },
  confirmCompany() {
    let that = this
    console.log("useSealCompanyList:",that.data.useSealCompanyList)
    let map = new Map();
    for(let item of that.data.useSealCompanyList) {
      map.set(item.useSealCompanyId,item);
    }
    that.conventMapToArray(map)
    that.setData({
      showYongyinDanwei0: false,
    });
    // console.log("useSealCompanyList:",that.data.useSealCompanyList)
    // 显示父页面后退按钮和tab栏
    that.triggerEvent('hideLeftArrow',{leftArrow:true})
  },
  userChange(event) {
    let that = this
    let selectUser = event.detail
    that.data.cities.forEach(function (item, index) {
      item.list.forEach(function (sub, index) {
        if(that.data.useSealCompanyId == sub.id) {
          sub.selectUser = selectUser
        }
      })
    })
    that.setData({
      cities: that.data.cities,
      actualUser: selectUser
    })
    if(that.data.actualUser != 0) {
      let obj = {"useSealCompanyId": that.data.useSealCompanyId,"actualUser": that.data.actualUser,"useSealCompany": that.data.useSealCompany}
      that.data.useSealCompanyList.push(obj)
      that.setData({
        useSealCompanyList: that.data.useSealCompanyList
      })
      // console.log("useSealCompanyList:",that.data.useSealCompanyList)
    }
  },
  selectCity(event) {
    const {
      select
    } = event.currentTarget.dataset;
    console.log("select:",select)
    this.data.cities.forEach(function (item, index) {
      item.list.forEach(function (sub, index) {
        if(select.id == sub.id) {
          sub.check = !sub.check
          sub.showDown = !sub.showDown
          sub.showUp = !sub.showDown
          console.log("down:",sub.showDown)
          console.log("up:",sub.showUp)
        }
      })
    })
    this.setData({
      cities: this.data.cities,
      useSealCompanyId: select.id,
      useSealCompany: select.companyName
    })
    // console.log("cities:",this.data.cities)
  },

三.思路

1.弹窗就不用说了,show为true或false的区别

2.selectCity:点击view,通过data-select="{{ item }}"把当前点击的公司传给js,js通过

const {

      select

    } = event.currentTarget.dataset;

来接收,然后给item.check,item.showDown,item.showUp赋值,check是用来控制使用人列表的显示和隐藏。showDown和showUp用来控制公司右边的图标变化

3.userChange:遍历公司,判断当前公司被选择,给item.selectUser赋值,selectUser用来回显页面单选框的选择效果。并且给actualUser赋值,把actualUser,useSealCompanyId,和useSealCompany组合成一个对象,塞进useSealCompanyList数组里面。useSealCompanyList数组就是要传给后端代码的参数

4.confirmCompany:点击确定时触发这个事件,一方面用来隐藏弹出框,另一方面在这个方法里对useSealCompanyList做一个去重,以useSealCompanyId为key去重

5.deleteCompany:删除选错的公司

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值