AllowTextInput #2943

Still has issues due to onSelectDate being called twice:
https://github.com/microsoft/fluentui/issues/22283
The second time it's called with a null value and it just resets the field.
This commit is contained in:
Alice Rosa 2022-09-02 08:24:04 +03:00
parent 678d265ec8
commit a0c70ec928
3 changed files with 74 additions and 44 deletions

View File

@ -25,7 +25,7 @@
"@types/webpack-env": "1.13.1", "@types/webpack-env": "1.13.1",
"@uifabric/icons": "^7.3.14", "@uifabric/icons": "^7.3.14",
"moment": "^2.24.0", "moment": "^2.24.0",
"office-ui-fabric-react": "^6.189.2", "office-ui-fabric-react": "^7.197.1",
"react-dnd": "~2.5.4", "react-dnd": "~2.5.4",
"react-dnd-html5-backend": "~2.5.4", "react-dnd-html5-backend": "~2.5.4",
"react-html-parser": "^2.0.2", "react-html-parser": "^2.0.2",

View File

@ -16,42 +16,27 @@ export interface IDateFormFieldProps extends IDatePickerProps {
value: any; value: any;
} }
export interface IDateFormFieldState { export interface IDateFormFieldState {
date?: Date; date: Date,
hours: number; options: {
minutes: number; hours: IComboBoxOption[],
minutes: IComboBoxOption[]
}
} }
export default class DateFormField extends React.Component<IDateFormFieldProps, IDateFormFieldState> { export default class DateFormField extends React.Component<IDateFormFieldProps, IDateFormFieldState> {
constructor(props) { constructor(props) {
super(props); super(props);
this._createComboBoxHours = this._createComboBoxHours.bind(this);
this._createComboBoxMinutes = this._createComboBoxMinutes.bind(this);
this.state = { this.state = {
hours: 0, date: this._parseDateString(this.props.value),
minutes: 0 options: {
hours: this._createComboBoxHours(),
minutes: this._createComboBoxMinutes()
}
}; };
} }
public componentDidUpdate(prevProps: IDateFormFieldProps, prevState: IDateFormFieldState) {
//Component Value property got updated from List State
if (this.props.value && prevProps.value != this.props.value) {
let momentDate = moment(this.props.value, moment.localeData(this.props.locale).longDateFormat('L'));
this.setState({
hours: momentDate.hour(),
minutes: momentDate.minute(),
date: momentDate.toDate()
});
}
//Component value updated
if (this.state.date && this.state.date != prevState.date) {
let result = this.props.fieldSchema.DisplayFormat == 1 ?
this.state.date.toLocaleDateString(this.props.locale) + " " + this.state.date.toLocaleTimeString(this.props.locale, { hour: "2-digit", minute: "2-digit" }) : //Date + Time
this.state.date.toLocaleDateString(this.props.locale); //Only date
this.props.valueChanged(result);
}
}
public render() { public render() {
return ( return (
<React.Fragment> <React.Fragment>
<DatePicker <DatePicker
@ -59,10 +44,10 @@ export default class DateFormField extends React.Component<IDateFormFieldProps,
ariaLabel={this.props.ariaLabel} ariaLabel={this.props.ariaLabel}
className={css(this.props.className, this.props.fieldSchema.DisplayFormat == 1 ? "ms-sm12 ms-md12 ms-lg6 ms-xl8" : "ms-sm12")} className={css(this.props.className, this.props.fieldSchema.DisplayFormat == 1 ? "ms-sm12 ms-md12 ms-lg6 ms-xl8" : "ms-sm12")}
firstDayOfWeek={this.props.firstDayOfWeek} firstDayOfWeek={this.props.firstDayOfWeek}
formatDate={(date: Date) => (typeof date.toLocaleDateString === 'function') ? date.toLocaleDateString(this.props.locale) : ''} formatDate={(date: Date) => (date && typeof date.toLocaleDateString === 'function') ? date.toLocaleDateString(this.props.locale) : ''}
isRequired={this.props.isRequired} isRequired={this.props.isRequired}
onSelectDate={this._onSelectDate} onSelectDate={this._onSelectDate}
parseDateFromString={(dateStr: string) => new Date(Date.parse(dateStr))} parseDateFromString={this._parseDateString}
placeholder={this.props.placeholder} placeholder={this.props.placeholder}
strings={strings} strings={strings}
value={this.state.date} value={this.state.date}
@ -72,20 +57,20 @@ export default class DateFormField extends React.Component<IDateFormFieldProps,
<React.Fragment> <React.Fragment>
<ComboBox <ComboBox
onChange={this._onHoursChanged} onChange={this._onHoursChanged}
selectedKey={this.state.hours} selectedKey={this.state.date ? this.state.date.getHours() : 0}
allowFreeform allowFreeform
autoComplete="on" autoComplete="on"
persistMenu={true} persistMenu={true}
options={this._createComboBoxHours()} options={this.state.options.hours}
className={css(this.props.className, "ms-sm6", "ms-md6", "ms-lg3", "ms-xl2")} className={css(this.props.className, "ms-sm6", "ms-md6", "ms-lg3", "ms-xl2")}
/> />
<ComboBox <ComboBox
selectedKey={this.state.minutes} selectedKey={this.state.date ? this.state.date.getMinutes() : 0}
onChange={this._onMinutesChanged} onChange={this._onMinutesChanged}
allowFreeform allowFreeform
autoComplete="on" autoComplete="on"
persistMenu={true} persistMenu={true}
options={this._createComboBoxMinutes()} options={this.state.options.minutes}
className={css(this.props.className, "ms-sm6", "ms-md6", "ms-lg3", "ms-xl2")} className={css(this.props.className, "ms-sm6", "ms-md6", "ms-lg3", "ms-xl2")}
/> />
</React.Fragment> </React.Fragment>
@ -95,28 +80,73 @@ export default class DateFormField extends React.Component<IDateFormFieldProps,
} }
private _onSelectDate = (inputDate: Date | null | undefined): void => { private _onSelectDate = (inputDate: Date | null | undefined): void => {
let date = inputDate ? moment(inputDate) : moment(); console.log("Date has been selected" + !inputDate ? "" : inputDate.toLocaleDateString());
date.hour(this.state.hours); if (inputDate) {
date.minute(this.state.minutes);
this.setState({ date: date.toDate() }); this.setState(prevState => {
return {
date: inputDate,
...prevState
};
});
//this._onValueChanged(inputDate);
}
} }
private _onHoursChanged = (event: React.FormEvent<IComboBox>, option?: IComboBoxOption): void => { private _onHoursChanged = (event: React.FormEvent<IComboBox>, option?: IComboBoxOption): void => {
console.log(event);
console.log(option);
if (option) { if (option) {
let date = this.state.date ? moment(this.state.date) : moment();
let hours = parseInt(option.key.toString()); let hours = parseInt(option.key.toString());
date.hour(hours); this.setState(prevState => {
this.setState({ date: date.toDate(), hours }); let momentDate = prevState.date ? moment(prevState.date) : moment();
momentDate.hour(hours);
let date = momentDate.toDate()
//this._onValueChanged(date);
return {
date: date,
...prevState
};
});
} }
} }
private _onMinutesChanged = (event: React.FormEvent<IComboBox>, option?: IComboBoxOption): void => { private _onMinutesChanged = (event: React.FormEvent<IComboBox>, option?: IComboBoxOption): void => {
if (option) { if (option) {
let date = this.state.date ? moment(this.state.date) : moment();
let minutes = parseInt(option.key.toString()); let minutes = parseInt(option.key.toString());
date.minute(minutes); this.setState(prevState => {
this.setState({ date: date.toDate(), minutes }); let momentDate = prevState.date ? moment(prevState.date) : moment();
momentDate.minutes(minutes);
let date = momentDate.toDate()
// this._onValueChanged(date);
return {
date: date,
...prevState
};
});
} }
} }
private _onValueChanged(date: Date) {
let result = '';
if (date) {
result = this.props.fieldSchema.DisplayFormat == 1 ?
date.toLocaleDateString(this.props.locale) + " " + date.toLocaleTimeString(this.props.locale, { hour: "2-digit", minute: "2-digit" }) : //Date + Time
date.toLocaleDateString(this.props.locale); //Only date
}
this.props.valueChanged(result);
}
private _parseDateString(inputDate: string): Date {
if (!inputDate) {
return null;
}
let momentDate = this.props.fieldSchema.DisplayFormat == 1 ?
moment(inputDate, moment.localeData(this.props.locale).longDateFormat('LT')) :
moment(inputDate, moment.localeData(this.props.locale).longDateFormat('L'))
return momentDate.toDate()
}
private _createComboBoxHours(): IComboBoxOption[] { private _createComboBoxHours(): IComboBoxOption[] {
let results = new Array<IComboBoxOption>(); let results = new Array<IComboBoxOption>();
if (this.props.fieldSchema.HoursOptions) { if (this.props.fieldSchema.HoursOptions) {

View File

@ -17,7 +17,7 @@ const SPFieldDateEdit: React.SFC<ISPFormFieldProps> = (props) => {
ariaLabel={props.fieldSchema.Title} ariaLabel={props.fieldSchema.Title}
locale={locale} locale={locale}
firstDayOfWeek={props.fieldSchema.FirstDayOfWeek} firstDayOfWeek={props.fieldSchema.FirstDayOfWeek}
allowTextInput allowTextInput={true}
fieldSchema={props.fieldSchema} fieldSchema={props.fieldSchema}
value={props.value} value={props.value}
valueChanged={props.valueChanged} valueChanged={props.valueChanged}