小程序里实现放在页面里的行选择日历

在日常需求里面,会碰到各式各样的需求,比如这样,需要把行选择日历放在页面里面,如下图:

可以切换选择按月选择,按时间段选择日期。按时间段选择日期里面,可以选择开始日期和结束日期。选择完毕后,将值传到上一个页面。

把值传到上一页的方法有两种:

1. 直接把数据缓存在本地,然后在上一页(目标页)直接去缓存就行。

2. 用getCurrentPages()获取当前的页面栈,一数组形式返回。示例代码如下:

// 当前所有页面栈
const pages = getCurrentPages()
// 上一页对象
const prevPage = pages[pages.length - 2]
// 直接给上一页data.prevPage赋值
prevPage.data.name = 'your value'

下面是实现代码:

视图层代码:fileName.wxml

<view class='container'>
  <view class='flex-row'>
    <view class="full-width rounded-20 text-center badge-brd badge-brd-lg {{datetype==0?'badge-brd-theme bg-light-theme':'bg-f3'}}" data-type='0' bindtap='switchTab'>按月选择</view>
    <view class="full-width rounded-20 text-center ml-10 badge-brd badge-brd-lg {{datetype==1?'badge-brd-theme bg-light-theme':'bg-f3'}}" data-type='1' bindtap='switchTab'>按时间段筛选</view>
  </view>
  <!-- 按月选择 -->
  <view class='mt-30' hidden='{{datetype!=0}}'>
    <view class='content border-bottom mb-15'>
      <input class='full-width text-center' placeholder='请选择月份' value='{{chooseMonthDate}}' disabled='true'></input>
    </view>
    <picker-view indicator-style="height: 50px;" style="width: 100%; height: 200px;" value="{{monthDateValue}}" indicator-class='monthPicker' bindchange="monthFilter">
      <picker-view-column>
        <view wx:for="{{dateObj.years}}" wx:key='' class='text-center' style="line-height: 50px">{{item}}年</view>
      </picker-view-column>
      <picker-view-column>
        <view wx:for="{{dateObj.months}}" wx:key='' class='text-center' style="line-height: 50px">{{item}}月</view>
      </picker-view-column>
      <!-- <picker-view-column>
        <view wx:for="{{days}}" class='text-center' style="line-height: 50px">{{item}}日</view>
      </picker-view-column> -->
    </picker-view>
  </view>
   
  <!-- 按时间段筛选 -->
  <view class='mt-30' hidden='{{datetype!=1}}'>
    <view class='flexRowCen mb-15'>
      <view class='content {{active==0?"border-bottom-theme":"border-bottom"}} full-width' bindtap='startOrEnd' data-type='0'>
        <input class='full-width text-center {{active==0?"color-theme":""}}' placeholder='请选择开始时间' value='{{startDate}}' disabled='true'></input>
      </view>
      <view class='no-shrink p-x-15'>至</view>
      <view class='content {{active==1?"border-bottom-theme":"border-bottom"}} full-width' bindtap='startOrEnd' data-type='1' >
        <input class='full-width text-center {{active==1?"color-theme":""}}' placeholder='请选择结束时间' value='{{endDate}}' disabled='true'></input>
      </view>
    </view>
    
    <picker-view indicator-style="height: 50px;" style="width: 100%; height: 200px;" value="{{durationDateValue}}" indicator-class='monthPicker' bindchange="durationFilter">
      <picker-view-column>
        <view wx:for="{{dateObj.years}}" wx:key='' class='text-center' style="line-height: 50px">{{item}}年</view>
      </picker-view-column>
      <picker-view-column>
        <view wx:for="{{dateObj.months}}" wx:key='' class='text-center' style="line-height: 50px">{{item}}月</view>
      </picker-view-column>
      <picker-view-column>
        <view wx:for="{{dateObj.days[durationDateValue[0]][durationDateValue[1]]}}" wx:key='' class='text-center' style="line-height: 50px">{{item}}日</view>
      </picker-view-column>
    </picker-view>
  </view>
</view>

<view class='fixed-bottom flex-row full-width bg-white box-sha-sm'>
  <navigator class='btn btn-gradient-orange half-width rounded-0 font-size-15' open-type='navigateBack'>返回</navigator>
  <view class='btn btn-theme full-width rounded-0 font-size-15' bindtap='doFilter'>确定</view>
</view>

样式文件:fileName.wxss

.monthPicker{
  position: relative;
}
.monthPicker::before,
.monthPicker::after{
  content: '';
  display: block;
  position: absolute;
  width: 140rpx;
  height: 4rpx;
  background: #ff5959;
  top: 0;
  left: 50%;
  transform: translate(-50%);
  border-radius: 50%;
}
.monthPicker::after{
  top: unset;
  bottom: 0;
}
.border-bottom-theme{
  border-bottom: 1px solid #ff5959;
}

逻辑层代码:fileName.js

