146 lines
4.4 KiB
Dart
146 lines
4.4 KiB
Dart
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:month_picker_dialog/month_picker_dialog.dart';
|
|
|
|
class ThemedDateField extends StatefulWidget {
|
|
const ThemedDateField({
|
|
super.key,
|
|
this.hintText,
|
|
this.txtwidth,
|
|
this.txtheight,
|
|
this.backgroundColor,
|
|
this.borderColor,
|
|
this.errorBorderColor,
|
|
this.onDateSelected,
|
|
this.controller,
|
|
this.validator,
|
|
this.lastDate, // ✅ new
|
|
this.firstDate,
|
|
});
|
|
|
|
final String? hintText;
|
|
final double? txtwidth;
|
|
final double? txtheight;
|
|
final Color? backgroundColor;
|
|
final Color? borderColor;
|
|
final Color? errorBorderColor;
|
|
final TextEditingController? controller;
|
|
final Function(DateTime)? onDateSelected;
|
|
final String? Function(String? value)? validator; // ✅ new
|
|
final DateTime? lastDate;
|
|
final DateTime? firstDate;
|
|
|
|
@override
|
|
State<ThemedDateField> createState() => _ThemedDateFieldState();
|
|
}
|
|
|
|
class _ThemedDateFieldState extends State<ThemedDateField> {
|
|
DateTime? selectedDate;
|
|
|
|
Future<void> pickDate(
|
|
BuildContext context,
|
|
FormFieldState<String> field,
|
|
) async {
|
|
DateTime initialDate =
|
|
selectedDate ??
|
|
(widget.controller?.text.isNotEmpty == true
|
|
? DateFormat('dd-MM-yyyy').parse(widget.controller!.text)
|
|
: DateTime.now());
|
|
final pickedDate = await showDatePicker(
|
|
context: context,
|
|
initialDate: initialDate,
|
|
firstDate: widget.firstDate ?? DateTime(2000),
|
|
// lastDate: DateTime(2100),
|
|
lastDate: widget.lastDate ?? DateTime(2100),
|
|
initialEntryMode: DatePickerEntryMode.calendarOnly,
|
|
);
|
|
|
|
if (pickedDate != null) {
|
|
setState(() => selectedDate = pickedDate);
|
|
|
|
final formattedDate = DateFormat('dd-MM-yyyy').format(pickedDate);
|
|
widget.controller?.text = formattedDate;
|
|
widget.onDateSelected?.call(pickedDate);
|
|
|
|
field.didChange(formattedDate); // ✅ notify form validation
|
|
}
|
|
}
|
|
|
|
@override
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return FormField<String>(
|
|
validator: widget.validator,
|
|
initialValue: widget.controller?.text,
|
|
builder: (field) {
|
|
final hasError = field.hasError;
|
|
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
InkWell(
|
|
onTap: () => pickDate(context, field),
|
|
|
|
borderRadius: BorderRadius.circular(10),
|
|
child: Container(
|
|
width: widget.txtwidth ?? MediaQuery.of(context).size.width,
|
|
height: widget.txtheight,
|
|
padding: const EdgeInsets.symmetric(
|
|
vertical: 8,
|
|
horizontal: 15,
|
|
),
|
|
decoration: BoxDecoration(
|
|
color: widget.backgroundColor ?? Colors.white,
|
|
borderRadius: BorderRadius.circular(10),
|
|
border: Border.all(
|
|
color: hasError
|
|
? (widget.errorBorderColor ?? Color(0xFFD83731))
|
|
: (widget.borderColor ?? Color(0xFFE2E8F0)),
|
|
width: 1,
|
|
),
|
|
),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Expanded(
|
|
child: Text(
|
|
widget.controller?.text.isNotEmpty == true
|
|
? widget.controller!.text
|
|
: widget.hintText ?? "Select Date",
|
|
style: TextStyle(
|
|
fontSize: 11,
|
|
color: hasError ? Color(0xFFD83731) : Colors.black,
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
const Icon(
|
|
Icons.calendar_today,
|
|
size: 16,
|
|
|
|
color: Color(0xFF5A6C7D),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
|
|
if (hasError)
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 5, left: 5),
|
|
child: Text(
|
|
field.errorText ?? '',
|
|
style: const TextStyle(
|
|
color: Color(0xFFD83731),
|
|
fontSize: 10,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|