DatePicker 日期选择
用于选择日期或者时间。
规则
- 最多展示 5 个独立滚轮,每个滚轮表示一个不同的值。
代码演示
基本
import { DatePicker, List } from 'antd-mobile';
import enUs from 'antd-mobile/lib/date-picker/locale/en_US';
const nowTimeStamp = Date.now();
const now = new Date(nowTimeStamp);
// GMT is not currently observed in the UK. So use UTC now.
const utcNow = new Date(now.getTime() + (now.getTimezoneOffset() * 60000));
// Make sure that in `time` mode, the maxDate and minDate are within one day.
let minDate = new Date(nowTimeStamp - 1e7);
const maxDate = new Date(nowTimeStamp + 1e7);
// console.log(minDate, maxDate);
if (minDate.getDate() !== maxDate.getDate()) {
// set the minDate to the 0 of maxDate
minDate = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate());
}
function formatDate(date) {
/* eslint no-confusing-arrow: 0 */
const pad = n => n < 10 ? `0${n}` : n;
const dateStr = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
const timeStr = `${pad(date.getHours())}:${pad(date.getMinutes())}`;
return `${dateStr} ${timeStr}`;
}
// If not using `List.Item` as children
// The `onClick / extra` props need to be processed within the component
const CustomChildren = ({ extra, onClick, children }) => (
<div
onClick={onClick}
style={{ backgroundColor: '#fff', height: '45px', lineHeight: '45px', padding: '0 15px' }}
>
{children}
<span style={{ float: 'right', color: '#888' }}>{extra}</span>
</div>
);
class Demo extends React.Component {
state = {
date: now,
time: now,
utcDate: utcNow,
dpValue: null,
customChildValue: null,
visible: false,
}
render() {
return (
<List className="date-picker-list" style={{ backgroundColor: 'white' }}>
<DatePicker
value={this.state.date}
onChange={date => this.setState({ date })}
>
<List.Item arrow="horizontal">Datetime</List.Item>
</DatePicker>
<DatePicker
mode="date"
title="Select Date"
extra="Optional"
value={this.state.date}
onChange={date => this.setState({ date })}
>
<List.Item arrow="horizontal">Date</List.Item>
</DatePicker>
<DatePicker
mode="time"
minuteStep={2}
use12Hours
value={this.state.time}
onChange={time => this.setState({ time })}
>
<List.Item arrow="horizontal">Time (am/pm)</List.Item>
</DatePicker>
<DatePicker
mode="time"
minDate={minDate}
maxDate={maxDate}
value={this.state.time}
onChange={time => this.setState({ time })}
>
<List.Item arrow="horizontal">Limited time</List.Item>
</DatePicker>
<DatePicker
mode="time"
locale={enUs}
format={val => `UTC Time: ${formatDate(val).split(' ')[1]}`}
value={this.state.utcDate}
onChange={date => this.setState({ utcDate: date })}
>
<List.Item arrow="horizontal">UTC time</List.Item>
</DatePicker>
<List.Item
extra={this.state.dpValue && formatDate(this.state.dpValue)}
onClick={() => this.setState({ visible: true })}
>
External control visible state
</List.Item>
<DatePicker
visible={this.state.visible}
value={this.state.dpValue}
onOk={date => this.setState({ dpValue: date, visible: false })}
onDismiss={() => this.setState({ visible: false })}
/>
<DatePicker
mode="time"
format="HH:mm"
title="Select Time"
value={this.state.customChildValue}
onChange={v => this.setState({ customChildValue: v })}
extra="click to choose"
>
<CustomChildren>With customized children</CustomChildren>
</DatePicker>
</List>
);
}
}
ReactDOM.render(<Demo />, mountNode);
.date-picker-list .am-list-item .am-list-line .am-list-extra {
flex-basis: initial;
}
结合 form 验证示例
日期时间选择示例, (rc-form)
import { DatePicker, List, Button, InputItem } from 'antd-mobile';
import { createForm } from 'rc-form';
const nowTimeStamp = Date.now();
const now = new Date(nowTimeStamp);
const utcOffset = new Date(now.getTime() - (now.getTimezoneOffset() * 60000));
// console.log(now, utcOffset, now.toISOString(), utcOffset.toISOString());
class Test extends React.Component {
state = {
dpValue: now,
idt: utcOffset.toISOString().slice(0, 10),
}
onSubmit = () => {
this.props.form.validateFields({ force: true }, (error) => {
if (!error) {
console.log(this.props.form.getFieldsValue());
} else {
console.log(error);
alert('Validation failed');
}
});
}
onReset = () => {
this.props.form.resetFields();
setTimeout(() => console.log(this.state), 0);
}
validateIdp = (rule, date, callback) => {
if (isNaN(Date.parse(date))) {
callback(new Error('Invalid Date'));
} else {
const cDate = new Date(date);
const newDate = new Date(+this.state.dpValue);
newDate.setFullYear(cDate.getFullYear());
newDate.setMonth(cDate.getMonth());
newDate.setDate(cDate.getDate());
// this.setState({ dpValue: newDate });
setTimeout(() => this.props.form.setFieldsValue({ dp: newDate }), 10);
callback();
}
}
validateDatePicker = (rule, date, callback) => {
if (date && date.getMinutes() !== 15) {
callback();
} else {
callback(new Error('15 is invalid'));
}
}
render() {
const { getFieldProps, getFieldError } = this.props.form;
return (<form>
<List
className="date-picker-list"
renderFooter={() => getFieldError('dp') && getFieldError('dp').join(',')}
>
<InputItem
placeholder="must be the format of YYYY-MM-DD"
error={!!getFieldError('idp')}
{...getFieldProps('idp', {
initialValue: this.state.idt,
rules: [
{ validator: this.validateIdp },
],
})}
>Input date</InputItem>
<DatePicker
{...getFieldProps('dp', {
initialValue: this.state.dpValue,
rules: [
{ required: true, message: 'Must select a date' },
{ validator: this.validateDatePicker },
],
})}
>
<List.Item arrow="horizontal">Date</List.Item>
</DatePicker>
<List.Item>
<Button type="primary" size="small" inline onClick={this.onSubmit}>Submit</Button>
<Button size="small" inline style={{ marginLeft: '2.5px' }} onClick={this.onReset}>Reset</Button>
</List.Item>
</List>
</form>);
}
}
const TestWrapper = createForm()(Test);
ReactDOM.render(<TestWrapper />, mountNode);
.date-picker-list .am-list-item .am-list-line .am-list-extra {
flex-basis: initial;
}
API
属性 | 说明 | 类型 | 默认值 |
---|
mode | 日期选择的类型, 可以是日期date ,时间time ,日期+时间datetime ,年year ,月month | String | date |
value | 当前选中时间 | Date | 无 |
minDate | 最小可选日期 | Date | new Date(2000, 1, 1, 0, 0, 0) |
maxDate | 最大可选日期 | Date | new Date(2030, 1, 1, 23, 59, 59) |
use12Hours | 12小时制 | Boolean | false |
minuteStep | 分钟数递增步长设置 | Number | 1 |
locale | 国际化,可覆盖全局LocaleProvider 的配置 | Object: {DatePickerLocale: {year, month, day, hour, minute, am?, pm?}, okText, dismissText } | - |
disabled | 是否不可用 | Boolean | false |
onChange | 时间发生变化的回调函数 | (date: Object): void | - |
onValueChange | 每列 picker 改变时的回调 | (vals: any, index: number) => void | - |
format | 格式化选中的值 | (value: Date) => date string / format string (对应 mode 下格式分别为:YYYY-MM-DD ,HH:mm ,YYYY-MM-DD HH:mm ) | - |
title | 弹框的标题 | string/React.ReactElement | 无 |
extra | 显示文案 | String | 请选择 |
prefixCls | class前缀 | string | am-picker |
className | 样式类名 | string | - |
onOk | 点击选中时执行的回调 | (val): void | 无 |
onDismiss | 点击取消时执行的回调 | (): void | 无 |
注意:日期字符串在不同浏览器有不同的实现,例如 new Date('2017-1-1')
在 Safari 上是 Invalid Date,而在 Chrome 上是能正常解析的。
注意:DatePicker
children 建议是 List.Item
, 如果不是,需要是自定义组件(组件内需处理 onClick
/ extra
/ children
属性,详情请看 demo