Material-ui-pickers: Add ability to select same date in date range picker

Created on 8 May 2020  Â·  22Comments  Â·  Source: mui-org/material-ui-pickers

It possible to select same date to make one day range. It currently gives validation error: https://dev.material-ui-pickers.dev/demo/daterangepicker

image
image

Follow up for https://github.com/mui-org/material-ui-pickers/issues/364#issuecomment-626012154

DateRangePicker enhancement

Most helpful comment

Yes, but it will look like

const [error, setError] = React.useState([null, null])

<DateRange
  onError={([startReason, endReason], [start, end]) => { 
     if (startReason === 'invalidRange' && isSameDay(start, end)) {
       setError([null, null])
       return;
     }

     setError([startReason, endReason])
  })}
  renderInput={props => <TextField {...props} error={Boolean(error[0])} />   }
/>

All 22 comments

For benchmark https://www.google.com/flights and https://www.airbnb.com/ allows selecting the same date while https://www.booking.com/ doesn't.

Would be great to add a prop to the api to allow or not allow the same date validation

I am wondering about the better API for that. Maybe something like minRangeLength and maxRangeLength? That by default will be 1 and null.

@dmtrKovalenko A side but related question. Should we move the validation outside of the DateRangePicker, as we did for the DatePicker?

In this approach, developers would have the following workaround: they could flag same-day selection as valid.

It already has the same validation as DatePicker with onError. But invalidRange reason returns when the start and end dates are the same

It already has the same validation as DatePicker with onError

@dmtrKovalenko So people can already add a conditional to their onError handler?
if reason === 'invalidRange' && startDate === endDate then ignore

Yes, but it will look like

const [error, setError] = React.useState([null, null])

<DateRange
  onError={([startReason, endReason], [start, end]) => { 
     if (startReason === 'invalidRange' && isSameDay(start, end)) {
       setError([null, null])
       return;
     }

     setError([startReason, endReason])
  })}
  renderInput={props => <TextField {...props} error={Boolean(error[0])} />   }
/>

@dmtrKovalenko This looks perfect for the "lazy" solution, to let end-users fall into this trap and get visual/text feedback 👌. However, there is another side to the problem.

I assume the concern now is about: Should the UI prevent this case in the first place? It would give faster feedback in the UI, this sounds fair.

Should it be done with a minRangeLength and maxRangeLength props? What if we went with the most flexible API: A callback method that determines if the user can select a range between two dates? This could extend the support to a use case like this: prevent the end of the range to be a weekend.

Related:

A callback method that determines if the user can select a range between two dates?

I thought about such api, and prepeared special design for this case – we have a function https://github.com/mui-org/material-ui-pickers/blob/7bed283699ef768936a3ec7c5dc89571492dddd4/lib/src/DateRangePicker/date-range-manager.ts#L12

that calculates range changes, we can expose the prop that will replace function and will make possible to significantly customize range picking behavior

@dmtrKovalenko Awesome. Maybe we should wait to get more feedback from the developers before making a step further in any direction :D?

Determining the kind of error in onError is quite awkward and verbose to me...

Taking into account that this component might be part of something like redux-form so all validation would be external, I'd suggest to just allow same date and let external validation to produce an error. And give an ability to provide this error to datepicker.

@kirill-konshin You are free to override the built-in validation. If it's what you are looking for, then you are already covered.

@kirill-konshin You are free to override the built-in validation. If it's what you are looking for, then you are already covered.

Will it allow to suppress the same-day error? Can you point on any example how to do it?

Hi folks.
I'm also having this issue (or wrong behavior to me) and I've seen that the calendar popper does not close when the dates are the same and it should IMHO.

@sergiolenza Interesting, thanks for raising. This makes me think of:

Do you have a preference on how the problem should be fixed?

Currently you can only select an end date that is later than the start date. Selecting the end date first and start date second is not possible. It would be useful to have it go both ways.

Currently you can only select an end date that is later than the start date. Selecting the end date first and start date second is not possible. It would be useful to have it go both ways.

I had that in mind but upon checking Kayak, Google Flights and some others I noticed they are not allowing this. But I personally agree that it’s useful.

That’s where I think exposing custom range strategy should help: https://github.com/mui-org/material-ui-pickers/issues/1759#issuecomment-626604129

@sergiolenza Interesting, thanks for raising. This makes me think of:

  • The selection behavior is inconsistent with the standalone date picker (date range picker closes while date picker doesn't). I have just added it under item 4. in #1682.
  • You have an argument for saying that #1759 (comment) is only good as a workaround, it's not a proper fix.

Do you have a preference on how the problem should be fixed?

I think the issue begins here, where we get ['invalidRange', 'invalidRange'].

var validationError = useDateRangeValidation(value, restProps);

Inside the useDateRangeValidation function:

var useDateRangeValidation = makeValidationHook(validateDateRange, {
  defaultValidationError: [null, null],
  isSameError: function isSameError(a, b) {
    return a[1] === b[1] && a[0] === b[0];
  }
});

I see the isSameError property is forcing the wrong behavior.

So should we can start solve this issue here?

Also I see another wrong behavior related to this issue when I select a range.

A range should be the time between the start of the day of the first day selected and the end of the day of the last day selected.

Makes sense?

Maybe keeping this in mind we get a starting point to solving this issue since we can pick the same day in two dates (start and end) but they are not the same ones.

@dmtrKovalenko What do you think about this resolution?

  1. We use the same default behavior as https://www.daterangepicker.com/#examples, hoping that in 5 years of business as a leading solution, they did some good tradeoff. Same behavior as AntD: users can select the same day without any error.
  2. We introduce a new API for implementing custom range, optimizing for flexibility
/**
 * Determine if the current range can be selected by the user.
 * For instance, it can be used to prevent the selected range to end the weekend.
 */
isRangeAvailable?: (range: [ParsableDate, ParsableDate]) => boolean;

While 1. is breaking, 2. could be implemented later on.

Users can select the same day without any error would be sufficient here imho

Was this page helpful?
0 / 5 - 0 ratings

Related issues

charlax picture charlax  Â·  3Comments

Lysander picture Lysander  Â·  3Comments

Harasz picture Harasz  Â·  3Comments

StevenRasmussen picture StevenRasmussen  Â·  3Comments

killjoy2013 picture killjoy2013  Â·  3Comments