我的自定义日历

这是 CalendarDate.js

import React, { useState, useEffect, useRef } from 'react'
import { Icon } from 'antd'
import './CalendarMore.css'
import './CalendarDate.css'
import { getMonth, weekArr } from './canlendarConfig'
import moment from 'moment'
function CalendarDate(props) {
    console.log('props', props);
    const [selectedValue, setSelectedValue] = useState([])//选中的值
    const [canSelectedList, setCanSelectedList] = useState([])//可选数组
    const [isShow, setIsShow] = useState(true)//日历组件是否显示
    const { list = [], onChange, } = props
    const calendarDiv = useRef(null);
    //设计默认值
    useEffect(() => {
        setSelectedValue(props.value || [])
        setCanSelectedList(list.map(one => one.code))
        document.addEventListener('click', outDivClickHandler);
        return () => {
            document.removeEventListener('click', outDivClickHandler);
        }
    }, [])
    function setSelectedValueChange(value) {
        setSelectedValue(value)
        onChange && onChange(value)
    }
    function outDivClickHandler(e) {
        let result = (calendarDiv.current).contains(e.target);
        if (!result) {
            setIsShow(false)
        }
    }
    return (
        
{selectedValue.length > 0 ? selectedValue.map(one =>
{one} setSelectedValueChange(selectedValue.filter(item => item != one))} />
) : 请选择日期}
setIsShow(!isShow)}>
{isShow ? : null}
) } function CalendarDays(props) { const nowDate = moment().format('YYYY-M').split('-') const [yearNumber, setYearNumber] = useState(nowDate[0]) const [monthNumber, setMonthNumber] = useState(nowDate[1]) const { selectedValue = [], canSelectedList = [], setSelectedValue } = props console.log('canSelectedList', canSelectedList) function changeDays(value, isSelected) { if (isSelected) { setSelectedValue(selectedValue.filter(one => one != value)) } else { setSelectedValue([...selectedValue, value]) } } const daysList = getMonth(yearNumber, monthNumber) function changAddNumber() { let number = Number(monthNumber) + 1 if (number == 13) { number = 1 setYearNumber(Number(yearNumber) + 1) } setMonthNumber(number) } function changLessMonth() { let number = Number(monthNumber) - 1 if (number == 0) { number = 12 setYearNumber(Number(yearNumber) - 1) } setMonthNumber(number) } return
setYearNumber((Number(yearNumber) - 1))} />
{yearNumber}年{monthNumber}月
setYearNumber(Number(yearNumber) + 1)} />
{weekArr.map(one =>
{one}
)} {daysList.map(one => { const nowValue = moment(one.date).format('YYYYMMDD') const isSelected = selectedValue.includes(nowValue) return
changeDays(nowValue, isSelected)} className={`common-days ${one.type == 'now' ? 'now-days' : 'other-days'} ${isSelected ? ' common-days-active' : ''}`} key={`${one.type}-${one.value}`}> {one.value}
})}
} export default CalendarDate

这是CalenDarDate.css

.calendar-days{
  position: absolute;
  border: 1px solid rgba(0, 0, 0, 0.15) ;
}
.calendar-days-content{
  display: flex;
  flex-wrap: wrap;
}
.other-days,.now-days{
  width:calc(100% / 7);
  text-align: center;
}
.other-days{
  color: #999;
}
.now-days{
  color: #000;
}
.common-days-active{
  background-color: #7300FF;
  color:#fff;
}
.common-days:hover{
  background-color: #efe6f5;
}
.days-width{
  min-width: 86px;
}

这是calendarConfig.js

