最近公司项目有地方用到平铺的时间选择组件,并且只能选择当天之后的时间,还要能切换月份,寻思antd都是下拉弹出框的datepicker,没有想要的效果,于是就自己写了,分享给大家。
先看效果(这个只是demo,样式无视):
紫色的代表当天以后的时间,运用的时候可以在事件函数回调中再判断下是否所选时间大于当天时间;点击prev/next按钮切换月份,当12月时next后自动切为下一年,1月时prev后自动切为上一年;(很懒,没写注释,能提升大家阅码能力也不错哈///(●'◡'●))
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<style>
table {
width: 300px;
border-collapse: collapse;
}
th, td {
text-align: center;
border: 1px solid green;
}
.isValid {
background: purple;
}
</style>
<body>
<div>
<button class="prev">prev</button> <button class="next">next</button> <span class="label"></span>
</div>
<table class="table">
<thead>
<th>日</th>
<th>一</th>
<th>二</th>
<th>三</th>
<th>四</th>
<th>五</th>
<th>六</th>
</thead>
<tbody class="tbody">
</tbody>
</table>
<script>
class InterviewDate {
state = {
cDate: new Date()
}
getCurrYear() {
return this.state.cDate.getFullYear()
}
getCurrMounth() {
return this.state.cDate.getMonth() + 1
}
getCurrWeek() {
return this.state.cDate.getDay()
}
getMounthDays(mounth) {
return new Date(this.getCurrYear(), mounth || this.getCurrMounth(), 0).getDate()
}
onTdClick = (e) => {
let d = e.target.innerText, m = this.getCurrMounth()+'', y = this.getCurrYear()
d = d.length == 1 ? 0 + d : d
m = m.length == 1 ? 0 + m : m
console.log(y + '/' + m + '/' + d)
}
render() {
let y = this.getCurrYear(), m = this.getCurrMounth()
let str = ''
let mounthStartWeek = new Date(y, m - 1, 1).getDay()
while (mounthStartWeek > 0) {
str += '<td></td>'
--mounthStartWeek
}
let tr = $('<tr></tr>').html(str)
for (let j = 1; j <= this.getMounthDays(); j++) {
let td = $('<td></td>')
if (new Date(y, m - 1, j, 24).getTime() >= new Date().getTime()) {
td.addClass('isValid')
}
td.text(j)
td.on('click', this.onTdClick)
tr.append(td)
if (tr.find('td').length == 7) {
$(".tbody").append(tr)
tr = $('<tr></tr>')
}
}
if (tr.find('td').length) $(".tbody").append(tr)
}
next() {
this.state.cDate = new Date(this.getCurrYear(), this.getCurrMounth())
$(".tbody").text('')
this.render()
}
prev() {
this.state.cDate = new Date(this.getCurrYear(), this.getCurrMounth() - 2)
$(".tbody").text('')
this.render()
}
}
let obj = new InterviewDate()
obj.render()
$('.label').text(obj.getCurrYear() + '年' + obj.getCurrMounth() + '月')
$('.prev').on('click', () => {
obj.prev()
$('.label').text(obj.getCurrYear() + '年' + obj.getCurrMounth() + '月')
})
$('.next').on('click', () => {
obj.next()
$('.label').text(obj.getCurrYear() + '年' + obj.getCurrMounth() + '月')
})
</script>
</body>
</html>
react版
import {Component} from 'react'
import {Icon} from 'antd'
import styles from './index.less'
export default class RepeatPicker extends Component {
state = {
cDate: new Date(),
active: new Date()
}
getCurrYear() {
return this.state.cDate.getFullYear()
}
getCurrMounth() {
return this.state.cDate.getMonth() + 1
}
getCurrWeek() {
return this.state.cDate.getDay()
}
getMounthDays(mounth) {
return new Date(this.getCurrYear(), mounth || this.getCurrMounth(), 0).getDate()
}
onTdClick = (e) => {
let d = e.target.innerText, m = this.getCurrMounth()+'', y = this.getCurrYear()
d = d.length == 1 ? 0 + d : d
m = m.length == 1 ? 0 + m : m
let active = y + '/' + m + '/' + d
console.log(active)
this.setState({active: new Date(active)}, ()=>{
this.props.onChange(active)
})
}
renderTD() {
let y = this.getCurrYear(), m = this.getCurrMounth()
let result = [], trIdx = 0, gKey = 0
let mounthStartWeek = new Date(y, m - 1, 1).getDay()
result[trIdx] = []
while (mounthStartWeek > 0) {
result[trIdx].push(<td key={gKey}></td>)
--mounthStartWeek
++gKey
}
for (let j = 1; j <= this.getMounthDays(); j++) {
++gKey
let getclass = ()=>{
let re = ''
let class1 = new Date(y, m - 1, j, 24).getTime() >= new Date().getTime() ? styles.isValid : null
if(class1){
if(this.getCurrMounth() == new Date().getMonth()+1 && this.state.active.getDate() == j){
re = class1 + ' ' + styles.active
}else{
re = class1
}
}
return re
}
let td = <td className={getclass()} onClick={this.onTdClick} key={gKey}>
<div className={styles.bg}>{j}</div>
</td>
if (result[trIdx].length == 7) {
++trIdx
result[trIdx] = []
}
result[trIdx].push(td)
}
return result
}
next = ()=> {
this.state.cDate = new Date(this.getCurrYear(), this.getCurrMounth())
this.forceUpdate()
}
prev = ()=> {
this.state.cDate = new Date(this.getCurrYear(), this.getCurrMounth() - 2)
this.forceUpdate()
}
render (){
return (
<div className={styles.box}>
<div className={styles.tit}>
<div>请选择日期</div>
<div>
{
this.getCurrMounth() > new Date().getMonth()+1 ?
<Icon type="left" onClick={this.prev}/>
:null
}
<span className={styles.month}>{`${this.getCurrYear()}年${this.getCurrMounth()}月`}</span>
<Icon type="right" onClick={this.next}/>
</div>
</div>
<table className={styles.table}>
<thead className={styles.thead}>
<tr>
<th>日</th>
<th>一</th>
<th>二</th>
<th>三</th>
<th>四</th>
<th>五</th>
<th>六</th>
</tr>
</thead>
<tbody className={styles.tbody}>
{
this.renderTD().map((v,i)=>(
<tr key={i}>{v}</tr>
))
}
</tbody>
</table>
</div>
)
}
}