var util = require('../../../../utils/util.js')
var date = require('../../../../utils/date.js')
const startYear = 2016  // datepicker的起始年份
const nowData = new Date()
const nowYear = nowData.getFullYear()
const nowMonth = nowData.getMonth() + 1
const nowDay = nowData.getDate()
var dateObj = date.pickerDate(startYear, nowYear, nowMonth, nowDay)
Page({

  /**
   * 页面的初始数据
   */
  data: {
    datetype: 0,   //日期筛选类型,0-按月,1-按时间段
    // year: date.getFullYear(),
    dateObj: dateObj,
    //初始化按月选择的年月
    monthDateValue: [nowYear - startYear, nowMonth-1],
    //初始化按月选择的日期
    chooseMonthDate: util.getNowDate('monthDate'),
    //初始化按月选择-开始日期:当月第一天
    month_startDate: util.getNowDate('monthDate') + '-01',
    //初始化按月选择-开始日期:今天
    month_endDate: util.getNowDate(),
    //初始化按时间段选择的年月日
    durationDateValue: [nowYear-startYear, nowMonth-1, nowDay-1],
    // 按时间段选择-初始化开始日期
    startDate: util.getNowDate(),
    // 按时间段选择-初始化结束日期
    endDate: util.getNowDate(),
    //开始日期-结束日期
    active: 0,
  },

  // 切换日期筛选类型
  switchTab: function (e) {
    console.log(e)
    if (e.currentTarget.dataset.type != this.data.datetype) {
      this.setData({
        datetype: e.currentTarget.dataset.type
      })
    }
  },

  // 按月份筛选
  monthFilter: function (e) { 
    const val = e.detail.value
    this.setData({
      chooseMonthDate: this.data.dateObj.years[val[0]] + '-' + util.formatDateAdd0(this.data.dateObj.months[val[1]])
    })
    this.data.month_startDate = this.data.dateObj.years[val[0]] + '-' + util.formatDateAdd0(this.data.dateObj.months[val[1]]) + '-01'
    this.data.month_endDate = this.data.dateObj.years[val[0]] + '-' + util.formatDateAdd0(this.data.dateObj.months[val[1]]) + '-' + util.formatDateAdd0(this.data.dateObj.days[val[0]][val[1]].slice(-1)[0])
  },

  // 按时间段筛选
  durationFilter: function(e){ 
    const val = e.detail.value
    if(this.data.active==0){
      console.log()
      this.setData({
        startDate: this.data.dateObj.years[val[0]] + '-' + util.formatDateAdd0(this.data.dateObj.months[val[1]]) + '-' + util.formatDateAdd0(this.data.dateObj.days[val[0]][val[1]][val[2]]),
        startValue: val,
        durationDateValue: val
      })
    }else{
      this.setData({
        endDate: this.data.dateObj.years[val[0]] + '-' + util.formatDateAdd0(this.data.dateObj.months[val[1]]) + '-' + util.formatDateAdd0(this.data.dateObj.days[val[0]][val[1]][val[2]]),
        endValue: val,
        durationDateValue: val
      })
    }
    
  },

  // 选中开始时间或结束时间
  startOrEnd: function(e){
    if (this.data.active!=e.currentTarget.dataset.type){
      if (e.currentTarget.dataset.type == 0) {
        this.data.durationDateValue = this.data.startValue || this.data.durationDateValue
      }else{
        this.data.durationDateValue = this.data.endValue || this.data.durationDateValue
      }
      this.setData({
        active: e.currentTarget.dataset.type,
        durationDateValue: this.data.durationDateValue
      })
    }
  },


  // 确定筛选并返回
  doFilter: function(){
    if (this.data.datetype==0){
      if (this.data.chooseMonthDate){
        this.data.prevPage.data.chooseDate = { 
          chooseMonthDate: this.data.chooseMonthDate,
          startCreateTime: this.data.month_startDate,
          endCreateTime: this.data.month_endDate
        }
        this.data.prevPage.data.fromDateChoose = true
        this.data.prevPage.data.keyWord ? delete this.data.prevPage.data.keyWord:''
        wx.navigateBack({
          delta: -1
        })
      }else{
        util.showFailToast({title: '请正确选择日期'})
      }
    }else{
      if (this.data.startDate && this.data.endDate){
        this.data.prevPage.data.chooseDate = { startCreateTime: this.data.startDate, endCreateTime: this.data.endDate}
        wx.navigateBack({
          delta: -1
        })
      }else{
        util.showFailToast({ title: '请正确选择日期' })
      }
    }
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.data.pages = getCurrentPages()
    this.data.prevPage = this.data.pages[this.data.pages.length - 2]
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  // onShareAppMessage: function () {

  // }
})

在date.js文件里生成日历数据,引入的date.js

// picker-view日历数据
const pickerDate=(startYear = 2015, endYear = (new Date()).getFullYear())=>{
  /**日历数据**/
  // const date = new Date()
  const years = []
  const months = []
  const days = []
  // dateObj = {year: [2015, 2016,..], month: [1, 2, 3, 4...], day: [[1,2,3...31],[1,2,3...28]] }
  const dateObj = {}

  for (let i = startYear; i <= endYear; i++) {
    years.push(i)
    days[i - startYear] = []
    var month_days = [31, 28 + isLeapYear(i), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    month_days.forEach((item, index) => {
      var daysArr = []
      for (var j = 1; j <= item; j++) {
        daysArr.push(j)
      }
      days[i - startYear].push(daysArr)
    })
  }

  for (let i = 1; i <= 12; i++) {
    months.push(i)
  }
  dateObj.years = years
  dateObj.months = months
  dateObj.days = days

  console.log(dateObj)
  return dateObj
}

//判断是否闰年 
const isLeapYear=(Year)=> {
  if (((Year % 4) == 0) && ((Year % 100) != 0) || ((Year % 400) == 0)) {
    return (true);
  } else { return (false); }
}

data.js中输出的日历数据格式如下图:

 

大家可以根据输出的日历数据格式,灵活运用。程序小白,分享这点代码给大家,多多指教!希望对大家有用。

后续考虑把这个封装成组件,更方便使用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值