championforms 0.0.4 copy "championforms: ^0.0.4" to clipboard
championforms: ^0.0.4 copied to clipboard

Easy Build Data Input Fields of All Types in Flutter

example/lib/main.dart

import 'package:championforms/championforms.dart';
import 'package:championforms/controllers/form_controller.dart';
import 'package:championforms/models/formfieldbase.dart';
import 'package:championforms/models/formresults.dart';
import 'package:championforms/models/multiselect_option.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // TRY THIS: Try running your application with "flutter run". You'll see
        // the application has a purple toolbar. Then, without quitting the app,
        // try changing the seedColor in the colorScheme below to Colors.green
        // and then invoke "hot reload" (save your changes or press the "hot
        // reload" button in a Flutter-supported IDE, or press "r" if you used
        // the command line to start the app).
        //
        // Notice that the counter didn't reset back to zero; the application
        // state is not lost during the reload. To reset the state, use hot
        // restart instead.
        //
        // This works for code too, not just values: Most code changes can be
        // tested with just a hot reload.
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late ChampionFormController controller;

  @override
  void initState() {
    super.initState();
    controller = ChampionFormController();
  }

  @override
  void dispose() {
    super.dispose();
    controller.dispose();
  }

  void _executeLogin() {
    // Because championforms relies on riverpod. Field results
    // are accessible anywhere in the app as long as the form is still active.
    // You can simply build the FormResults object at any time to cause the form
    // to pass results and run validation.
    final FormResults results = FormResults.getResults(controller: controller);

    // Once run the form will tell you if it is in an error state.
    // If true, then stop processing.
    final errors = results.errorState;
    debugPrint("Current Error State is: $errors");
    if (errors == false) {
      // No errors, excellent!
      // Fields can be "grabbed" from the results by their ID.
      // Then you can format them .asString(), asStringList(), asMultiSelectList()
      debugPrint(results.grab("Email").asString());
      debugPrint(results.grab("DropdownField").asString());
      debugPrint(results
          .grab("SelectBox")
          .asMultiselectList()
          .map((field) => field.value)
          .join(", "));
    } else {
      debugPrint("The form had some errors.");
      debugPrint(results.formErrors
          .map((error) =>
              "Field ${error.fieldId} had the error: ${error.reason}")
          .join(", "));
    }
  }

  @override
  Widget build(BuildContext context) {
    // Time to build a sample form:
    final List<FormFieldBase> fields = [
      ChampionTextField(
        id: "Email", // To ID the field, must be unique per form
        validateLive:
            true, // This causes the field to validate itself as soon as it loses focus -- defaults to false.
        maxLines: 1, // Forces field to one line
        hintText: "Email", // Hint text in the text field
        textFieldTitle:
            "Email", // This is the title which displays in the field until you click on it, then moves to the border
        description:
            "Enter your email Address", // Description by default displays above the field below the title
        // Validators are a list of FormBuilderValidator objects which run a bool function on the results to determine if the input is satisfactory.
        // Default validators are provided in the DefaultValidators() object. The most important one there is the dependency on valid emails.
        // If a field isn't valid, then the field state is set to error causing the colors to change and the error is displayed (by default) below the field in errorBorder color.
        validators: [
          FormBuilderValidator(
            validator: (results) => DefaultValidators().isEmpty(results),
            reason: "Field is empty",
          ),
          FormBuilderValidator(
            validator: (results) => DefaultValidators().isEmail(results),
            reason: "This isn't an email address",
          ),
        ],
        // Leading icon. Can make clickable with MouseRegion, and GestureDetector
        leading: const Icon(Icons.verified_user),
      ),
      ChampionTextField(
          id: "Text Field 1",
          textFieldTitle: "Password",
          maxLines: 1,
          password: true, // Password being true obscures the text in the field
          validateLive: true,

          // The onSubmit will fire when the user presses enter.
          // If maxLines is null or set to a larger number then onSubmit will fire on enter and
          // new line will be triggered on shift + enter.
          // If no onSubmit is present, then enter will add a new line as normal.
          onSubmit: (results) => debugPrint("Login"),
          validators: [
            FormBuilderValidator(
                validator: (results) => DefaultValidators().isEmpty(results),
                reason: "Password is Empty"),
          ],
          leading: const Icon(Icons.password)),

      // Champion option fields utilize a builder to handle the elements in the field.
      // Currently, this is the base implementation which spits out a Dropdown.
      // The setup should work for any multi-select object being used.
      // Custom builders can be inserted via the fieldBuilder property.
      // See the widgets_external/field_builders/checkboxfield_builder.dart file for details
      // on constructing your own custom builder.
      ChampionOptionSelect(
          id: "DropdownField", // ID can be anything but should be unique
          title: "Quick Dropdown",
          // MultiselectOption by default will pass through the label and value when the form is submitted.
          // However the additionalData property will accept any object? allowing you to pass through any element you desire to the formResults.
          options: [
            MultiselectOption(
              label: "Option 1",
              value: "Value 1",
            ),
            MultiselectOption(
              label: "Option 2",
              value: "Value 2",
            ),
            MultiselectOption(
              label: "Option 3",
              value: "Value 3",
            ),
            MultiselectOption(
              label: "Option 4",
              value: "Value 4",
            ),
          ]),
      // ChampionCheckboxSelect extends ChampionOptionSelect simply swapping out the fieldBuilder
      // For one which displays the options as checkboxes.
      ChampionCheckboxSelect(
        id: "SelectBox",
        requestFocus: true,
        multiselect: true,
        validateLive: true,
        validators: [
          FormBuilderValidator(
              validator: (results) => DefaultValidators().isEmpty(results),
              reason: "Nothing is checked"),
        ],

        title: "Choose your weapon",
        //defaultValue: ["Hiya"],icon: const Icon(Icons.title),
        leading: const MouseRegion(
            cursor: SystemMouseCursors.click, child: Icon(Icons.mic)),
        trailing: const Icon(Icons.search),

        options: [
          MultiselectOption(value: "Hi", label: "Hello"),
          MultiselectOption(value: "Hiya", label: "Wat"),
          MultiselectOption(value: "Yoz", label: "Sup"),
        ],
      ),
    ];

    return Scaffold(
      appBar: AppBar(
        // TRY THIS: Try changing the color here to a specific color (to
        // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
        // change color while the other colors stay the same.
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: const Text("Champion Forms Example"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            // The ChampionForm widget actually displays a form.
            // Throw in the fields defined above.
            // The ID keeps forms seperate when pulling results.
            // If two forms have the same ID and different fields, then all fields
            // will appear in the results when the form is evaluated.
            ChampionForm(
              theme: softBlueColorTheme(context),
              controller: controller,
              spacing: 10,
              fields: fields,
            ),
            ElevatedButton(
                child: const Text("Set Values"),
                onPressed: () {
                  controller.updateTextFieldValue("Email", "Hello@hello.com");
                  controller.toggleMultiSelectValue("DropdownField", toggleOn: ["Value 3", "Value 2"]);
                  controller.toggleMultiSelectValue(
                    "SelectBox",
                    toggleOn: ["Hi", "Yoz"],
                    toggleOff: ["Hiya"],
                  );
                }),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _executeLogin,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}
2
likes
130
points
52
downloads

Publisher

unverified uploader

Weekly Downloads

Easy Build Data Input Fields of All Types in Flutter

Homepage
Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

collection, dotted_border, email_validator, flutter, super_clipboard, super_drag_and_drop, textfield_tags, uuid

More

Packages that depend on championforms