Начало работы с FForm 🌟

Прежде всего, давайте добавим пакет FForm в ваш проект Flutter. Добавьте FForm в файл pubspec.yaml в разделе зависимостей:

Не забудьте запустить flutter pub get в вашем терминале, чтобы установить пакет.

Обзор

FForm — это высокоуровневый пакет Flutter, разработанный для упрощения создания и управления формами с упрощенной валидацией полей. Он предлагает два основных компонента: FFormField и FFormBuilder, которые вместе приносят легкость и гибкость в обработку форм в приложениях Flutter.

  • FFormField<T, E>: Базовый класс для всех полей формы, поддерживающий значения, валидацию на лету и обработку изменений.

  • FFormBuilder<F extends FForm>: Виджет, который конструирует и управляет состоянием формы, используя потоки для динамического обновления интерфейса по мере изменения данных.

  • FForm: Базовый класс для создания пользовательских классов форм, позволяющий добавлять конкретные методы и свойства в ваши формы.

  • FFormException: Базовый класс для создания пользовательских исключений для полей формы, позволяющий определять пользовательские правила валидации и сообщения об ошибках.

  • FFormProvider: Виджет, который позволяет получить доступ к форме в дереве виджетов без передачи ее в качестве параметра.

Почему это круто 🎸

  • Упрощенное управление состоянием: Автоматически обрабатывает состояние как отдельных полей формы, так и формы в целом.

  • Встроенная валидация с изюминкой: Поддерживает валидацию на лету и обработку ошибок для каждого поля, обеспечивая плавный пользовательский опыт.

  • Максимальная гибкость: Поддерживает любой тип данных для значений полей и ошибок валидации благодаря дженерикам.

  • Реактивные формы для победы: Использует потоки для отслеживания изменений состояния формы, обеспечивая синхронизацию вашего интерфейса.

  • Множество форм? Нет проблем: Создавайте несколько форм с пользовательскими полями и правилами валидации, все это управляется FForm.

  • Пользовательские исключения для особых нужд: Определяйте пользовательские исключения для полей формы, чтобы с легкостью обрабатывать сложные правила валидации и сообщения об ошибках.

Примеры использования

FFormField

FFormField — базовый класс для всех полей формы, поддерживающий значения, валидацию на лету и обработку изменений. Он предоставляет набор геттеров и методов для управления состоянием поля, включая проверку валидности поля, получение текущего значения и обработку исключений.

Пример

enum EmailError {
  empty,
  not;

  @override
  String toString() {
    switch (this) {
      case empty:
        return 'emailEmpty';
      case not:
        return 'invalidFormatEmail';
      default:
        return 'invalidFormatEmail';
    }
  }
}

class EmailField extends FFormField<String, EmailError> {

  EmailField({required String value}) : super(value);

  @override
  EmailError? validator(value) {
    if (value.isEmpty) return EmailError.empty;
    return null;
  }
}

FForm

FForm — базовый класс для создания пользовательских классов форм с конкретными полями и правилами валидации. Он предоставляет набор геттеров и методов для управления состоянием формы, включая проверку валидности формы, получение ответов и обработку исключений.

Пример

Это простой пример того, как создать форму с одним полем. Вы можете расширить класс FForm, чтобы создать пользовательские формы с конкретными полями и правилами валидации.

class LoginForm extends FForm {
  EmailField email;
  
  LoginForm({
    required this.email,
  });

  @override
  List<FFormField> get fields => [email];
}

Это более сложный пример того, как создать форму с несколькими полями. Вы можете расширить класс FForm, чтобы создать пользовательские формы с конкретными полями и правилами валидации.

class Form extends FForm {
  List<Form> forms;

  Form({
    required this.forms,
  });

  @override
  List<FFormField> get subForms => forms;
}

allFieldUpdateCheck — это свойство в FForm, которое определяет, приводит ли каждое обновление поля к перестройке FFormBuilder. Когда установлено в true, форма будет перестраиваться при каждом обновлении поля, обеспечивая мгновенную обратную связь для пользователя. Когда установлено в false, форма будет перестраиваться только при вызове геттеров isValid или isInvalid, уменьшая количество перестроек и повышая производительность.

class LoginForm extends FForm {
  EmailField email;