import moment from 'moment'
export const weekArr = ['一', '二', '三', '四', '五', '六', '七']
export const getMonth = (year, month) => {
    const date = `${year}-${month}`
    const lastArr = getLastDays(date)
    const nowMonthDays = moment(date).endOf('month').format('YYYY-MM-DD').split('-')[2]
    const size = 42 - nowMonthDays - lastArr.length
    let nextStr = moment(date).add(1, 'month').format('YYYY-MM')
    const nowArr = getDays(nowMonthDays, 'now', date)
    const nextArr = getDays(size, 'next', nextStr)
    console.log('data', date, lastArr, nowMonthDays, nextArr, nextStr);


    return [...lastArr, ...nowArr, ...nextArr]
}
//获取上个月的日期参数
const getLastDays = (date) => {
    const start = moment(date).startOf('week').format('YYYY-MM-DD')
    const end = moment(start).endOf('month').format('YYYY-MM-DD')
    console.log('start', start, end, date);
    if (start == moment(date).format('YYYY-MM-DD')) {
        return []
    }
    return getDateArr(start, end)
}
//获取size长度的数组
const getDays = (size, type, str) => {
    const data = []
    for (let i = 0; i < size; i++) {
        data.push({ value: i + 1, type: type, date: `${str}-${i + 1}` })
    }
    return data
}
//获取上个月的数组
const getDateArr = (start, end) => {
    const min = start.split('-')
    let str = `${min[0]}-${min[1]}`
    const max = end.split('-')[2]
    let data = []
    console.log('min',min, max);
    for (let i = 0; i < max - min[2]; i++) {
        const value = Number(min[2]) + i + 1
        data.push({ value: value, type: 'last', date: `${str}-${value}` })
    }
    return data
}

// const adasd = {
//     "name": "@param_age",
//     "title": "年龄",
//     "stype": 0,
//     "values": [
//         {
//             "name": "19-24岁",
//             "code": "5"
//         }, {
//             "name": "25-29岁",
//             "code": "1"
//         }
//     ]
// }


// function getAgeValue(data = {}) {
//     let { values = [] } = data
//     console.log("getAgeValue -> values", values)
//     let str = ''
//     if (values.length > 0) {
//         const firstValue = values[0].name.split('-')
//         let start = firstValue[0]
//         let end = firstValue[1].replace('岁', '')
//         if (values.length > 1) {
//             const endValue = values[values.length - 1].name.split('-')
//             end = endValue[1].replace('岁', '')
//         }
//         str = `${start}-${end}`
//     }
//     return str
// }

这是CalendarMore.js

import React, { useState, useEffect, useRef } from 'react'
import { Icon } from 'antd'
import moment from 'moment'
import './CalendarMore.css'

function CalendarMore(props) {
    const [selectedValue, setSelectedValue] = useState([])//选中的值
    const [canSelectedList, setCanSelectedList] = useState([])//可选数组
    const [isShow, setIsShow] = useState(false)//日历组件是否显示
    const { list = [], onChange } = props
    const calendarDiv = useRef(null);
    //设计默认值
    useEffect(() => {
        setSelectedValue(props.value || [])
        setCanSelectedList(list.map(one => one.code))
        document.addEventListener('click', outDivClickHandler);
        return () => {
            document.removeEventListener('click', outDivClickHandler);
        }
    }, [])
    function setSelectedValueChange(value) {
        setSelectedValue(value)
        onChange && onChange(value)
    }
    function outDivClickHandler(e) {
        let result = (calendarDiv.current).contains(e.target);
        if (!result) {
            setIsShow(false)
        }
    }
    return (
        
{selectedValue.length > 0 ? selectedValue.map(one =>
{one} setSelectedValueChange(selectedValue.filter(item => item != one))} />
) : 请选择日期}
setIsShow(!isShow)}>
{isShow ? : null}
) } function CalendarMonth(props) { const [yearNumber, setYearNumber] = useState(moment().year()) const { selectedValue = [], canSelectedList = [], setSelectedValue } = props const monthArr = [ { name: 1, value: '01' }, { name: 2, value: '02' }, { name: 3, value: '03' }, { name: 4, value: '04' }, { name: 5, value: '05' }, { name: 6, value: '06' }, { name: 7, value: '07' }, { name: 8, value: '08' }, { name: 9, value: '09' }, { name: 10, value: '10' }, { name: 11, value: '11' }, { name: 12, value: '12' }, ] function selectedMonth(value, isSelected) { if (isSelected) { setSelectedValue(selectedValue.filter(one => one != value)) } else { setSelectedValue([...selectedValue, value]) } } return
setYearNumber(yearNumber - 1)} />
{yearNumber}年
setYearNumber(yearNumber + 1)} />
{monthArr.map(one => { const value = `${yearNumber}${one.value}` const isCanSelected = canSelectedList.includes(value) const isSelected = selectedValue.includes(value) return isCanSelected ?
selectedMonth(value, isSelected)}>{one.name}月
:
{one.name}月
})}
} export default CalendarMore

这是CalendarMore.css

