Skip to content

A dynamic form rendering and submission package for Flutter using Form.io schemas.

License

Notifications You must be signed in to change notification settings

mskayali/formio_flutter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

48 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Form.io Flutter

A comprehensive Flutter package for rendering Form.io forms with full feature parity.

Pub Version License

Features

✅ Complete Component Support (100%)

All 41 Form.io components are fully implemented:

  • Basic: TextField, TextArea, Number, Password, Email, URL, PhoneNumber, Tags, Address
  • Advanced: DateTime, Day, Time, Currency, Survey
  • Layout: Panel, Table, Tabs, Well, Columns, FieldSet, Container
  • Data: Select, SelectBoxes, Checkbox, Radio, Button
  • Special: File, Signature, Hidden, HTML, Content, Alert, Form

✅ Full Flutter Theme Support

  • 100% ThemeData integration - All components respect inputDecorationTheme and colorScheme
  • Zero hardcoded styles - Border radius, colors, and borders from theme
  • Live theme switching - Change themes at runtime (see example app)
  • Consistent UI - Components automatically match your design system

✅ Internationalization (i18n)

  • 60+ customizable strings - All user-facing text translatable
  • Built-in locales: English (default), Turkish
  • Easy custom locales - Create your own language support
  • Global configuration - Set once via ComponentFactory.setLocale()

✅ Custom Widget Callbacks

  • Custom pickers - Use Material, Cupertino, or your own date/time pickers
  • Custom file picker - Integrate any file picker package
  • Custom HTTP client - Use dio, http, or custom networking
  • 100% optional - Defaults work out of the box

✅ Comprehensive Validation System

  • Required, Pattern (regex), Min/Max Length
  • Min/Max Words, Min/Max Numeric Values
  • Email, URL, JSON format validation
  • Date/Time validation (minDate, maxDate, minYear, maxYear)
  • File validation (fileSize, filePattern with MIME types)
  • Custom JavaScript validation (via flutter_js)
  • Cross-field validation (password confirmation, field comparison)
  • Config-driven validation with FormioValidators.fromConfig()

✅ Advanced Form Features (~98% Form.io Parity)

  • Wizard Forms: Multi-page forms with navigation and progress tracking
  • Calculated Values: Auto-calculated fields using JSONLogic or JavaScript
  • Conditional Logic: Show/hide components based on form data (Simple + JSONLogic)
  • Default Values: Pre-populate form fields
  • Data Grids: Editable table data

✅ Complete API Integration

  • Form CRUD operations
  • Submission management
  • User authentication
  • Action handling
  • Role-based access

Installation

Add to your pubspec.yaml:

dependencies:
  formio: ^1.0.0

Quick Start

1. Basic Form Rendering

import 'package:formio/flutter_formio.dart';

// Set your Form.io server URL
ApiClient.setBaseUrl(Uri.parse('https://examples.form.io'));

// Fetch and render a form
final formService = FormService(ApiClient());
final form = await formService.fetchForm('formPath');

// Display the form
FormRenderer(
  form: form,
  onSubmit: (data) => print('Submitted: $data'),
  onError: (error) => print('Error: $error'),
)

2. Theme Customization

import 'package:flutter/material.dart';

MaterialApp(
  theme: ThemeData(
    colorScheme: ColorScheme.fromSeed(seedColor: Colors.purple),
    inputDecorationTheme: InputDecorationTheme(
      border: OutlineInputBorder(
        borderRadius: BorderRadius.circular(20), // Rounded inputs!
      ),
      focusedBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(20),
        borderSide: BorderSide(color: Colors.purple, width: 2),
      ),
    ),
    elevatedButtonTheme: ElevatedButtonThemeData(
      style: ElevatedButton.styleFrom(
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(20), // Rounded buttons!
        ),
      ),
    ),
  ),
  home: MyFormPage(),
)
// All form components automatically use this theme!

3. Internationalization (i18n)

import 'package:formio/flutter_formio.dart';

void main() {
  // Set global locale (before MaterialApp)
  ComponentFactory.setLocale(FormioLocale.tr()); // Turkish
  
  // Or create custom locale
  ComponentFactory.setLocale(FormioLocale(
    submit: 'إرسال',      // Arabic
    cancel: 'إلغاء',
    clear: 'مسح',
    // ... 60+ customizable strings
  ));
  
  runApp(MyApp());
}

4. Custom Widget Callbacks

import 'package:file_picker/file_picker.dart';