  LoginForm({
    required this.email,
  });

  @override
  bool get allFieldUpdateCheck => true;
  
  @override
  List<FFormField> get fields => [email];
}

FFormBuilder

FFormBuilder — это виджет, который конструирует и управляет состоянием формы, используя потоки для динамического обновления интерфейса по мере изменения данных. Он предоставляет функцию построения, которая принимает форму и возвращает дерево виджетов на основе состояния формы.

Пример

Это пример того, как использовать FFormBuilder для создания формы с одним полем. Функция построения принимает форму в качестве параметра и возвращает дерево виджетов на основе состояния формы.

void _submit() {
  if(_form.isValid) { // .isValid или .isInvalid запускают перестройку в FFormBuilder и возвращают boolean
    print('Форма валидна');
  };
}

@override
Widget build(BuildContext context) {
  return FFormBuilder<LoginForm>(
    form: _form,
    builder: (context, form) {
      EmailField email = form.email; // или FFormProvider.of<LoginForm>(context).get<NameField>()
      
      return Column(
        children: [
          TextField(
            key: email.key,
            controller: _emailController,
            decoration: InputDecoration(
              labelText: 'Email',
              errorText: email.exception.toString(),
            ),
          ),
          ElevatedButton(
            onPressed: _submit,
            child: const Text('Отправить'),
          ),
        ],
      );
    },
  );
}

FFormProvider

FFormProvider — это виджет, который позволяет получить доступ к форме в дереве виджетов без передачи ее в качестве параметра.

Пример

FFormBuilder<LoginForm>(
  form: _form,
  builder: (context, form) {
    
    FFormProvider.of<LoginForm>(context).email; // или form.email;
    FFormProvider.of<LoginForm>(context).get<NameField>(); // или form.get<NameField>();

    return YourForm();
  },
)

FFormException

FFormException — базовый класс для создания пользовательских исключений для полей формы. Он позволяет определять пользовательские правила валидации и сообщения об ошибках для полей формы, позволяя с легкостью обрабатывать сложные сценарии валидации.

Пример

Вы можете создать пользовательский класс исключения, который расширяет FFormException, чтобы определить конкретные правила валидации и сообщения об ошибках для поля формы.

class PasswordValidationException extends FFormException {
  final bool isMinLengthValid;
  final bool isSpecialCharValid;
  final bool isNumberValid;

  PasswordValidationException({
    required this.isMinLengthValid,
    required this.isSpecialCharValid,
    required this.isNumberValid,
  });

  @override
  bool get isValid => isMinLengthValid && isSpecialCharValid && isNumberValid;
}

class PasswordField extends FFormField<String, PasswordValidationException> {
  PasswordField(String value) : super(value);

  @override
  PasswordValidationException? validator(String value) {
    final validator = FFormValidator(value);
    return PasswordValidationException(
      isMinLengthValid: validator.isMinLength(8),
      isSpecialCharValid: validator.isHaveSpecialChar,
      isNumberValid: validator.isHaveNumber,
    );
  }
}

Не стесняйтесь внести свой вклад в пакет или сообщить о любых проблемах в репозитории GitHub. Приятного кодирования!

Пример показывает дефолтную реализации формачки, буквально каждый реализовывал такую реализацию

Был использован:

class LoginForm extends FForm
class EmailField extends FFormField
class PasswordField extends FFormField

Показан пример со сложной валидацией поля, как в примере это пароль с проверкой на

- Максимальное количество символов

- Обязательно специфичные цифры

- Обязательно цифры

Был Использован:
class PasswordValidationException extends FFormException

class PasswordField extends FFormField<string, PasswordValidationException>

class PasswordForm extends FForm

На примере показана, форма которая включает в себя другие формы, что дать гибкость в создание сложных систем валидации на уровне клиента.


Тут был DrawForm который включает в себе List<DrawForm>

Простая форма, которая включает в себе массив других форм.

Если заметить, то поле сверху автоматически проверяется в случае какого либо изменения. За это как раз таки отвечает поле bool allFieldUpdateCheck которое можно перезаписать в случае вашего кейса. Это используется для определения необходимости перестраивать форму при каждом обновлении поля.

Ссылка на пакет fform, github repository, блог в котором можно отследить изменения и дополнения этого пакета