.calendar-more{
  border:1px solid #DADADA;
  height: 30px;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  font-variant: tabular-nums;
  list-style: none;
  -webkit-font-feature-settings: 'tnum';
  font-feature-settings: 'tnum', "tnum";
  position: relative;
  display: inline-block;
  width:100%;
  height: 32px;
  padding: 4px 11px;
  color: rgba(0, 0, 0, 0.65);
  font-size: 14px;
  line-height: 1.5;
  background-color: #fff;
  background-image: none;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  -webkit-transition: all 0.3s;
  transition: all 0.3s;
}
.show-box{
  display: flex;
  width: 100%;
  justify-content: space-between;
}
.selected-show{
  width: calc(100% - 30px);
  display: flex;
  overflow-x: auto;
}
.icon-calendar{
  width: 20px;
}
.calendar-month{
  position: relative;
}
.calendar-content{
  position: fixed;
  z-index: 99999;
  width:300px;
  height:205px;
  background:rgba(255,255,255,1);
  box-shadow:0px 0px 6px 0px rgba(0,0,0,0.15);
  border-radius:3px;
}
.year-number{
  font-size:12px;
  font-family:SourceHanSansCN-Regular,SourceHanSansCN;
  font-weight:400;
  color:rgba(40,40,40,0.85);

}
.calendar-title{
  font-size:12px;
  font-family:SourceHanSansCN-Regular,SourceHanSansCN;
  display: flex;
  height: 36px;
  justify-content: space-between;
  border-bottom: 1px solid rgba(0, 0, 0, 0.15) ;
  padding: 0px 10px;
}
.month-show{
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
  font-size: 12px;
}
.selected-show::-webkit-scrollbar {
  width: 3px;
  height: 3px;
}

/* Track */

.selected-show::-webkit-scrollbar-track {
  -webkit-box-shadow: none;
  border-radius: 0;
  background-color: transparent;
}

/* Handle */

.selected-show::-webkit-scrollbar-thumb {
  width: 2px !important;
  height: 6px !important;
  border-radius: 4px;
  background: rgba(111, 33, 212, 0.8);
  -webkit-box-shadow: inset 0 0 6px rgba(103, 82, 197, 0.3);
}

.selected-item{
  background: #F5f5f5;
  display: flex;
  align-items: center;
  color: #000;
  padding: 2px 5px;
  font-size: 12px;
  margin:0px 2px;
  min-width: 50px;
}
.month-box{
  width: 32px;
  height: 32px;
  margin: 5px calc((100% - 32*3px) /6);
  text-align: center;
  border-radius: 50%;
  line-height: 32px;
  -webkit-transition: all 0.3s;
  transition: all 0.3s;
}
.month-box:hover{
  background-color: #efe6f5;
}
.month-box-active{
  background-color: #7300FF;
  color:#fff;
}
.month-box-disable{
  cursor:not-allowed;
  background-color: #ccc;
}
.month-box-disable:hover{
  cursor:not-allowed;
  background-color: #ccc;
}

这是index.js

import React, { useEffect, useState } from 'react'
import { Form, Button, Input } from 'antd'
import CalendarMore from './CalendarMore'
import CalendarDate from './CalendarDate'
const data = [
    {
        "code": "202002",
        "name": "202002"
    },
    {
        "code": "201902",
        "name": "201902"
    },
    {
        "code": "202003",
        "name": "202003"
    },
    {
        "code": "201905",
        "name": "201905"
    },
    {
        "code": "201803",
        "name": "201803"
    },
    {
        "code": "202005",
        "name": "202005"
    }
]
function TestForm(props) {
    const [date, setDate] = useState([])
    function submit(e) {
        e.preventDefault();
        props.form.validateFields((err, values) => {
            if (!err) {
                console.log('Received values of form: ', values);
            }
        });
    }
    useEffect(() => {
        setTimeout(() => {
            yarn(["202003", "202002"])
        }, 2000);
    }, [])
    const { getFieldDecorator, getFieldsError, getFieldError, isFieldTouched } = props.form;
    return (
        
{/* {getFieldDecorator('@param_month', { initialValue: date, rules: [{ required: true, message: 'Please input your Password!' }], })( )} */} {getFieldDecorator('@param_month23', { initialValue: ["20200322", "20200212"], rules: [{ required: true, message: 'Please input your Password!' }], })( )}
) } const WrappedHorizontalLoginForm = Form.create('asd')(TestForm); export default WrappedHorizontalLoginForm

你可能感兴趣的:(javascript)