Material-ui: [DateTimePicker]: Hard to compose DatePicker and TimePicker

Created on 4 May 2016  路  15Comments  路  Source: mui-org/material-ui

Problem Description

Hard to compose DatePicker and TimePicker

I think material-ui needs something like this material-datetime-picker

wontfix

Most helpful comment

There is a 3rd party package that joins pickers https://www.npmjs.com/package/material-ui-datetimepicker

All 15 comments

Could you be a little more elaborate on this?

The current implementation of date and time pickers are in accordance to the material-design spec.
https://www.google.com/design/spec/components/pickers.html

Having said that, there is a good amount of work going on/ proposed to make the pickers more in sync with the material design spec.

We had a PR for something similar to this and we decided to not go ahead for it atleast for now.

Closing this. Feel free to leave comments below if you need to add something to this.

I understand and appreciate your effert to sync with MD.

I said 'Hard to compose DatePicker and TimePicker'.

It means if I need user to pick a datetime, I have one variable with two inputs(or pickers), which is very odd and doesn't make sense. And it's hard and ugly to combine two Date(one represents date, one represents time) into one if I don't use a libraries like moment.

Maybe I'm thinking this problem in a wrong way. Please tell me how to do this in a decent way.

@stupidisum : Thanks for the clarification. I understand your problem much more clear now.

Currently, we do not have any provision to do what you want. You can adjust the dateTimeformat to get time as well but the time is not adjustable and hence won't serve your purpose.

If you need a solution to it, I would suggest use the DatePicker and TimePicker as separate adjacent fields and combine the two inputs when you are processing the data. I know its a trivial thing to do and not the perfect solution.

I am reopening the issue and marking it as a new feature. If you would care to submit a PR it would help not just you but also others who are looking for similar solution.

Thanks!

@stupidisum

FWIW, google usually present them as 2 separate controls (date and time pickers).

would be great to have built-in util for compose date and time in a single value

Closing for new, as this isn't something we're planning to add.

Also, this isn't how google do it on android.

Just found this thread looking to do exactly this. I'm perfectly happy combining the two values into a single Date object on form submit, except I'm new to this and have no idea how.

Does anyone who has done this previously have any pointers/advice on how to do this?

Thanks in advance!

@HemalR ....I recently worked on a project in which I was using both Datepicker and Timepicker and I did manage to combine both as a single object on form submit. Your user is going to have to pick the day and then pick the time separately (different fields), but in terms of submitting the overall form, for me, it just seemed to "know" and autocombined date and time into the single date object. I didn't do anything complicated. All I can say is that it was one of those things where it worked, so I said "yay!", didn't question it, and moved on. Here's parts of the code:

`
handleTime(event, time){
this.setState({time: time})
}
handleDate(event, date){
this.setState({date: date})
}

handleSubmit(event){
const newChore = {
name: this.state.name,
end_time: this.state.date,
category: "chore",
assigned_to: this.state.assigned_to
}`

`



      <SelectField
        value={this.state.assigned_to}
        onChange={this.handleAssignment}
        floatingLabelText={"Assign to: "}>
        {this.props.groupMembers.map(function(member) {
          return <MenuItem value={member.id} primaryText={ member.first_name }/>
        })}
      </SelectField><br/>

      <DatePicker onChange={this.handleDate} value ={this.state.date} hintText="Date to be completed by" />
      <TimePicker onChange={this.handleTime} value={this.state.time} hintText="Time to be completed by" />

    </form>

`

As you can see, I've got different event handlers and different fields for state when a user inputs date and time, but in the submit handler, I only needed to assign it the state value for date and as I said, it worked just fine for me. It was interacting with a Rails API, so I don't know if that had anything to do with it.

Here's the project if you want to take a look at it. Feel free to clone it down and play with it. You'll need to run the corresponding Rails API though: https://github.com/alxsanborn/houseMate-React/blob/master/src/components/chores/chores_new.js

Cheers @alxsanborn !

I did end up finding a solution (similar in many ways to yours in that they are treated separately at the start) using moment.js.

Summary version - set the time and date states separately based on user input, then, just prior to submitting to the server (can be done on the server as well I guess, may be better), I create a new moment object using the date fields from the date picker and time fields from the time picker.

Relevant part of the code below:

let momentTime = moment(this.state.appointmentTime);
let momentDate = moment(this.state.appointmentDate);
let appointmentMoment = moment({
    year: momentDate.year(),
    month: momentDate.month(),
    day: momentDate.date(),
    hour: momentTime.hours(),
    minute: momentTime.minutes()
});

Now, Time-Picker preserved 'Date' part.

But Date-Picker don't preserve 'Time' part.
It change 'Time' part to Local-Time 00:00:00.

I think Date-Picker should preserved 'Time' part of initialDate.

For example. (JST +0900)
2017-04-01 20 43 52

That way, the work will be much easier.

If you use 'redux-form-material-ui', the following works properly.

<div>
  <Field name={name} component={DatePicker} />
  <Field name={name} component={TimePicker} />
</div>

Modify it as follows.

https://github.com/exabugs/material-ui/commit/85591dc39ca9d1ed0a1abcb554edce953af66231

@nathanmarks @mbrookes
After re-learned sth about material-design. I think you're doing date picker and time picker in a wrong way.
Look at the guidelines. There's no 'TextField-like' pickers. Just some modals. The reason these two pickers are hard to compose is that you bound them with a field.
https://material.io/guidelines/components/pickers.html

How about doing it in this way?

<DateField datePicker={<DatePicker />} timePicker={<TimePicker />} />

<DateField > should just equal to <TextField type="date"> without any pickers.

Also, this issue shouldn't be closed because DatePicker and TimePicker fulfilled in this repo are not following material-design guidelines.

I was able to compose them using openDialog() method on Time Picker. I created a very simple new DateTimePicker component

  showTimePicker() {
    this.refs.timepicker.openDialog();
  }

  render() {
    return (
      <div>
        <DatePicker
          onChange={this.showTimePicker}
        />
        <TimePicker
          ref="timepicker"
          style={{ display: 'none' }}
        />
      </div>
    );
  }
}

as for combining the date and time in one field, we can use the neat way described above by @alxsanborn and leverage the formatDate field to show time in the Date picker text field as well.

demo (datefield not merged yet):

mui-datetimepicker

There is a 3rd party package that joins pickers https://www.npmjs.com/package/material-ui-datetimepicker

I've started a request thread to have something to solve this entered into the MUI spec. There's clearly use cases for this kind of single data-point interface, and since we're all trying to follow MUI's spec, it would be good to have it added so we can all get on the same boat, so to speak: https://github.com/material-components/material-components-web/issues/2042

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  路  3Comments

ryanflorence picture ryanflorence  路  3Comments

FranBran picture FranBran  路  3Comments

mb-copart picture mb-copart  路  3Comments

ghost picture ghost  路  3Comments