Search code examples
fluttertextinput

Is there a way to have one text controller for multiple text fields in flutter?


I have a form where users enter a title and a description and right now I have it set up with one text controller for each textfield

late final TextEditingController _titleController;
late final TextEditingController _descriptionController;



@override
void initState() {
  _calendarService = CalendarCloudStorage();
  _titleController = TextEditingController();
  _descriptionController = TextEditingController();
  super.initState();
}

@override
void dispose() {
  _titleController.dispose();
  _descriptionController.dispose();
  super.dispose();
}


void _setupTextControllerListener() {
  _titleController.removeListener(_titleControllerListener);
  _titleController.addListener(_titleControllerListener);
  _descriptionController.removeListener(_descriptionControllerListener);
  _descriptionController.addListener(_descriptionControllerListener);
}

void _titleControllerListener() async {
  if (_event == null) {
    return;
  }
  final titleText = _titleController.text;
  await _calendarService.updateEvent(
    documentId: _event!.documentId,
    title: titleText,   
  );
}

void _descriptionControllerListener() async {
  if (_event == null) {
    return;
  }
  final descriptionText = _descriptionController.text;
  await _calendarService.updateEvent(
    documentId: _event!.documentId,
    description: descriptionText,
  );
}

this is the code I have for setting up the text controllers and then in the scaffold I have

TextField(
  controller: _titleController,
  maxLines: 1,
  decoration: const InputDecoration(hintText: 'Title here'),
),
TextField(
  controller: _descriptionController,
  maxLines: null,
  keyboardType: TextInputType.multiline,
  decoration: const InputDecoration(hintText: 'The description of your event'),
),
 

This feels inefficient is there a better way?

I tried using one per field but can I have one and treat the whole thing as one form?


Solution

  • You can't use a TextEditingController more than once but you can use the onChanged property on the TextField. Such as:

    TextField(
      controller: _titleController,
      maxLines: 1,
      decoration: const InputDecoration(hintText: 'Title here'),
      onChanged: (final String value) async =>
          await _calendarService.updateEvent(
          documentId: _event!.documentId,
          title: value,)
    ),
    TextField(
      controller: _descriptionController,
      maxLines: null,
      keyboardType: TextInputType.multiline,
      decoration: const InputDecoration(hintText: 'The description of your event'),
      onChanged: (final String value) async =>
          await _calendarService.updateEvent(
          documentId: _event!.documentId,
          description: value,)
    ),