If I have this:
class SomethingState extends State<Something> {
String name;
#override
Widget build(BuildContext context) {
return TextField(
onChange: (text) {
name = text
}
)
}
}
Do I have to wrap name = text in setState to trigger the build method or no because when the user types something in the TextField it already does that?
This is how I have it now and it works, but I want to make sure I understand this correctly.
The value will change without setState but will not change on the UI. To update the UI you must use setState and rebuild the widgets.
This code for the question in the comments
class Homepage extends StatelessWidget {
final controller = TextEditingController();
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Center(child: TextField(controller: controller,),),
FlatButton(child: Text("change"),onPressed: (){
controller.text = 'new text';
},)
],
);
}
}
Related
There's a button on my home page which when clicked should redirect me to another page and click on textformfield on that page,I dont know how to do that
just use autofocus: true on another page
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: TextButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) {
return NextPage();
},
));
},
child: Text("Click")),
),
);
}
}
class NextPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: TextField(
autofocus: true,
),
);
}
}
There is multiple ways to do this depending on your use case
1- if you want to focus on the text form field every time you enter the page you change autofocus property in the textField to true,
TextField(
autofocus:true,
)
2- if you want to trigger focus on a textfield by manually you can use FocusNode object, this focus node will be attached to your text field.
First you need to initialize the object.
FocusNode myFocusNode;
#override
void initState() {
super.initState();
myFocusNode = FocusNode();
}
#override
void dispose() {
// Clean up the focus node when the Form is disposed.
myFocusNode.dispose();
super.dispose();
}
then Attach the focus node object to your text field
TextField(
focusNode: myFocusNode,
);
Now you can use this focus node in a function to focus on this text
// focus on textfield (same as text field pressed)
myFocusNode.requestFocus()
// unfocus on textfield (same as pressing done on textfield or pressing the back button)
myFocusNode.unfocus()
you can pass a flag to the new page you are going to, which will trigger the focus function
I'm trying to insert an initial value to the flutter_quill flutter text editor with no success. Link to package https://pub.dev/packages/flutter_quill . From a normal TextField I would have done something like below using the controller.
class _FooState extends State<Foo> {
TextEditingController _controller;
#override
void initState() {
super.initState();
_controller = new TextEditingController(text: 'Initial value');
}
#override
Widget build(BuildContext context) {
return new Column(
children: <Widget>[
new TextField(
// The TextField is first built, the controller has some initial text,
// which the TextField shows. As the user edits, the text property of
// the controller is updated.
controller: _controller,
),
],
);
}
}
I appreciate your help.
usually I can disable/grey-out a button until a TextFormField meets certain parameters in flutter by something like this:
TextFormField(
controller: _controller
value: (value)
)
SubmitButton(
onPressed: _controller.text.isNotEmpty ? _submit : null;
)
But when compiled as a website the Button seems no longer aware of the controller value...
I have tried targeting in several different ways, e.g. _controller.value.text.isEmpty and _controller.text.isEmpty...
I'm guessing I'm missing something or this method just isn't possible for web ... Is there any other way to get the same result?
To be honest, your code shouldn't work in flutter mobile either, but may be works because of screen keyboard causes widget rebuild when showing or hiding.
To fix this issue we have to use stateful widget with state variable like canSubmit and update it in textField's listener onChange with setState method. Then every time the text changes, our stateful widget will update the submit button..
class Page extends StatefulWidget {
#override
_PageState createState() => _PageState();
}
class _PageState extends State<Page> {
bool canSubmit;
#override
void initState() {
canSubmit = false;
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
TextField(
onChanged: (value) {
setState(() {
canSubmit = value.isNotEmpty;
});
},
),
RaisedButton(
onPressed: canSubmit ? _submit : null,
child: Text('Submit'),
)
],
),
),
);
}
void _submit() {
print('Submitted');
}
}
I have the following problem. In a stateful widget (1), which contains a text field, a stateful widget (2) is called, which outputs a text. If an entry was made in the stateful widget (1), the stateful widget (2) should output the current text. (So it has to be updated).
Here is my sample code that unfortunately doesn't work:
class _TexfildState extends State<Texfild> {
String text;
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
TextField(
onChanged: (str){
setState(() {
text = str;
});
},
),
Textprint(text) //This widget should reload if str changes!
],
);
}
}
class Textprint extends StatefulWidget {
#override
final String textprint;
Textprint(this.textprint);
_TextprintState createState() => _TextprintState();
}
class _TextprintState extends State<Textprint> {
#override
Widget build(BuildContext context) {
return Container(
child: Text(widget.textprint),
);
}
}
What you need to do is to initialize the text with value or so called empty string. Because TextPrint Widget can't receive null String.
String text = '';
the TextFiled class
class InputContainer extends StatefulWidget{
final _InputContainerInner input = new _InputContainerInner();
#override
State<StatefulWidget> createState() {
return input;
}
}
class _InputContainerInner extends State<InputContainer>{
TextEditingController controller = TextEditingController();
String num = '';
#override
Widget build(BuildContext context) {
return Container(
...
child: TextField(
...
controller: controller,
...
)
)
}
i use it in another file
Widget build(BuildContext context) {
InputContainer passWord = new InputContainer();
return Scaffold(
body: new Column(
children: <Widget>[
passWord,
new MaterialButton(
onPressed: () {
print(passWord.input);
print(passWord.input.num);
}
)
]
)
}
i click the button , but got nothing of this TextFiled, print result is
flutter: InputContainerInner#9818c(lifecycle state: created, no widget, not mounted)
flutter:
maybe it is the matter of lifecycle, but i have made it in the widget , what happen ?
Maybe U can save it in some variable e.g.
String password = controller.text
then call it from other class by creating object or something
I think you shouldn't create a new instance of InputContainer in the other widget class, it's wrong.
The ideal way is to use inheritedwidget or scopedmodel,provider but that is more complicated
You can try creating a globalkey inside the other class and access the InputContainerInner text controller from there
Note: Change your _InputContainerInner to InputContainerInner
//put this inside your class widget, where u declare all the variables
final GlobalKey<InputContainerInner> containerKey;
Widget build(BuildContext context) {
return Scaffold(
body: new Column(
children: <Widget>[
//import the inputContainer class
InputContainer(),
new MaterialButton(
onPressed: () {
print(widget.containerKey.currentState.controller.text);
print(widget.containerKey.currentState.controller.input.num);
}
)
]
)
}
full example
TextEditingController completeAddressController = new TextEditingController();
TextFormField(
controller: completeAddressController,
),
get value of TextFormField
String text = completeAddressController.text.toString(),