A powerful local-persistence layer for Flutter forms that remembers user input and provides intelligent profile-based autofill.
Standard browser or OS autofill is great for a user's own identity, but it fails for applications that manage multiple entities. Think of:
- A logistics app pre-filling a customer's shipping details.
- A maintenance app remembering the state of different vehicle IDs.
- A medical app recalling a patient's previous visit data.
smart_form_memorysolves this by creating a powerful, local "memory" for your forms, tied to a unique identifier you control.
| Initial State (Empty Form) | Suggestions | Autofill |
|---|---|---|
![]() |
![]() |
![]() |
- 🧠 Record-Based Memory: Ties entire form states to a unique key (Phone, ID, Email).
- 🛡️ Non-Destructive Autofill: Intelligently updates only empty fields. It will never overwrite what a user has already manually typed.
- 🚀 Zero Boilerplate: No need to manually manage
TextEditingControllersorJSONserialization. - 🛡️ **Built-in OS Support: Works seamlessly with iOS/Android Autofill hints while providing its own local history.
- 🔌 Extensible Storage: Use the built-in
SharedPreferencesengine or plug in your own (Hive, Secure Storage, etc.).
Add the package to your pubspec.yaml:
dependencies:
smart_form_memory: ^1.0.0Wrap your form in a SmartForm and use the specialized fields. The uniqueFieldKey is the "trigger" that saves and recalls data.
import 'package:smart_form_memory/smart_form_memory.dart';
// ... inside your build method
SmartForm(
uniqueFieldKey: 'phone_number',
child: Column(
children: [
// The Primary Key field (triggers history suggestions)
const SmartFormTextField(
fieldKey: 'phone_number',
decoration: InputDecoration(labelText: 'Phone Number'),
keyboardType: TextInputType.phone,
),
// Automatically filled when a phone number is selected
const SmartFormTextField(
fieldKey: 'full_name',
decoration: InputDecoration(labelText: 'Full Name'),
),
// Modern Radio Selection Cards
const SmartFormRadio(
fieldKey: 'address_type',
label: 'Location Type',
options: ['Home', 'Office', 'Other'],
),
const SizedBox(height: 20),
// Save Button (essential for the workflow)
Builder(
builder: (ctx) => ElevatedButton(
child: const Text('Save Record'),
onPressed: () async {
// Save the current form state to local memory
final saved = await SmartForm.of(ctx)?.save() ?? false;
if (saved && ctx.mounted) {
ScaffoldMessenger.of(ctx).showSnackBar(
const SnackBar(content: Text('Record saved!')),
);
}
},
),
),
],
),
)Clearing the Form vs. Wiping History You can clear the UI inputs without affecting your database, or wipe the database entirely.
// 1. Clear current UI fields only
SmartForm.of(context)?.resetForm();
// 2. Wipe ALL saved records from disk
const storage = SharedPrefsSmartFormStorage();
await storage.clearAll();
await SmartForm.of(context)?.refreshIds(); // Sync the UIImplement the SmartFormStorage interface to use Hive, Secure Storage, or your own backend.
class MySecureStorage implements SmartFormStorage {
@override
Future<void> write(String id, Map<String, dynamic> data) async { /* ... */ }
@override
Future<Map<String, dynamic>?> read(String id) async { /* ... */ }
@override
Future<List<String>> getAllKeys() async => [];
@override
Future<void> clearAll() async {}
}| Component | Description |
|---|---|
SmartForm |
The root coordinator widget. It manages the registry of field controllers and handles communication with the SmartFormStorage engine. |
uniqueFieldKey |
A required String that defines the "Primary Key" (e.g., 'phone'). When this field is filled, it triggers history suggestions and form-wide autofill. |
SmartForm.of(context) |
A static method used to access the SmartFormController from any child widget. |
| Component | Best For | Storage Behavior |
|---|---|---|
SmartFormTextField |
Text, Phones, Emails, or IDs. | Stores as a raw String. |
SmartFormRadio |
Modern, card-based single selection. | Stores the selected option as a String. |
SmartFormDropdown |
Standard Material dropdown menus. | Stores the selected value as a String. |
SmartFormTagField |
Multi-select chips or category tags. | Stores as a comma-separated String. |
When using SmartForm.of(context), you gain access to these powerful methods:
By calling SmartForm.of(context), you can trigger these actions from your buttons or logic:
-
save(): Captures all current field values and persists them to local storage using theuniqueFieldKeyvalue as the record ID. -
resetForm(): Clears the current text and selections from all registered fields in the UI. Does not delete saved records from storage. -
loadAndAutofill(id): Manually triggers a data fetch for a specific record ID and populates all matching fields. -
refreshIds(): Force-reloads the list of saved IDs from the storage engine (essential after manual history deletion).
This is a community-driven project. We welcome Pull Requests for:
🏗 New Field Types: Support for Dropdowns, Checkboxes, and DatePickers.
💾 Storage Adapters: Official implementations for Hive or SQLite.
🎨 UI Customization: More control over the Autocomplete overlay styling.
📄 License This project is licensed under the MIT License - see the LICENSE file for details.


