0
votes

I have an application written in React Typescript with hooks where I am trying to set a date input field in two ways(controlled/uncontrolled). It should change either when the user changes the input or when the component receives props from its parent.

However, my problem is that after I set the value prop at the input-field, it is not possible for the user to change the values in the input-field... Here is my code:

interface Props {
    valuesChanged: (type: string, value: string) => void;
    minChanged: string;
    maxChanged: string;
}

const DateInputField: FC<Props> = ({ valuesChanged, minChanged, maxChanged }: Props) => {
    const [minValue, setMinValue] = useState<string>('');
    const [maxValue, setMaxValue] = useState<string>('');

    // Input changed in parent, trigger changes here
    useEffect(() => {
        const date = moment(minChanged, 'YYYY-MM-DD', true);
        if (date.isValid()) {
            setMinValue(minChanged);
        }
    }, [minChanged]);

    useEffect(() => {
        const date = moment(maxChanged, 'YYYY-MM-DD', true);
        if (date.isValid()) {
            setMaxValue(maxChanged);
        }
    }, [maxChanged]);

    // Input changed in input field
    const inputChanged = (type: string, input: string) => {
        const date = moment(input, 'YYYY-MM-DD', true);
        if (date.isValid()) {
            valuesChanged(type, input); // tell parent component values changed
            if (type === 'startDate') {
                setMinValue(input);
            } else if (type === 'endDate') {
                setMaxValue(input);
            }
        }
    };

    return (
        <div>
            <input value={maxValue} type="date" onChange={(e) => inputChanged('endDate', e.target.value)} />
            <input value={maxValue} type="date" onChange={(e) => inputChanged('endDate', e.target.value)} />
        </div>
    );
};
export default DateInputField;

The valuesChanged prop is a function telling the parent that values in this component changed. Hope someone can help!

1
what's the isValid function like?Alexander Hemming
It is coming from moment, and used to check whether a date is valid as far as I have understood: momentjscom.readthedocs.io/en/latest/moment/01-parsing/…alp123

1 Answers

1
votes

moment().isvalid checks to see if a date is valid.

your input will not type anything anless what passes thoruhg the onChange aspect to the input is valid.

According to the docs, the isvalid will only support valid for an entier date. The onCHange will only work then if you can type the entire date in one click.

Therefore it will not type as the validity cannot be assertained until the entire date is put into the input.

If you want to solve this you can either make it impossible to deviate from a dat. This would mean you have to pass it through a function that says false when it deviates from what could be a valid date.

edit: You can if you want create a date and then take away from the date the same amount as you are putting into it from the input, then you can check if that is valid with moment.

something like :

    let index = input.length;
        (index, date) => {
             setNewDate(input + date.substr(0, index) );
        }
if(newDate) { setInput(e.target.value) }

Or you could crerate an alert on submission of a wrong format, as is normally the case. So using the moment(input, dd-mm--yy ).isvalid on submission event.