form_builder_autocomplete 0.9.0 copy "form_builder_autocomplete: ^0.9.0" to clipboard
form_builder_autocomplete: ^0.9.0 copied to clipboard

An advanced Autocomplete input extension widget for Flutter FormBuilder, supporting type-safe predictive text filtering and async data fetching.

example/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:form_builder_autocomplete/form_builder_autocomplete.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FormBuilder Autocomplete Showcase',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(useMaterial3: true, colorSchemeSeed: Colors.teal),
      home: const AutocompletePlaygroundPortal(),
    );
  }
}

/// A clean enterprise mock data structure representing a user profile object entity
class UserAccount {
  final String uid;
  final String fullName;
  final String department;

  const UserAccount({
    required this.uid,
    required this.fullName,
    required this.department,
  });
}

class AutocompletePlaygroundPortal extends StatefulWidget {
  const AutocompletePlaygroundPortal({super.key});

  @override
  State<AutocompletePlaygroundPortal> createState() =>
      _AutocompletePlaygroundPortalState();
}

class _AutocompletePlaygroundPortalState
    extends State<AutocompletePlaygroundPortal> {
  final _formKey = GlobalKey<FormBuilderState>();

  // High-volume mock repository for strict local predictable filtering
  final List<String> _globalCountriesDatabase = [
    'Argentina',
    'Australia',
    'Brazil',
    'Canada',
    'Denmark',
    'Egypt',
    'France',
    'Germany',
    'India',
    'Indonesia',
    'Japan',
    'Malaysia',
    'Mexico',
    'Netherlands',
    'Philippines',
    'Singapore',
    'South Korea',
    'Thailand',
    'United Kingdom',
    'United States',
    'Vietnam',
    'Zimbabwe',
  ];

  Map<String, dynamic>? _submittedDataSnapshot;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Predictive Input Form Portal'),
        centerTitle: true,
        backgroundColor: Colors.teal.withValues(alpha: 0.1),
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(24.0),
        child: Center(
          child: SizedBox(
            width: double.maxFinite,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                FormBuilder(
                  key: _formKey,
                  autovalidateMode: AutovalidateMode.onUserInteraction,
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      const Text(
                        'DEMO 1: LOCAL TEXT FILTERING (SIMPLE STRING)',
                        style: TextStyle(
                          fontWeight: FontWeight.bold,
                          fontSize: 12,
                          color: Colors.blueGrey,
                        ),
                      ),
                      const SizedBox(height: 8),

                      // Example 1: Local predictive search returning simple Strings
                      FormBuilderAutocomplete<String>(
                        name: 'target_country',
                        decoration: const InputDecoration(
                          labelText: 'Select Country Region',
                          hintText: 'Type to search (e.g., Viet, United...)',
                          prefixIcon: Icon(Icons.public_outlined),
                          border: OutlineInputBorder(),
                        ),
                        displayStringForOption: (option) => option,
                        searchItems: (String searchText) async {
                          // Immediate inline local computation mapping
                          return _globalCountriesDatabase
                              .where(
                                (country) => country.toLowerCase().contains(
                                  searchText.toLowerCase(),
                                ),
                              )
                              .toList();
                        },
                      ),

                      const SizedBox(height: 32),
                      const Text(
                        'DEMO 2: ASYNC REMOTE QUERY (COMPLEX OBJECT ENTITY)',
                        style: TextStyle(
                          fontWeight: FontWeight.bold,
                          fontSize: 12,
                          color: Colors.blueGrey,
                        ),
                      ),
                      const SizedBox(height: 8),

                      // Example 2: Delayed query mapping complex runtime Entities
                      FormBuilderAutocomplete<UserAccount>(
                        name: 'assigned_manager',
                        decoration: const InputDecoration(
                          labelText: 'Assign Project Manager Account',
                          hintText: 'Type employee name (e.g., Alex, Sam...)',
                          prefixIcon: Icon(Icons.badge_outlined),
                          border: OutlineInputBorder(),
                        ),
                        displayStringForOption:
                            (user) => '${user.fullName} (${user.department})',

                        // Customizes the prediction drop-down list UI elements beautifully
                        optionsViewBuilder: (context, onSelected, options) {
                          return Align(
                            alignment: Alignment.topLeft,
                            child: Material(
                              elevation: 4.0,
                              borderRadius: BorderRadius.circular(8.0),
                              child: SizedBox(
                                width: 500,
                                height: 250,
                                child: ListView.builder(
                                  padding: EdgeInsets.zero,
                                  shrinkWrap: true,
                                  itemCount: options.length,
                                  itemBuilder: (
                                    BuildContext context,
                                    int index,
                                  ) {
                                    final UserAccount option = options
                                        .elementAt(index);
                                    return ListTile(
                                      leading: CircleAvatar(
                                        backgroundColor: Colors.teal.withValues(
                                          alpha: 0.2,
                                        ),
                                        child: Text(option.fullName[0]),
                                      ),
                                      title: Text(
                                        option.fullName,
                                        style: const TextStyle(
                                          fontWeight: FontWeight.w600,
                                        ),
                                      ),
                                      subtitle: Text(
                                        'ID: ${option.uid} • Dept: ${option.department}',
                                      ),
                                      onTap: () => onSelected(option),
                                    );
                                  },
                                ),
                              ),
                            ),
                          );
                        },
                        searchItems: (String searchText) async {
                          // Simulate dynamic background engine latency delay network pipeline
                          await Future.delayed(
                            const Duration(milliseconds: 400),
                          );

                          final List<UserAccount> mockServerDatabase = [
                            const UserAccount(
                              uid: 'USR-701',
                              fullName: 'Alex Mercer',
                              department: 'Cyber Security',
                            ),
                            const UserAccount(
                              uid: 'USR-702',
                              fullName: 'Alexander Pierce',
                              department: 'R&D Lab',
                            ),
                            const UserAccount(
                              uid: 'USR-804',
                              fullName: 'Samantha Green',
                              department: 'Product Operations',
                            ),
                            const UserAccount(
                              uid: 'USR-911',
                              fullName: 'Samuel Jackson',
                              department: 'Executive Hub',
                            ),
                            const UserAccount(
                              uid: 'USR-952',
                              fullName: 'Victoria Sterling',
                              department: 'UI/UX Guild',
                            ),
                          ];

                          return mockServerDatabase
                              .where(
                                (user) => user.fullName.toLowerCase().contains(
                                  searchText.toLowerCase(),
                                ),
                              )
                              .toList();
                        },
                      ),
                    ],
                  ),
                ),
                const SizedBox(height: 32),

                // Operational Portal Action Trigger Bar
                Row(
                  children: [
                    Expanded(
                      child: ElevatedButton.icon(
                        style: ElevatedButton.styleFrom(
                          padding: const EdgeInsets.symmetric(vertical: 14),
                          backgroundColor: Colors.teal,
                          foregroundColor: Colors.white,
                        ),
                        icon: const Icon(Icons.cloud_upload_outlined),
                        label: const Text('Save & Extract Form Data'),
                        onPressed: () {
                          if (_formKey.currentState?.saveAndValidate() ??
                              false) {
                            setState(() {
                              _submittedDataSnapshot =
                                  _formKey.currentState!.value;
                            });
                          }
                        },
                      ),
                    ),
                    const SizedBox(width: 12),
                    OutlinedButton(
                      style: OutlinedButton.styleFrom(
                        padding: const EdgeInsets.symmetric(vertical: 14),
                      ),
                      onPressed: () {
                        _formKey.currentState?.reset();
                        setState(() {
                          _submittedDataSnapshot = null;
                        });
                      },
                      child: const Text('Reset Form'),
                    ),
                  ],
                ),

                // Structural Result Trace Monitor Panel
                if (_submittedDataSnapshot != null) ...[
                  const SizedBox(height: 28),
                  Container(
                    padding: const EdgeInsets.all(16),
                    decoration: BoxDecoration(
                      color: Colors.teal.withValues(alpha: 0.08),
                      borderRadius: BorderRadius.circular(10),
                      border: Border.all(
                        color: Colors.teal.withValues(alpha: 0.25),
                      ),
                    ),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        const Text(
                          'EXTRACTED TYPE-SAFE OBJECT REGISTRY:',
                          style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 11,
                            color: Colors.teal,
                          ),
                        ),
                        const SizedBox(height: 10),

                        // Output 1: String
                        Text(
                          '1. Country Selected: "${_submittedDataSnapshot!['target_country'] ?? 'None'}"',
                          style: const TextStyle(
                            fontSize: 14,
                            fontFamily: 'monospace',
                          ),
                        ),
                        const SizedBox(height: 8),

                        // Output 2: Complex Class Object properties
                        Builder(
                          builder: (context) {
                            final manager =
                                _submittedDataSnapshot!['assigned_manager'];
                            if (manager == null) {
                              return const Text(
                                '2. Manager Selected: Null Object',
                              );
                            }
                            final UserAccount account = manager as UserAccount;
                            return Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Text(
                                  '2. Manager Locked Instance Object Details:',
                                  style: TextStyle(color: Colors.grey[800]),
                                ),
                                Padding(
                                  padding: const EdgeInsets.only(
                                    left: 16.0,
                                    top: 4.0,
                                  ),
                                  child: Text(
                                    '• Object Type: ${account.runtimeType}\n'
                                    '• Full Name: ${account.fullName}\n'
                                    '• Unique UID: ${account.uid}\n'
                                    '• Division: ${account.department}',
                                    style: const TextStyle(
                                      fontFamily: 'monospace',
                                      fontSize: 13,
                                      height: 1.4,
                                    ),
                                  ),
                                ),
                              ],
                            );
                          },
                        ),
                      ],
                    ),
                  ),
                ],
              ],
            ),
          ),
        ),
      ),
    );
  }
}
0
likes
160
points
45
downloads

Documentation

API reference

Publisher

verified publishero7planning.org

Weekly Downloads

An advanced Autocomplete input extension widget for Flutter FormBuilder, supporting type-safe predictive text filtering and async data fetching.

Homepage
Repository (GitHub)
View/report issues

License

BSD-3-Clause (license)

Dependencies

flutter, flutter_form_builder

More

Packages that depend on form_builder_autocomplete