Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/cookbook/forms/focus/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class MyCustomForm extends StatefulWidget {
class _MyCustomFormState extends State<MyCustomForm> {
// Define the focus node. To manage the lifecycle, create the FocusNode in
// the initState method, and clean it up in the dispose method.
late FocusNode myFocusNode;
late final FocusNode myFocusNode;

@override
void initState() {
Expand Down Expand Up @@ -63,7 +63,7 @@ class _MyCustomFormState extends State<MyCustomForm> {
onPressed: () => myFocusNode.requestFocus(),
tooltip: 'Focus Second Text Field',
child: const Icon(Icons.edit),
), // This trailing comma makes auto-formatting nicer for build methods.
),
);
}
}
2 changes: 1 addition & 1 deletion examples/cookbook/forms/focus/lib/starter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class MyCustomForm extends StatefulWidget {
class _MyCustomFormState extends State<MyCustomForm> {
// Define the focus node. To manage the lifecycle, create the FocusNode in
// the initState method, and clean it up in the dispose method.
late FocusNode myFocusNode;
late final FocusNode myFocusNode;

@override
void initState() {
Expand Down
2 changes: 1 addition & 1 deletion examples/cookbook/forms/focus/lib/step2.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class MyCustomForm extends StatefulWidget {
class _MyCustomFormState extends State<MyCustomForm> {
// Define the focus node. To manage the lifecycle, create the FocusNode in
// the initState method, and clean it up in the dispose method.
late FocusNode myFocusNode;
late final FocusNode myFocusNode;

@override
void initState() {
Expand Down
4 changes: 3 additions & 1 deletion examples/cookbook/forms/focus/lib/step3.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class MyCustomForm extends StatefulWidget {
class _MyCustomFormState extends State<MyCustomForm> {
// Define the focus node. To manage the lifecycle, create the FocusNode in
// the initState method, and clean it up in the dispose method.
late FocusNode myFocusNode;
late final FocusNode myFocusNode;

@override
void initState() {
Expand Down Expand Up @@ -51,6 +51,8 @@ class _MyCustomFormState extends State<MyCustomForm> {
// When the button is pressed,
// give focus to the text field using myFocusNode.
onPressed: () => myFocusNode.requestFocus(),
tooltip: 'Focus Second Text Field',
child: const Icon(Icons.edit),
),
// #enddocregion FloatingActionButton
);
Expand Down
2 changes: 1 addition & 1 deletion examples/cookbook/forms/retrieve_input/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class _MyCustomFormState extends State<MyCustomForm> {
context: context,
builder: (context) {
return AlertDialog(
// Retrieve the text the that user has entered by using the
// Retrieve the text that the user has entered by using the
// TextEditingController.
content: Text(myController.text),
);
Expand Down
4 changes: 2 additions & 2 deletions examples/cookbook/forms/text_field_changes/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Retrieve Text Input',
title: 'Handle Text Field Changes',
home: MyCustomForm(),
);
}
Expand Down Expand Up @@ -59,7 +59,7 @@ class _MyCustomFormState extends State<MyCustomForm> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Retrieve Text Input')),
appBar: AppBar(title: const Text('Handle Text Field Changes')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
Expand Down
2 changes: 1 addition & 1 deletion examples/cookbook/forms/text_input/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class MyCustomForm extends StatelessWidget {
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
children: [
const Padding(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 16),
// #docregion TextField
Expand Down
10 changes: 4 additions & 6 deletions examples/cookbook/forms/validation/lib/form.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,17 @@ class MyCustomForm extends StatefulWidget {
const MyCustomForm({super.key});

@override
MyCustomFormState createState() {
return MyCustomFormState();
}
State<MyCustomForm> createState() => _MyCustomFormState();
}

// Define a corresponding State class.
// This class holds data related to the form.
class MyCustomFormState extends State<MyCustomForm> {
class _MyCustomFormState extends State<MyCustomForm> {
// Create a global key that uniquely identifies the Form widget
// and allows validation of the form.
//
// Note: This is a `GlobalKey<FormState>`,
// not a GlobalKey<MyCustomFormState>.
// not a GlobalKey<_MyCustomFormState>.
final _formKey = GlobalKey<FormState>();

@override
Expand All @@ -26,7 +24,7 @@ class MyCustomFormState extends State<MyCustomForm> {
return Form(
key: _formKey,
child: const Column(
children: <Widget>[
children: [
// Add TextFormFields and ElevatedButton here.
],
),
Expand Down
8 changes: 3 additions & 5 deletions examples/cookbook/forms/validation/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,17 @@ class MyCustomForm extends StatefulWidget {
const MyCustomForm({super.key});

@override
MyCustomFormState createState() {
return MyCustomFormState();
}
State<MyCustomForm> createState() => _MyCustomFormState();
}

// Create a corresponding State class.
// This class holds data related to the form.
class MyCustomFormState extends State<MyCustomForm> {
class _MyCustomFormState extends State<MyCustomForm> {
// Create a global key that uniquely identifies the Form widget
// and allows validation of the form.
//
// Note: This is a GlobalKey<FormState>,
// not a GlobalKey<MyCustomFormState>.
// not a GlobalKey<_MyCustomFormState>.
final _formKey = GlobalKey<FormState>();

@override
Expand Down
24 changes: 11 additions & 13 deletions sites/docs/src/content/cookbook/forms/focus.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ TextField(
);
```

For more information on handling input and creating text fields,
see the [Forms][] section of the cookbook.
To learn more about handling input and creating text fields,
consult the [Forms][] section of the cookbook.

## Focus a text field when a button is tapped

Expand All @@ -46,9 +46,9 @@ text field in response to an API call or a validation error.
In this example, give focus to a text field after the user
presses a button using the following steps:

1. Create a `FocusNode`.
2. Pass the `FocusNode` to a `TextField`.
3. Give focus to the `TextField` when a button is tapped.
1. Create a `FocusNode`.
Comment thread
sfshaza2 marked this conversation as resolved.
1. Pass the `FocusNode` to a `TextField`.
1. Give focus to the `TextField` when a button is tapped.

### 1. Create a `FocusNode`

Expand Down Expand Up @@ -77,7 +77,7 @@ class MyCustomForm extends StatefulWidget {
class _MyCustomFormState extends State<MyCustomForm> {
// Define the focus node. To manage the lifecycle, create the FocusNode in
// the initState method, and clean it up in the dispose method.
late FocusNode myFocusNode;
late final FocusNode myFocusNode;

@override
void initState() {
Expand Down Expand Up @@ -126,6 +126,8 @@ FloatingActionButton(
// When the button is pressed,
// give focus to the text field using myFocusNode.
onPressed: () => myFocusNode.requestFocus(),
tooltip: 'Focus Second Text Field',
child: const Icon(Icons.edit),
),
```

Expand Down Expand Up @@ -159,7 +161,7 @@ class MyCustomForm extends StatefulWidget {
class _MyCustomFormState extends State<MyCustomForm> {
// Define the focus node. To manage the lifecycle, create the FocusNode in
// the initState method, and clean it up in the dispose method.
late FocusNode myFocusNode;
late final FocusNode myFocusNode;

@override
void initState() {
Expand Down Expand Up @@ -198,21 +200,17 @@ class _MyCustomFormState extends State<MyCustomForm> {
onPressed: () => myFocusNode.requestFocus(),
tooltip: 'Focus Second Text Field',
child: const Icon(Icons.edit),
), // This trailing comma makes auto-formatting nicer for build methods.
),
);
}
}
```

<noscript>
<img src="/assets/images/docs/cookbook/focus.webp" alt="Text Field Focus Demo" class="site-mobile-screenshot" />
<img src="/assets/images/docs/cookbook/focus.png" alt="Text Field Focus Demo" />
</noscript>


[fix has landed]: {{site.repo.flutter}}/pull/50372
[`FocusNode`]: {{site.api}}/flutter/widgets/FocusNode-class.html
[Forms]: /cookbook/forms
[flutter/flutter@bf551a3]: {{site.repo.flutter}}/commit/bf551a31fe7ef45c854a219686b6837400bfd94c
[Issue 52221]: {{site.repo.flutter}}/issues/52221
[`requestFocus()`]: {{site.api}}/flutter/widgets/FocusNode/requestFocus.html
[workaround]: {{site.repo.flutter}}/issues/52221#issuecomment-598244655
22 changes: 11 additions & 11 deletions sites/docs/src/content/cookbook/forms/retrieve-input.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ In this recipe,
learn how to retrieve the text a user has entered into a text field
using the following steps:

1. Create a `TextEditingController`.
2. Supply the `TextEditingController` to a `TextField`.
3. Display the current value of the text field.
1. Create a `TextEditingController`.
Comment thread
sfshaza2 marked this conversation as resolved.
1. Supply the `TextEditingController` to a `TextField`.
1. Display the current value of the text field.

## 1. Create a `TextEditingController`

Expand All @@ -20,9 +20,9 @@ create a [`TextEditingController`][]
and supply it to a `TextField` or `TextFormField`.

:::important
Call `dispose` of the `TextEditingController` when
you've finished using it. This ensures that you discard any resources
used by the object.
Call `dispose()` on the `TextEditingController` when
you've finished using it.
This ensures that you discard any resources used by the object.
:::

<?code-excerpt "lib/starter.dart (Starter)" remove="return Container();"?>
Expand Down Expand Up @@ -69,9 +69,9 @@ return TextField(controller: myController);
## 3. Display the current value of the text field

After supplying the `TextEditingController` to the text field,
begin reading values. Use the [`text`][]
property provided by the `TextEditingController` to retrieve the
String that the user has entered into the text field.
begin reading values.
Use the [`text`][] property provided by the `TextEditingController`
to retrieve the `String` that the user has entered into the text field.

The following code displays an alert dialog with the current
value of the text field when the user taps a floating action button.
Expand Down Expand Up @@ -156,7 +156,7 @@ class _MyCustomFormState extends State<MyCustomForm> {
context: context,
builder: (context) {
return AlertDialog(
// Retrieve the text the that user has entered by using the
// Retrieve the text that the user has entered by using the
// TextEditingController.
content: Text(myController.text),
);
Expand All @@ -172,7 +172,7 @@ class _MyCustomFormState extends State<MyCustomForm> {
```

<noscript>
<img src="/assets/images/docs/cookbook/retrieve-input.webp" alt="Retrieve Text Input Demo" class="site-mobile-screenshot" />
<img src="/assets/images/docs/cookbook/retrieve-input.png" alt="Retrieve Text Input Demo" />
</noscript>


Expand Down
26 changes: 15 additions & 11 deletions sites/docs/src/content/cookbook/forms/text-field-changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ results as the user types.
How do you run a callback function every time the text changes?
With Flutter, you have two options:

1. Supply an `onChanged()` callback to a `TextField` or a `TextFormField`.
2. Use a `TextEditingController`.
1. Supply an `onChanged()` callback to a `TextField` or a `TextFormField`.
Comment thread
sfshaza2 marked this conversation as resolved.
1. Use a `TextEditingController`.

## 1. Supply an `onChanged()` callback to a `TextField` or a `TextFormField`

Expand All @@ -25,10 +25,10 @@ Whenever the text changes, the callback is invoked.
In this example, print the current value and length of the text field
to the console every time the text changes.

It's important to use [characters][] when dealing with user input,
as text may contain complex characters.
It's important to use [`characters`][characters] when dealing with user input,
as text might contain complex characters.
This ensures that every character is counted correctly
as they appear to the user.
as it appears to the user.

<?code-excerpt "lib/main.dart (TextField1)"?>
```dart
Expand All @@ -39,6 +39,10 @@ TextField(
),
```

<noscript>
<img src="/assets/images/docs/cookbook/text-field-changes.png" alt="Handle Text Field Changes Demo" />
</noscript>

## 2. Use a `TextEditingController`

A more powerful, but more elaborate approach, is to supply a
Expand All @@ -48,10 +52,10 @@ property of the `TextField` or a `TextFormField`.
To be notified when the text changes, listen to the controller
using the [`addListener()`][] method using the following steps:

1. Create a `TextEditingController`.
2. Connect the `TextEditingController` to a text field.
3. Create a function to print the latest value.
4. Listen to the controller for changes.
1. Create a `TextEditingController`.
Comment thread
sfshaza2 marked this conversation as resolved.
1. Connect the `TextEditingController` to a text field.
1. Create a function to print the latest value.
1. Listen to the controller for changes.

### Create a `TextEditingController`

Expand Down Expand Up @@ -166,7 +170,7 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Retrieve Text Input',
title: 'Handle Text Field Changes',
home: MyCustomForm(),
);
}
Expand Down Expand Up @@ -211,7 +215,7 @@ class _MyCustomFormState extends State<MyCustomForm> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Retrieve Text Input')),
appBar: AppBar(title: const Text('Handle Text Field Changes')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
Expand Down
Loading
Loading