You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
HMG_Patient_App/lib/widgets/input/text_field.dart

268 lines
9.2 KiB
Dart

import 'package:hmg_patient_app/theme/colors.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class NumberTextInputFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
final int newTextLength = newValue.text.length;
int selectionIndex = newValue.selection.end;
int usedSubstringIndex = 0;
final StringBuffer newText = StringBuffer();
if (newTextLength >= 1) {
newText.write('(');
if (newValue.selection.end >= 1) selectionIndex++;
}
if (newTextLength >= 4) {
newText.write(newValue.text.substring(0, usedSubstringIndex = 3) + ') ');
if (newValue.selection.end >= 3) selectionIndex += 2;
}
if (newTextLength >= 7) {
newText.write(newValue.text.substring(3, usedSubstringIndex = 6) + '-');
if (newValue.selection.end >= 6) selectionIndex++;
}
if (newTextLength >= 11) {
newText.write(newValue.text.substring(6, usedSubstringIndex = 10) + ' ');
if (newValue.selection.end >= 10) selectionIndex++;
}
// Dump the rest.
if (newTextLength >= usedSubstringIndex) newText.write(newValue.text.substring(usedSubstringIndex));
return TextEditingValue(
text: newText.toString(),
selection: TextSelection.collapsed(offset: selectionIndex),
);
}
}
final _mobileFormatter = NumberTextInputFormatter();
class TextFields extends StatefulWidget {
TextFields(
{Key? key,
this.type,
this.hintText,
this.suffixIcon,
this.autoFocus,
this.onChanged,
this.initialValue,
this.minLines,
this.maxLines,
this.inputFormatters,
this.padding,
this.focus = false,
this.maxLengthEnforced = true,
this.suffixIconColor,
this.inputAction,
this.onSubmit,
this.keepPadding = true,
this.textCapitalization = TextCapitalization.none,
this.controller,
this.keyboardType,
this.validator,
this.borderOnlyError = false,
this.onSaved,
this.onSuffixTap,
this.readOnly = false,
this.maxLength,
this.prefixIcon,
this.bare = false,
this.onTap,
this.fontSize = 16.0,
this.fontWeight = FontWeight.w700,
this.fillColor,
this.hintColor})
: super(key: key);
final String? hintText;
final String? initialValue;
final String? type;
final bool? autoFocus;
final IconData? suffixIcon;
final Color? suffixIconColor;
final Icon? prefixIcon;
final VoidCallback? onTap;
final TextEditingController? controller;
final TextInputType? keyboardType;
final FormFieldValidator? validator;
final Function(String?)? onSaved;
final VoidCallback? onSuffixTap;
final Function(String?)? onChanged;
final Function(String?)? onSubmit;
final bool? readOnly;
final int? maxLength;
final int? minLines;
final int? maxLines;
final bool? maxLengthEnforced;
final bool? bare;
final TextInputAction? inputAction;
final double? fontSize;
final FontWeight? fontWeight;
final bool? keepPadding;
final TextCapitalization? textCapitalization;
final List<TextInputFormatter>? inputFormatters;
final EdgeInsets? padding;
final bool? focus;
final bool? borderOnlyError;
final Color? hintColor;
final Color? fillColor;
@override
_TextFieldsState createState() => _TextFieldsState();
}
class _TextFieldsState extends State<TextFields> {
final FocusNode _focusNode = FocusNode();
bool? focus = false;
bool? view = false;
@override
void initState() {
super.initState();
_focusNode.addListener(() {
setState(() {
focus = _focusNode.hasFocus;
});
});
}
@override
void didUpdateWidget(TextFields oldWidget) {
if (widget.focus != null) _focusNode.requestFocus();
super.didUpdateWidget(oldWidget);
}
@override
void dispose() {
_focusNode.dispose();
super.dispose();
}
Widget _buildSuffixIcon() {
switch (widget.type) {
case "password":
return Padding(
padding: const EdgeInsets.only(right: 8.0),
child: view!
? InkWell(
onTap: () {
this.setState(
() {
view = false;
},
);
},
child: Icon(
Icons.remove_red_eye_sharp,
size: 24.0,
color: Color.fromRGBO(78, 62, 253, 1.0),
),
)
: InkWell(
onTap: () {
this.setState(() {
view = true;
});
},
child: Icon(Icons.remove_red_eye_sharp, size: 24.0, color: Colors.grey[500]),
),
);
default:
if (widget.suffixIcon != null)
return InkWell(
onTap: widget.onSuffixTap,
child: Icon(widget.suffixIcon, size: 22.0, color: widget.suffixIconColor != null ? widget.suffixIconColor : Colors.grey[500]),
);
else
return SizedBox();
}
}
bool _determineReadOnly() {
if (widget.readOnly != null && widget.readOnly!) {
_focusNode.unfocus();
return true;
} else {
return false;
}
}
@override
Widget build(BuildContext context) {
return (AnimatedContainer(
duration: Duration(milliseconds: 300),
decoration: widget.bare!
? null
: BoxDecoration(boxShadow: [
// BoxShadow(
// color: Color.fromRGBO(70, 68, 167, focus ? 0.20 : 0),
// offset: Offset(0.0, 13.0),
// blurRadius: focus ? 34.0 : 12.0)
BoxShadow(color: Color.fromRGBO(110, 68, 80, focus! ? 0.20 : 0), offset: Offset(0.0, 13.0), blurRadius: focus! ? 34.0 : 12.0)
]),
child: TextFormField(
keyboardAppearance: Theme.of(context).brightness,
scrollPhysics: BouncingScrollPhysics(),
textCapitalization: widget.textCapitalization!,
onFieldSubmitted: widget.inputAction! == TextInputAction.next!
? (widget.onSubmit! != null
? widget.onSubmit!
: (val) {
_focusNode.nextFocus!();
})
: widget.onSubmit!,
textInputAction: widget.inputAction,
minLines: widget.minLines ?? 1,
maxLines: widget.maxLines ?? 1,
// maxLengthEnforcement: widget.maxLengthEnforced,
initialValue: widget.initialValue,
onChanged: widget.onChanged!,
focusNode: _focusNode,
maxLength: widget.maxLength ?? null,
controller: widget.controller,
keyboardType: widget.keyboardType,
readOnly: _determineReadOnly(),
obscureText: widget.type == "password" && !view! ? true : false,
autofocus: widget.autoFocus ?? false,
validator: widget.validator,
onSaved: widget.onSaved,
// style: Theme.of(context)
// .textTheme
// .bodyText1!
// .copyWith(fontSize: widget.fontSize, fontWeight: widget.fontWeight),
style: TextStyle(color: Colors.black, letterSpacing: 0.6, fontSize: widget.fontSize, fontWeight: widget.fontWeight),
inputFormatters: widget.keyboardType == TextInputType.phone
? <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly,
_mobileFormatter,
]
: widget.inputFormatters,
decoration: InputDecoration(
counterText: "",
hintText: widget.hintText,
hintStyle: TextStyle(
fontSize: widget.fontSize,
fontWeight: widget.fontWeight,
color: widget.hintColor ?? Theme.of(context).hintColor,
),
contentPadding: widget.padding != null ? widget.padding : EdgeInsets.symmetric(vertical: (widget.bare! && !widget.keepPadding!) ? 0.0 : 10.0, horizontal: 16.0),
filled: true,
fillColor: widget.bare! ? Colors.transparent : CustomColors.white,
suffixIcon: _buildSuffixIcon(),
prefixIcon: widget.prefixIcon,
errorStyle: TextStyle(fontSize: 14.0, fontWeight: widget.fontWeight, height: widget.borderOnlyError! ? 0.0 : null),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: CustomColors.accentColor.withOpacity(widget.bare! ? 0.0 : 0.5), width: 1.0), borderRadius: BorderRadius.circular(widget.bare! ? 0.0 : 8.0)),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(color: CustomColors.accentColor.withOpacity(widget.bare! ? 0.0 : 0.5), width: 1.0), borderRadius: BorderRadius.circular(widget.bare! ? 0.0 : 8.0)),
focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.grey, width: 1.0), borderRadius: BorderRadius.circular(widget.bare! ? 0.0 : 8.0)),
disabledBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.grey, width: 1.0), borderRadius: BorderRadius.circular(widget.bare! ? 0.0 : 8.0)),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 1.0),
borderRadius: BorderRadius.circular(widget.bare! ? 0.0 : 8.0),
),
),
),
));
}
}