how to stop keyboard cursor to move to starting point - flutter

like i have an edit profile page and inside text form field i populate textform field with existing data but when i press on that textform field i want my cursor to start from the last index of my pre loaded data but the keyboard cursor moves to starting point is there a way to achieve this.
this is my text form field
TextFormField(
decoration:
const InputDecoration(hintText: "First Name"),
validator: (value) {
if (value == null || value.isEmpty) {
return "Please enter your first name";
} else {
return null;
}
},
onChanged: (value) {
firstName = firstNameController.text;
if (firstName.isNotEmpty) {
firstName =
"${firstName[0].toUpperCase()}${firstName.substring(1)}";
firstNameController.selection =
TextSelection.fromPosition(
TextPosition(offset: firstName.length));
}
},
controller: firstNameController..text = firstName,
),
i am able to populate data inside textform field but the problem is when i press on textformfield i want my keyboard starting point to be at the last index of this populated data but keyboard cursor moves to the starting point no matter what need some help here thanks.

You can use selection like this
firstNameController.selection = TextSelection.fromPosition(
TextPosition(
offset: firstNameController.text.length));

Related

Get cursor position in a TextField

I want to create a view with a TextField whose default behavior is disabled (i.e. I don't enable the default keyboard on click).
I created my own keyboard because it allows me to do specific actions for my application.
The keyboard works well and populates the TextField.
My problem
I can't manage the blinking cursor in the TextField. Indeed when I type on my keyboard the cursor follows my text so no problem.
On the other hand, if I decide to click manually in the middle of my text, the cursor moves but the new characters entered do not go to the location of the cursor.
How to do this ?
What does it look like ?
My code
My TextField Widget:
InputAtom(
autofocus: true,
controller: controllerInput,
placeholder: "Placeholder",
fontSize: 35,
keyboard: TextInputType.none,
enableInteractiveSelection: true,
showCursor: true,
cursorColor: Colors.red,
enableSuggestions: false,
autocorrect: false,
),
My button keyboard example:
KeyboardButtonAtom.numeric({
Key? key,
required String text,
required TextEditingController controller,
}): super(
key: key,
text: text,
controller: controller,
onPressed: (){
// Here I add the number typed on the keyboard after
controller.text += text.toString();
// Here the cursor moves to the end of my controller.text
controller.selection = TextSelection.collapsed(offset: controller.text.length);
print(controller.selection.baseOffset);
}
);
How to retrieve the cursor position when I type somewhere by hand in my TextField to be able to add my numbers from the cursor position?
EDIT
In my KeyboardButtonAtom, I do that and it works. Thanks to #Kaushik Chandru
Here is the code that works regardless of the position of the cursor even placed by hand in the middle of your character string
String textBeforeCursor = controller.text.substring(0, controller.selection.baseOffset);
String textAfterCursor = controller.text.substring(controller.selection.extentOffset);
controller.text = textBeforeCursor + text.toString() + textAfterCursor;
int cursorPosition = textBeforeCursor.length + 1;
controller.selection = TextSelection.collapsed(offset: cursorPosition);
To get the current position of the cursor you can try
var cursorPos = _textEditController.selection.base.offset;
String textAfterCursor = _textEditController.text.substring(cursorPos);
String textBeforeCursor = _textEditController.text.substring(0, cursorPos);
_textEditController.text = textBeforeCursor + "someText" + textAfterCursor;
_textEditingController.selection = TextSelection.collapsed(offset: _textEditingController.text.length);

Flutter textfield behaves strange (updating with the wrong value)

I ran into a weird behavior related to the TextFormField, so I maintained a list of Objects in the parent widget, I'm using the following code to render a list of child widgets
children: <Widget>[
...childProfiles
.map((e) => ChildProfileCard(
childProfile: e,
removeChildProfile: removeChildProfile))
.toList(),
And the ChildProfileCard includes a TextFormField, the code is like the following
TextFormField(
decoration: const InputDecoration(
contentPadding: EdgeInsets.only(top: 0),
hintText: "Enter child's name",
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Name is required';
}
return null;
},
),
There is a "remove" function that simply removes one of the items from the list like the following
setState(() {
childProfiles = childProfiles
.where((childProfile) => childProfile.id != childProfileToRemove.id)
.toList();
});
When there are more than two items (two child widgets), I input some texts in the TextFormField in the first child widgets, then I remove the first item, the text will always automatically apply to the second child widget, what did I do wrong? I can confirm the list is correctly updated, but the text behaves strangely.
Before deleting, you can see we have different texts for different widgets
After deleting, the first widget's text is wrongfully copied over to the next widget, you can see the uuid is the second widget's.
You should Use any unique key while building ChildProfileCard
ChildProfileCard(key: Key(<ANY UNIQUE VALUE>),)
Example
ChildProfileCard(key: Key(e.id),)

Flutter Form controller throws "The method 'validate' was called on null"

The method 'validate' was called on null.
Receiver: null
Tried calling: validate()
I don't understand this. I thought maybe the problem was the Form isn't the root element of the class, it's not return Form(child: Column(children: [... So I tried making the Form Widget the root, it stopped the error, but didn't activate the TextFormField validator or save, it just said 'everything fine, move along'.
It's just one field I presently wish to validate. I've looked up other such queries, both the Form widget & the TextFormField have keys, so I'm stuck.
I declare the form key with final _formKeyForDeposit = GlobalKey<FormState>();
And here is the un-cooperative form:
Form(key: _formKeyForDeposit, child:
TextFormField(
controller: _controllerDefaultDeposit,
key: Key('defaultLoanDeposit'),
decoration: InputDecoration(
//icon: Icon(Icons.location_city),
labelText: 'Per item deposit',
hintText: 'Whole numbers',
suffixIcon: IconButton(
icon: Icon(Icons.clear),
onPressed: () {
_controllerDefaultDeposit.clear();
},
),
),
keyboardType: TextInputType.numberWithOptions(decimal: false, signed: false),
onSaved: (String amountStr) {
print("saving deposit");
user.defaultItemDeposit = int.parse(amountStr.trim());
},
validator: (String value) {
print(LOG + "validator called");
if(int.tryParse(value.trim()) == null) {
inputCompletionAlert += "But your default item deposit is not a number, please correct.\n";
return 'Not a £-- whole number monetary amount';
}
if(value == "" || value == "0") {
print(LOG + 'deposit validator called, should launch Dialog from here');
inputCompletionAlert += "Would you like to set a default deposit?";
return "Would you like to set a deposit?";
}
return null;
},
),
),
Have you tried building a custom validator function and then directly calling it from the validator property.
For example :-
Validator (String value) {
print(LOG + "validator called");
if(int.tryParse(value.trim()) == null) {
inputCompletionAlert += "But your default item deposit is not a number, please correct.\n";
return 'Not a £-- whole number monetary amount';
}
}
This was an incomplete question, this array of ExpansionBoxes messes up the validator:
ExpansionPanelList.radio(initialOpenPanelValue: 2,
children: [
bicyclePanel,
carPanel,
floodPanel,
diyPanel,
surplusPanel,
gardeningPanel,
ballSportsPanel,
snowSportsPanel,
waterSportsPanel,
campingPanel,
backpackingPanel,
circusPanel,
]),
I presume that when _formKeyForDeposit.currentState.validate() is called it heads down into the ExpansionPanelList and can't escape to trigger the validator of TextFormFields above it.
Since I only have 1 TextFormField outwidth the ExpansionPanelList, I've used _controllerDefaultDeposit.text to get the Deposit FormField value and manually validate it. It's a hacky solution, but it'll do for now.

how to avoid scrolling to the TEXTFORMFIELD when I force input value to that field in flutter

I have two text form fields that change same value on the same screen in flutter (to make it easier on the user), the user can change the variable from any of the two fields.
The problem is that when the user changes the value in one field (and while still inputting) flutter automatically scrolls to the second field, and even worse the animation is unpredictable sometimes it scrolls back to the original field and sometimes it keeps the view to the second field.
What I need is to make flutter ignore this animation. I want the user to change the value of the text field as a normal iput and in the background flutter would change
the second field, so that is the use of scroll down at some point to the second field he will find the variable updated.
CustomTextFormFieldRow(
maxLength: 5,
suffixText: 'in',
labelText: 'Annular Diam.',
maxInput: kMaxHoleSize,
minInput: _casing.iDiameter(),
controller: _controller1,
onChanged: (value) {
if (value.isNotEmpty &&
value != '.' &&
double.tryParse(value) != null) {
_annularOD = double.tryParse(value);
_controller2.text = value;
} else {
_annularOD = 0;
}
setState(() {
_annularOD;
});
},
),
Here I have a custom form field that I have created, I have created two of those on my screen each having its own controller named one and two, when the user input value add any of them I setState() and change the value of the other controller with _controller2.text = value;
check your controller looks like you have provided the same controller to both text form field.

Output the cursor's position in a Textfield

I have a textfield controller in Flutter and wish to return the position which the cursor occupies in the textfield?
Keep in mind a user may have typed in text then moved the cursor back along the text to say edit the text.
TextField(
onChanged: (value) {
//TODO - Return Cursor Position
}
),
the cursor posistion in text field
first make controller for text field now
TextField(
onChanged: (value) {
int cursorPos = _textController.selection.base.offset;
print(cursorPos);
//TODO - Return Cursor Position
}
),