text_controller_manager

pub package License

Many TextFields/TextFormFields would bring many controllers as well, right? that would be annoy to create all of that controllers everytime, right?

A Dart CLI tool for generating Flutter TextEditingController classes from YAML configuration. Perfect for quickly scaffolding form controllers with disposeAll() and toMap() methods, as well as many other useful methods that manage data.


Features

  • Generate Flutter controller classes automatically.
  • Supports default values for each field.
  • Includes disposeAll(), toMap(), and many other methods for memory safety.
  • CLI usage with custom YAML config and output directory.

Installation

Add the package to your project:

dev_dependencies:
  text_controller_manager: <latest_version>

Then run:

dart pub get

Usage (CLI)

Make sure to create controllers.ymal in root project

YAML Configuration Example

controllers:
  - className: LoginController
    fields:
      - name: email
        type: string
      - name: password
        type: string
      - name: age
        type: int
      - name: isActive
        type: bool
    initialValues:
      email: "user@example.com"
      age: "25"
      isActive: "true"
  • className — the name of the Dart controller class.
  • fields — list of TextEditingController fields.
  • type - type of variable when return Map using toMap()
  • initialValues — optional default values for each field. Generate controllers from a YAML file:
dart run text_controller_manager:generate

Options

-c, --config   Path to YAML configuration file (default: controllers.yaml)
-o, --output   Output directory for generated controllers (default: lib/controllers/)
-h, --help     Show this help message

Examples

  1. Default usage (uses controllers.yaml and outputs to lib/controllers/):
dart run text_controller_manager:generate
  1. Custom YAML file:
dart run text_controller_manager:generate -c my_controllers.yaml
  1. Custom output directory:
dart run text_controller_manager:generate -c lib/custom_controllers/
  1. Custom config and output:
dart run text_controller_manager:generate -c my_controllers.yaml -o lib/custom_controllers/

Generated Class Example

For the above YAML, the generated class:

import 'dart:convert';

import 'package:flutter/material.dart';

// Generated controller class for LoginController
class LoginController {
  final TextEditingController email;
  final TextEditingController password;
  final TextEditingController age;
  final TextEditingController isActive;

  LoginController({Map<String, String>? initialValues})
      :
        email = TextEditingController(text: initialValues?["email"] ?? "user@example.com"),
        password = TextEditingController(text: initialValues?["password"] ?? ''),
        age = TextEditingController(text: initialValues?["age"] ?? "25"),
        isActive = TextEditingController(text: initialValues?["isActive"] ?? "true");

  /// Dispose all controllers
  void disposeAll() {
    email.dispose();
    password.dispose();
    age.dispose();
    isActive.dispose();
  }

  dynamic _convertType(String text, String type) {
    switch(type) {
      case "int": return int.tryParse(text) ?? 0;
      case "double": return double.tryParse(text) ?? 0.0;
      case "bool": return text.toLowerCase() == "true";
      case "string":
      default: return text;
    }
  }

  /// Convert all controller values to Map with type conversion
  Map<String, dynamic> toMap() => {
    "email": _convertType(email.text, "string"),
    "password": _convertType(password.text, "string"),
    "age": _convertType(age.text, "int"),
    "isActive": _convertType(isActive.text, "bool"),
  };

  /// Create controller from Map
  factory LoginController.fromMap(Map<String, dynamic> map) {
    return LoginController(initialValues: map.map((k,v) => MapEntry(k, v.toString())));
  }

  /// Clear all fields
  void clearAll() {
    email.clear();
    password.clear();
    age.clear();
    isActive.clear();
  }

  /// Set multiple fields at once
  void setValues(Map<String, dynamic> values) {
    if (values.containsKey("email")) { email.text = values["email"].toString(); }
    if (values.containsKey("password")) { password.text = values["password"].toString(); }
    if (values.containsKey("age")) { age.text = values["age"].toString(); }
    if (values.containsKey("isActive")) { isActive.text = values["isActive"].toString(); }
  }

  /// Update single field safely
  void updateField(String fieldName, String value) {
    switch(fieldName) {
      case "email": email.text = value; break;
      case "password": password.text = value; break;
      case "age": age.text = value; break;
      case "isActive": isActive.text = value; break;
      default: break;
    }
  }

  /// Check if all fields are empty
  bool isEmpty() => email.text.isEmpty && password.text.isEmpty && age.text.isEmpty && isActive.text.isEmpty;

  /// Check if any field is empty
  bool anyEmpty() => email.text.isEmpty || password.text.isEmpty || age.text.isEmpty || isActive.text.isEmpty;

  /// Check if any field contains the given value
  bool contains(String value) => email.text.contains(value) || password.text.contains(value) || age.text.contains(value) || isActive.text.contains(value);

  /// Convert to JSON string
  String toJson() => jsonEncode(toMap());

  /// Initialize from JSON string
  factory LoginController.fromJson(String json) {
    return LoginController.fromMap(Map<String, dynamic>.from(jsonDecode(json)));
  }
}

Notes

  • Make sure the output directory exists or let the tool create it automatically.
  • Always call disposeAll() for cleanup in Flutter widgets.
  • Supports multiple controllers in a single YAML file.

License

This project is licensed under the MIT License.


Libraries

controllers/logincontroller
controllers/registercontroller
text_controller_manager
The main library for text_controller_manager. Provides functions to generate Flutter TextEditingController-based classes.