FormRenderer(
  form: form,
  
  // Optional: Use your own file picker
  onFilePick: ({required allowMultiple, allowedExtensions}) async {
    final result = await FilePicker.platform.pickFiles(
      allowMultiple: allowMultiple,
      type: allowedExtensions != null ? FileType.custom : FileType.any,
      allowedExtensions: allowedExtensions,
    );
    return result?.files.map((f) => FileData(
      name: f.name,
      bytes: f.bytes,
      path: f.path,
    )).toList();
  },
  
  // Optional: Use Cupertino date picker
  onDatePick: ({required initialDate, required firstDate, required lastDate}) async {
    return await showCupertinoDatePicker(...);
  },
)

5. Wizard (Multi-Page) Forms

final wizardConfig = WizardConfig.fromJson({
  'display': 'wizard',
  'components': [
    {
      'type': 'panel',
      'key': 'page1',
      'label': 'Personal Info',
      'components': [...]
    },
    {
      'type': 'panel',
      'key': 'page2',
      'label': 'Address',
      'components': [...]
    },
  ]
});

WizardRenderer(
  wizardConfig: wizardConfig,
  onSubmit: (data) => print('Wizard completed: $data'),
  showProgress: true,
)

3. Calculated Values

ComponentModel.fromJson({
  'type': 'currency',
  'key': 'total',
  'label': 'Total',
  'calculateValue': {
    '+': [
      {'var': 'data.subtotal'},
      {'var': 'data.tax'}
    ]
  },
  'allowCalculateOverride': false,
})

4. Cross-Field Validation

// Password confirmation
ComponentModel.fromJson({
  'type': 'password',
  'key': 'confirmPassword',
  'label': 'Confirm Password',
  'validate': {
    'required': true,
    'matchField': 'password',
  },
})

Advanced Usage

Custom Validation

TextFormField(
  validator: (val) => FormioValidators.combine([
    () => FormioValidators.required(val, fieldName: 'Email'),
    () => FormioValidators.email(val),
    () => FormioValidators.maxLength(val, 100),
  ]),
)

Conditional Logic

Components support both simple and JSONLogic conditionals:

{
  "conditional": {
    "when": "country",
    "eq": "USA",
    "show": true
  }
}

Or with JSONLogic:

{
  "conditional": {
    "json": {
      "and": [
        {"==": [{"var": "data.country"}, "USA"]},
        {">": [{"var": "data.age"}, 18]}
      ]
    }
  }
}

Implementation Status

Feature Category Coverage Status
Components 100% (41/41) ✅ Complete
Validation 95% ✅ Complete
Wizard Forms 100% ✅ Complete
Calculated Values 95% (JSONLogic) ✅ Complete
Conditional Logic 100% ✅ Complete
API Integration 100% ✅ Complete

Overall: ~92% Form.io feature parity

Architecture

lib/
├── core/               # Core functionality
│   ├── validators.dart        # Centralized validation
│   ├── calculation_evaluator.dart  # Calculated values
│   ├── conditional_evaluator.dart  # Conditional logic
│   └── utils.dart            # Helper functions
├── models/             # Data models
│   ├── form.dart
│   ├── component.dart
│   └── wizard_config.dart
├── widgets/            # UI components
│   ├── form_renderer.dart
│   ├── wizard_renderer.dart
│   ├── component_factory.dart
│   └── components/           # All 41 components
├── services/           # API services
│   ├── form_service.dart
│   ├── submission_service.dart
│   └── auth_service.dart
└── network/
    └── api_client.dart

Testing

The package includes comprehensive test coverage:

flutter test

Test Results: 56/56 passing

  • Validator tests: 28/28
  • Calculation tests: 13/13
  • Cross-field validation: 15/15

Live Demo

Run the example app to test with real forms:

cd example
flutter run

The demo loads forms from a live Form.io server and demonstrates all features.

Limitations

JavaScript Expressions

Custom JavaScript code is not supported. Use JSONLogic instead:

Not Supported:

"calculateValue": "value = data.price * data.quantity"

Use JSONLogic:

"calculateValue": {
  "*": [
    {"var": "data.price"},
    {"var": "data.quantity"}
  ]
}

Not Implemented (Low Priority)

  • PDF generation (backend feature)
  • Unique validation via API
  • File upload to external providers (S3, Azure)
  • Google Places autocomplete

Contributing

Contributions are welcome! Please read our contributing guidelines.

License

MIT License - see LICENSE file for details.

Support

Credits

Built with ❤️ for the Flutter community.

Form.io is a trademark of Form.io, Inc.

About

A dynamic form rendering and submission package for Flutter using Form.io schemas.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors