Reputation: 5865
*****EDIT******* So now I have it formatting as I expect, anyone have an idea why once it is in the textfield, if they type an extra character or make a mistake why they would not be able to backspace and delete? Here is the working code for formatting.
class _DateFormatter 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 = new StringBuffer();
/*if (newTextLength >= 1) {
newText.write('');
if (newValue.selection.end >= 1)
selectionIndex++;
}*/
if (newTextLength >= 2) {
newText.write(newValue.text.substring(0, usedSubstringIndex = 2) + '/');
if (newValue.selection.end >= 3)
selectionIndex += 2;
}
if (newTextLength >= 5) {
newText.write(newValue.text.substring(2, usedSubstringIndex = 4) + '/');
if (newValue.selection.end >= 5)
selectionIndex +=2;
}
if (newTextLength == 10) {
newText.write(newValue.text.substring(4, usedSubstringIndex = 8) + '');
if (newValue.selection.end >= 9)
selectionIndex +=4;
}
// Dump the rest.
if (newTextLength >= usedSubstringIndex)
newText.write(newValue.text.substring(usedSubstringIndex));
return new TextEditingValue(
text: newText.toString(),
selection: new TextSelection.collapsed(offset: selectionIndex),
);
}
}
Any help is appreciated. Also can anyone think of a reason it does not work the same in Android as in iOS?
Upvotes: 0
Views: 2135
Reputation: 53327
You can use a Row
of three TextField
s for (DD/MM/YY) respectively.
Using TextEditingController
you can put some limits on your text being typed however you like (e.g: 2 keyboard inputs for day/month, 4 for a year). Moreover, you can shift the focus of the TextField
when the limits of the current one has been reached:
_dayFocus.unfocus();
, unsubscribes the day TextField
from the keyboard.FocusScope.of(context).requestFocus(_monthFocus);
, shifts the focus to the month TextField
, and so on.Example:
Code:
import "package:flutter/material.dart";
import 'package:flutter/src/services/text_editing.dart';
class DateFormat extends StatefulWidget {
@override
_DateFormatState createState() => new _DateFormatState();
}
class _DateFormatState extends State<DateFormat> {
TextEditingController _dayController = new TextEditingController();
String day = "";
FocusNode _dayFocus = new FocusNode();
bool _dayFocused = true;
TextEditingController _monthController = new TextEditingController();
String month = "";
FocusNode _monthFocus = new FocusNode();
//bool _monthFocused=false;
TextEditingController _yearController = new TextEditingController();
String year = "";
FocusNode _yearFocus = new FocusNode();
//bool _yearFocused;
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
appBar: new AppBar(title: new Text("Date Format"),),
body: new Row(
children: <Widget>[ new Flexible (
child: new TextField(
keyboardType: TextInputType.datetime,
autofocus: _dayFocused,
focusNode: _dayFocus,
controller: _dayController,
onChanged: (value) {
if (value.length <= 2) {
//save
day = value;
}
else {
_dayFocus.unfocus();
FocusScope.of(context).requestFocus(_monthFocus);
// _monthFocused =true;
_dayController.value = new TextEditingValue(
text: day,
composing: new TextRange(
start: 0,
end: 2,
)
);
}
},
),),
new Text("/"),
new Flexible (
child: new TextField(
keyboardType: TextInputType.datetime,
focusNode: _monthFocus,
controller: _monthController,
onChanged: (value) {
if (value.length <= 2) {
//save
month = value;
}
else {
_monthFocus.unfocus();
FocusScope.of(context).requestFocus(_yearFocus);
_monthController.value = new TextEditingValue(
text: month,
composing: new TextRange(
start: 0,
end: 2,
)
);
}
},
),),
new Text("/"),
new Flexible (
child: new TextField(
keyboardType: TextInputType.datetime,
focusNode: _yearFocus,
controller: _yearController,
onChanged: (value) {
if (value.length <= 4) {
//save
year = value;
}
else {
_yearFocus.unfocus();
_yearController.value = new TextEditingValue(
text: year,
composing: new TextRange(
start: 0,
end: 4,
)
);
}
},
onSubmitted: (value) =>
_scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text("Your date is $day/$month/$value"))),),),
],),);
}
}
UPDATE
To ignore the slash event, we need to update the next TextEditingController
with the third input so it carries on like this:
import "package:flutter/material.dart";
import 'package:flutter/src/services/text_editing.dart';
class DateFormat extends StatefulWidget {
@override
_DateFormatState createState() => new _DateFormatState();
}
class _DateFormatState extends State<DateFormat> {
TextEditingController _dayController = new TextEditingController();
String day = "";
FocusNode _dayFocus = new FocusNode();
bool _dayFocused = true;
TextEditingController _monthController = new TextEditingController();
String month = "";
FocusNode _monthFocus = new FocusNode();
//bool _monthFocused=false;
TextEditingController _yearController = new TextEditingController();
String year = "";
FocusNode _yearFocus = new FocusNode();
//bool _yearFocused;
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
appBar: new AppBar(title: new Text("Date Format"),),
body: new Row(
children: <Widget>[ new Flexible (
child: new TextField(
keyboardType: TextInputType.datetime,
autofocus: _dayFocused,
focusNode: _dayFocus,
controller: _dayController,
onChanged: (value) {
if (value.length <= 2) {
//save
day = value;
}
else {
_dayFocus.unfocus();
_monthController.text = value[2];
_monthController.selection=new TextSelection.collapsed(offset: 1);
FocusScope.of(context).requestFocus(_monthFocus);
// _monthFocused =true;
_dayController.value = new TextEditingValue(
text: day,
composing: new TextRange(
start: 0,
end: 2,
)
);
}
},
),),
new Text("/"),
new Flexible (
child: new TextField(
keyboardType: TextInputType.datetime,
focusNode: _monthFocus,
controller: _monthController,
onChanged: (value) {
if (value.length <= 2) {
//save
//_monthController.text = value;
month = value;
}
else {
_yearController.text = value[2];
_yearController.selection=new TextSelection.collapsed(offset: 1);
_monthFocus.unfocus();
FocusScope.of(context).requestFocus(_yearFocus);
_monthController.value = new TextEditingValue(
text: month,
// selection: new TextSelection(baseOffset: 1, extentOffset: 1),
composing: new TextRange(
start: 0,
end: 2,
)
);
}
},
),),
new Text("/"),
new Flexible (
child: new TextField(
keyboardType: TextInputType.datetime,
focusNode: _yearFocus,
controller: _yearController,
onChanged: (value) {
if (value.length <= 4) {
//save
year = value;
}
else {
_yearFocus.unfocus();
_yearController.value = new TextEditingValue(
text: year,
composing: new TextRange(
start: 0,
end: 4,
)
);
}
},
onSubmitted: (value) =>
_scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text("Your date is $day/$month/$value"))),),),
],),);
}
}
Upvotes: 1