skip to Main Content

I have the following code with a DateTimeRange and I would like to allow the user to select a range without exceed 15 days. For example a range before today will be 02/02 to 02/16 or lower or after today 02/14 to 03/01 or lower. How can I do that if it’s possible ?

class DateRangeView extends StatefulWidget {
  late bool isClearClicked;

  DateRangeView({Key? key, required this.isClearClicked}) : super(key: key);

  @override
  DateRangeView createState() => DateRangeViewState();
}

class DateRangeViewState extends State<DateRangeView> {
  DateTimeRange? dateRange;
  DateTimeRange? initialDateRange;
  DateTimeRange? newDateRange;

  String getFrom() {
    if (dateRange == null) {
      return DateTime.now().toRangeDate();
    } else {
      return dateRange!.start.toRangeDate();
    }
  }

  String getUntil() {
    if (dateRange == null) {
      return DateTime.now().toRangeDate();
    } else {
      return dateRange!.end.toRangeDate();
    }
  }

  @override
  Widget build(BuildContext context) {
    return HeaderWidget(
      title: Translation.current.period.toUpperCase(),
      child: Row(
        children: [
          Expanded(
            child: ButtonWidget(
              text: widget.isClearClicked
                  ? DateTime.now().toRangeDate()
                  : getFrom(),
              onClicked: () => pickDateRange(context),
            ),
          ),
          Text(Translation.current.untilDateKeyword.toUpperCase(),
            style:
            TextStyle(fontSize: ThemeSize.text(xl), color: ThemeColor.gray500),
          ),
          Expanded(
            child: ButtonWidget(
              text: widget.isClearClicked
                  ? DateTime.now().toRangeDate()
                  : getUntil(),
              onClicked: () => pickDateRange(context),
            ),
          ),
          Icon( Icons.calendar_month_rounded, color: ThemeColor.gray600,),
        ],
      ),
    );
  }

  Future pickDateRange(BuildContext context) async {
      initialDateRange = DateTimeRange(
      start: DateTime.now(),
      end: DateTime.now(),
    );
    newDateRange = await showDateRangePicker(
      initialEntryMode: DatePickerEntryMode.calendarOnly,
      context: context,
      firstDate: DateTime(2022),
      lastDate: DateTime(2030),
      initialDateRange: dateRange ?? initialDateRange,
        builder: (context, Widget? child) => Theme(
          data:ThemeData.light().copyWith(
            //Header background color
            primaryColor: ThemeColor.primaryVariant,
            scaffoldBackgroundColor: Colors.grey[50],
            dividerColor: Colors.grey,
            textTheme: TextTheme(
              bodyText2:
              TextStyle(color: ThemeColor.gray700, fontSize: ThemeSize.text(xxl)),
            ),
            colorScheme: ColorScheme.fromSwatch().copyWith(
              primary: ThemeColor.primaryVariant,
              onSurface: Colors.black,
            ),
          ),
          child: child!,
        ),
    );

    if (newDateRange == null) return;

    setDateRange();
  }

  setDateRange() {
    setState(() {
      dateRange = newDateRange;
      widget.isClearClicked = false;
    });
    Future.delayed(
      const Duration(milliseconds: 100), () {
        dateRange = initialDateRange;
        },
    );
  }
}

2

Answers


  1. You can change this two params to :

    firstDate: DateTime.now(),
     lastDate: DateTime.now().add(Duration(days: 15)),
    
    Login or Signup to reply.
  2. You can use syncfusion_flutter_datepicker library. It has a selectionChanged callback that you can manipulate to limit selectable dates on the go. This is my answer to a similar question

    class Home extends StatefulWidget {
      const Home({super.key});
    
      @override
      State<Home> createState() => _HomeState();
    }
    
    class _HomeState extends State<Home> {
      final DateTime _minDate = DateTime.now();
      DateTime _maxDate = DateTime.now().add(const Duration(days: 365));
    
      final Duration _duration = const Duration(days: 14);
    
      DateTime _start = DateTime.now();
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: SafeArea(
              child: SfDateRangePicker(
            minDate: _minDate,
            maxDate: _maxDate,
            selectionMode: DateRangePickerSelectionMode.range,
            onSelectionChanged: (DateRangePickerSelectionChangedArgs args) {
              if (args.value is PickerDateRange) {
                _start = (args.value as PickerDateRange).startDate!;
                setState(() {
                  // limit the maxDate to 14 days from selected date
                  _maxDate = _start.add(_duration);
                });
              }
            },
          )),
        );
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search