Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DateTimePicker time portion not re-rendered when state changed programmatically #713

Closed
rendersbymarsh opened this issue Oct 29, 2020 · 9 comments
Labels
status:fixed-next-drop Issue will be fixed in upcoming release. type:bug
Milestone

Comments

@rendersbymarsh
Copy link

Category

[ ] Enhancement

[x] Bug

[ ] Question

Version

Please specify what version of the library you are using: [ 2.1.0 ]

Expected / Desired Behavior / Question

I have a DateTimePicker on a form that's showing time. If I programmatically change the value of the component, the date portion re-renders successfully but not the time portion. (Changes made via UI work normally as they fire the onChange handler.)

My specific use case is an Undo button on the form that reverts the form values back to what was initially retrieved from the server.

Initial value:

image

After change via UI:

image

After Undo button pressed:

image

I know the value is actually being changed correctly in code, because if I close the panel containing the form and re-open it the value is back to what I would expect it to be. Therefore I think it's a bug with the component and how it detects a change to the time portion of the value.

Observed Behavior

The time portion should change to reflect the current value in state.

Steps to Reproduce

Listed above

@ghost
Copy link

ghost commented Oct 29, 2020

Thank you for reporting this issue. We will be triaging your incoming issue as soon as possible.

@ghost ghost added the Needs: Triage 🔍 label Oct 29, 2020
@AJIXuMuK
Copy link
Collaborator

AJIXuMuK commented Nov 7, 2020

Hi @BreakfastMaintenance!
Thank you for reporting the issue.

Could you please provide some code to reproduce it? I can't reproduce it in my tests.

// ...
private _onDateTimePickerChange = (dateTimeValue: Date) => {
    this.setState({ dateTimeValue });
    console.log("Selected Date/Time:", dateTimeValue.toLocaleString());
  }

//...

<DateTimePicker
          label="DateTime Picker (Controlled)"
          formatDate={d => `${d.getFullYear()} - ${d.getMonth() + 1} - ${d.getDate()}`}
          dateConvention={DateConvention.DateTime}
          timeConvention={TimeConvention.Hours24}
          firstDayOfWeek={DayOfWeek.Monday}
          value={this.state.dateTimeValue}
          onChange={this._onDateTimePickerChange}
          isMonthPickerVisible={false}
          showMonthPickerAsOverlay={true}
          showWeekNumbers={true}
          showSeconds={true}
        />
        <PrimaryButton text={'Change Date'} onClick={() => {
          const date = this.state.dateTimeValue || new Date();
          date.setMinutes(50);
          this.setState({
            dateTimeValue: date
          });
        }} />

@rendersbymarsh
Copy link
Author

rendersbymarsh commented Nov 9, 2020

Hi @AJIXuMuK

This is a barebones example of essentially what I'm doing, which still exhibits the issue:

interface Entity {
  dateTimeField: Date;
}

const defaultEntityState = {
  dateTimeField: new Date('October 17, 2020 13:12:00')
};

const ChildComponent: React.FC = () => {
  const [entity, setEntity] = React.useState<Entity>(defaultEntityState);
  
  const onFieldChange = (name: string) => (value: any) => {
    setEntity({
      ...entity, [name]: value
    });
  }
  
  const revertTimeToDefault = (_e) => {
    setEntity(defaultEntityState);
  }
  
  const fieldValue = entity && entity.dateTimeField;
  
  return (
    <>
      <button onClick={revertTimeToDefault} type="button">Revert DateTime</button>
      <DateTimePicker
        firstDayOfWeek={DayOfWeek.Monday}
        strings={DayPickerStrings}
        placeholder="Select a date..."
        showLabels
        dateConvention={DateConvention.DateTime}
        timeConvention={TimeConvention.Hours24}
        timeDisplayControlType={TimeDisplayControlType.Dropdown}
        onChange={onFieldChange('dateTimeField')}
        value={fieldValue instanceof Date ? fieldValue : null}
        />  
    </>
  );
}

DayPickerStrings is just the set of labels, included below for your tests.

const DayPickerStrings: IDateTimePickerStrings = {
    dateLabel: 'Date',
    timeLabel: 'Time',
    timeSeparator: ':',
    amDesignator: 'AM',
    pmDesignator: 'PM',
    months: [
        'January',
        'February',
        'March',
        'April',
        'May',
        'June',
        'July',
        'August',
        'September',
        'October',
        'November',
        'December',
    ],
    shortMonths: [
        'Jan',
        'Feb',
        'Mar',
        'Apr',
        'May',
        'Jun',
        'Jul',
        'Aug',
        'Sep',
        'Oct',
        'Nov',
        'Dec',
    ],
    days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
    shortDays: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
    goToToday: 'Go to today',
    prevMonthAriaLabel: 'Go to previous month',
    nextMonthAriaLabel: 'Go to next month',
    prevYearAriaLabel: 'Go to previous year',
    nextYearAriaLabel: 'Go to next year',
};

AJIXuMuK added a commit that referenced this issue Nov 18, 2020
@AJIXuMuK
Copy link
Collaborator

Thank you @BreakfastMaintenance for the details!
I was able to reproduce it when the time portion is displayed as a dropdown.

The fix has been done and will be available in the next release.

In a meanwhile you can test the functionality in beta version

@AJIXuMuK AJIXuMuK added status:fixed-next-drop Issue will be fixed in upcoming release. type:bug and removed Needs: Attention 👋 labels Nov 18, 2020
@AJIXuMuK AJIXuMuK added this to the 2.2.0 milestone Nov 18, 2020
@rendersbymarsh
Copy link
Author

Fantastic @AJIXuMuK, thanks for sorting 😄

I've got a janky workaround for the time being based on setting a random key against the DateTimePicker, so will wait for the 2.2.0 release and get that taken out once it drops.

@280237
Copy link

280237 commented Dec 2, 2020

I am facing same issue. When will be the next release? Also, is there workaround to handle this temporarily?

@estruyf estruyf mentioned this issue Dec 3, 2020
@rendersbymarsh
Copy link
Author

@280237, this is the hacky workaround we've got currently. Just sets a new key on the component every time to force React to re-render it:

const getKey = (props: IDateFormFieldProps) => props.showTime && `datetime-${new Date().getTime()}`;

<DateTimePicker
    key={getKey(props)}
    ...
/>

Judging by the merge 20 minutes ago though we may be looking at a release for 2.2.0 soon so maybe best to just hold off!

@rendersbymarsh
Copy link
Author

Hi @AJIXuMuK

I've just checked this in release 2.2.0, and the minutes appear to be working but not the hours.

If I follow the same test as in my original post, I end up with:

image

This has reverted the minutes back to 12, but not the hours back to 11

@AJIXuMuK
Copy link
Collaborator

AJIXuMuK commented Dec 3, 2020

Please, create a separate issue so we could work on that.
Thanks!

@AJIXuMuK AJIXuMuK closed this as completed Dec 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status:fixed-next-drop Issue will be fixed in upcoming release. type:bug
Projects
None yet
Development

No branches or pull requests

3 participants