admin管理员组

文章数量:1398766

I want to add mask in the antd datepicker and also validate it as correct date format like dd/mm/yy this format

This is the code I've tried

<FormItem label="Date of Birth">
{getFieldDecorator("dob", {rules: [{ required: true, message:"Please input the dob!" }]})(
  <DatePicker format="DD/MM/YY" getCalendarContainer={() => document.getElementById('dobParent')} onChange={handleChange} disabledDate={disabledDate} suffixIcon={<span className="icon-calendar datepicker-block"></span>} placeholder="dd/mm/yy"/>)}
</FormItem>

I want to add mask in the antd datepicker and also validate it as correct date format like dd/mm/yy this format

This is the code I've tried

<FormItem label="Date of Birth">
{getFieldDecorator("dob", {rules: [{ required: true, message:"Please input the dob!" }]})(
  <DatePicker format="DD/MM/YY" getCalendarContainer={() => document.getElementById('dobParent')} onChange={handleChange} disabledDate={disabledDate} suffixIcon={<span className="icon-calendar datepicker-block"></span>} placeholder="dd/mm/yy"/>)}
</FormItem>
Share Improve this question asked Nov 12, 2019 at 12:42 Haris GeorgeHaris George 3598 silver badges21 bronze badges 5
  • you can use external library like moment.js to format the date – Wasif Commented Nov 12, 2019 at 19:29
  • It maybe helpful for you stackoverflow./a/58855473/5124488 – blueseal Commented Nov 17, 2019 at 14:37
  • Thank you for you reply @Wasif. But I want to type the date in the datepicker input and as I type it should be masked eg: When I type 10 it should be 10 and then when I type the next number it shoul bee like this 10/1. Is there a way for that – Haris George Commented Nov 18, 2019 at 10:24
  • So basically, if someone types in a date like 10/31/20 - you want it to autocorrect the field to 31/10/20? That's how I'm ultimately reading this. – elisciandrello Commented Nov 16, 2020 at 15:13
  • I'm trying to achieve the same thing. Have you figured it out, mate? @HarisGeorge – Blitva Commented Nov 26, 2021 at 15:12
Add a ment  | 

3 Answers 3

Reset to default 6

Ant Design's Date Picker doesn't provide a convenient way to add a mask to its input element (at least until v4.x), so we need to access its internal API.

Here is a workaround (with imask) that applies a mask and reformats the date while users type it in to avoid the need to add //-.

import React from 'react'
import {
  DatePicker as AntdDatePicker,
  DatePickerProps as AntDatePickerProps,
} from 'antd'
import IMask from 'imask'
import moment from 'moment'

const DATE_FORMAT = 'MM/DD/YYYY'
const MASKED = IMask.createMask({
  blocks: {
    DD: {from: 1, mask: IMask.MaskedRange, to: 31},
    MM: {from: 1, mask: IMask.MaskedRange, to: 12},
    YYYY: {from: 1900, mask: IMask.MaskedRange, to: Number.MAX_VALUE},
  },
  format: (date: Date) => moment(date).format(DATE_FORMAT),
  mask: Date,
  parse: (date: string) => moment(date, DATE_FORMAT),
  pattern: DATE_FORMAT,
})

export type DatePickerProps = Omit<AntDatePickerProps, 'format' | 'picker' | 'onKeyDown'>

const DatePicker = (props: DatePickerProps) => (
  <AntdDatePicker
    format={DATE_FORMAT}
    onKeyDown={(event: React.KeyboardEvent<HTMLInputElement>) => {
      const input = event.target as HTMLInputElement
      input.value = MASKED.resolve(input.value)
    }}
    picker="date"
    placeholder={DATE_FORMAT.toLowerCase()}
    {...props}
  />
)

export default DatePicker

EN-US - dd/mm/yyyy CodeSandbox

EN-GB - mm/dd/yy CodeSandbox

this if else is not most beautiful, but is as you wished

import React, { useState, useCallback, useRef, useMemo } from "react";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import "./styles.css";

export default function App() {
  const [date, setDate] = useState(new Date());

 const isLeapYear = useCallback(year => {
    return !((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0)
 }, [])

 const format = useCallback((val) => {
    if(!val) return "";
    const len = val.length;
    if (len === 1 && !["0", "1", "2", "3"].includes(val[0])) {
        return "";
    } else if (
        (len === 2 && val[0] === "3" && !["0", "1"].includes(val[1])) ||
         val.substr(0, 2) === "00"
    ) {
        return val.substr(0, 1);
    } else 
    
    if (len === 3) {
        if (val[2] === "/") {
            return val.substr(0, 2);
        } else if (["0", "1"].includes(val[2])
        ) {
            return val.substr(0, 2) + "/" + val.substr(2);
        } else {
            return val.substr(0, 2);
        }
    } else if (
        len === 5 &&
        (val.substr(3, 5) === "00" ||
        (val[3] === "1" && !["0", "1", "2"].includes(val[4])) ||
        (["30","31"].includes(val.substr(0, 2)) && val.substr(3, 5) === "02")||
        (val.substr(0, 2) === "31"  &&
            !["01", "03", "05", "07", "08", "10", "12"].includes(val.substr(3, 5)))
        )
    ) {
        return val.substr(0, 4);
    } else if (len === 6) {
        if (val[5] === "/") {
            return val.substr(0, 5);
        } else {
            return val.substr(0, 5) + "/" + val.substr(5);
        }
    }  else if (len === 8 && val.substr(0, 6) === "29/02/") {
        let year = +val.substr(6);
        year = year > 1970 ? 1900 + year : 2000 + year;
        if (isLeapYear(year)) {
            return val.substr(0, 7);
        }
    } else  if (len > 8) {
        return val.substr(0, 8);
    }
    return val;
  }, [isLeapYear]);

  
  const onChangeRaw = useCallback((e) => {
    e.target.value = format(e.target.value);
  }, [format]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <DatePicker
        dateFormat="dd/MM/yy"
        //locale="en-GB"
        onChange={setDate}
        onChangeRaw={onChangeRaw}
        selected={date}
        suffixIcon={<span className="icon-calendar datepicker-block"></span>}
        placeholder="mm/dd/yy"
      />
    </div>
  );
}

Good one, but antd-lib datepicker has no such API as onChangeRaw

本文标签: javascriptHow to add mask in antd datepicker reactjsStack Overflow