This is form field code
class CaratMinMaxFields extends FormField<Range> {
final String? title;
/// The minimum allowed value for the range. Defaults to 0.
final double minValue;
/// The maximum allowed value for the range. Defaults to 100.
final double maxValue;
/// A callback function called when the range values change.
/// This callback getting triggered does not mean the text field have validated value.
final ValueChanged<Range?>? onChanged;
final TextEditingController minController;
final TextEditingController maxController;
final AutovalidateMode? validateMode;
final Range? range;
static bool _fakeValidator = true;
CaratMinMaxFields({
this.title,
this.minValue = 0,
this.maxValue = 100,
this.onChanged,
this.validateMode = AutovalidateMode.disabled,
this.range,
required this.minController,
required this.maxController,
super.key,
}) : super(
autovalidateMode: validateMode,
initialValue: range,
validator: (Range? range) {
if (_fakeValidator) return null;
if (range == null || (range.from == null && range.to == null)) {
return AppRouter.navigatorKey.currentContext?.localizations
.enterValueRangeErrorWithString('0.15', '50.00');
}
if (range.from == null) {
return AppRouter.navigatorKey.currentContext?.localizations
.fromFieldCannotBeEmpty;
}
if (range.to == null) {
return AppRouter.navigatorKey.currentContext?.localizations
.toFieldCannotBeEmpty;
}
final isFromGreaterThanTo =
(range.from ?? double.maxFinite) > (range.to ?? 0);
final isFromSmallerThanMinValue =
(range.from ?? double.maxFinite) < minValue;
final isToGreaterThanMaxValue =
(range.to ?? double.maxFinite) > maxValue;
if (isFromGreaterThanTo) {
return AppRouter.navigatorKey.currentContext?.localizations
.minGreaterThanMaxValueError;
}
if (isFromSmallerThanMinValue || isToGreaterThanMaxValue) {
return AppRouter.navigatorKey.currentContext?.localizations
.enterValueRangeErrorWithString(
minValue.toStringAsFixed(2),
maxValue.toStringAsFixed(2));
}
return null;
},
builder: (FormFieldState<Range> state) {
return Builder(
builder: (context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (title != null) ...{
Text(
title,
style: CoreTextStyle.sRegular,
),
16.height,
},
Row(
children: [
Expanded(
flex: 3,
child: CoreLeadingInputField(
title: context.localizations.from,
controller: minController,
onChanged: (value) {
_fakeValidator = true;
final fromValueInNum =
num.tryParse(value.replaceAll(",", "."));
if (fromValueInNum == null) {
if (state.value?.to == null) {
state.reset();
state.didChange(const Range());
} else {
state.didChange(
(Range(to: state.value?.to)),
);
}
} else {
state.didChange(
(state.value ?? const Range())
.copyWith(from: fromValueInNum),
);
}
state.validate();
_fakeValidator = false;
onChanged?.call(state.value);
},
keyboardType: const TextInputType.numberWithOptions(
decimal: true,
),
textInputFormatter: [
FilteringTextInputFormatter.allow(
twoDecimalPlaceNumber,
),
],
hasError: state.hasError,
),
),
const Spacer(),
Expanded(
flex: 3,
child: CoreLeadingInputField(
title: context.localizations.to,
controller: maxController,
onChanged: (value) {
debugPrint('onChanged-----$value');
_fakeValidator = true;
final toValueInNum =
num.tryParse(value.replaceAll(",", "."));
if (toValueInNum == null) {
if (state.value?.from == null) {
state.reset();
state.didChange(const Range());
} else {
state.didChange(
Range(from: state.value?.from),
);
}
} else {
state.didChange(
(state.value ?? const Range()).copyWith(
to: toValueInNum,
),
);
}
state.validate();
_fakeValidator = false;
onChanged?.call(state.value);
},
keyboardType: const TextInputType.numberWithOptions(
decimal: true,
),
textInputFormatter: [
FilteringTextInputFormatter.allow(
twoDecimalPlaceNumber,
),
],
hasError: state.hasError,
),
),
],
),
if (state.hasError) ...{
4.height,
Text(
state.errorText!,
style: CoreTextStyle.sRegular.copyWith(
color: context.colorScheme.error,
),
),
},
],
);
},
);
},
);
@override
FormFieldState<Range> createState() => CaratMinMaxTextFields();
}
class CaratMinMaxTextFields extends FormFieldState<Range> {
@override
void didUpdateWidget(covariant FormField<Range> oldWidget) {
setValue(widget.initialValue);
validate();
super.didUpdateWidget(oldWidget);
}
}
After click on plus button validation should be disable, But first time when we click on plus button without entring value should show error, once valid value edited and click on plus button should add in list that is working, But on plus button when value is right after addition no message should shown