theideasaler / calendar_date_picker2

Lightweight and highly customizable calendar picker built on Flutter's original CalendarDatePicker, with support for multi and range modes.
https://pub.dev/packages/calendar_date_picker2
Apache License 2.0
128 stars 151 forks source link

[Feature]when a third date is selected, instead of resetting range to empty, replace date closest to the new date #218

Open macMikey opened 1 month ago

macMikey commented 1 month ago

still a dart/flutter n00b, but, i managed to implement a feature i wanted, so now i'm proposing it, before i issue a PR:

use cases:

  1. (nearest end of the range changes): planning a vacation. the user selects two dates, but the flights don't work for the return day, so they tap a different day, that is closer to the end of the range. the end date is switched. that flight works, but now, that also means they will use too much vacation, so they want to shift the start date, as well.
  2. (keeping one end of the range fixed): a scheduling app is used to decide when to schedule an audit. the audit must occur before a certain date. we can play around with different start dates for the window, depending on some factor, and notify the auditor of the range.
sdzfg347 commented 1 month ago

hi @macMikey, if I understand your request correctly. You want to make one end of the range fixed, e.g. fixed startDate or endDate.

This is achievable with current implementation. What you need is to tweak the dates yield from the onValueChanged. e.g.

    value: _rangeDatePickerValueWithDefaultValue,
    onValueChanged: (dates) {
      setState(() => _rangeDatePickerValueWithDefaultValue = [
            DateTime(1999, 5, 1),
            dates.last
          ]);
    }),

Above is an example of fixing the start date of a range.

macMikey commented 1 month ago

that was suggestion 2. suggestion 1 was the one that is more interesting to me: don't clear the range when another date is selected, instead replace the one that is closest to the newly-selected date. there are any number of websites (say, for making hotel reservations) that reset the range rather than modifying it, which is really annoying.

sdzfg347 commented 1 month ago

I think this is still achievable with the current implementation - CalendarDatePicker2 does not hold any dates, the dates passed into it will be always rendered on the UI.

So if you want to modify the selection range to replace closest date, you will need to check which one is closer inside onValueChanged and then modify the value passed into CalendarDatePicker2. Take the example app as a sample and assume you already have a range selected.

    value: _rangeDatePickerValueWithDefaultValue,
    onValueChanged: (dates) {
      setState(() {
         // get the newly selectedDate: dates.first
         // check selectedDate is closer to _rangeDatePickerValueWithDefaultValue.first or _rangeDatePickerValueWithDefaultValue.last
        // replace _rangeDatePickerValueWithDefaultValue.first or _rangeDatePickerValueWithDefaultValue.last with the newy selected date
      });
    }),
macMikey commented 1 month ago

that's if you build you own dialog. i was suggesting adding a feature to the library so someone does not have to build their own dialog.

sdzfg347 commented 1 month ago

This will be off the plan right now since it is only for the dialog method not the main widget.

Implement a custom dialog method shouldn't be too different and complex.

sdzfg347 commented 1 week ago

@macMikey Your understanding is correct that CalendarDatePicker2WithActionButtons will emit values only when user hits 'OK' - so to meet your needs, you will need to use CalendarDatePicker2 widget directly inside your custom dialog.

macMikey commented 1 week ago

so are you ok with a pr to change that, since that means CalendarDatePicker2WithActionButtons is not usable, in this scenario, as-is?

sdzfg347 commented 1 week ago

@macMikey no, this won't be accepted by the package - CalendarDatePicker2WithActionButtons is just a lightweight handy widget, any customisation can be done by creating your own CalendarDatePicker2WithActionButtons widget