Dynamic Intake Builder

A powerful and flexible Flutter package for building custom intake forms with support for multiple question types, validation, and easy customization.

Features

Multiple Question Types

  • Text input for open-ended responses
  • Multiple choice (single selection)
  • Checkboxes (multiple selections)
  • Rating scale (1-10)

🎨 Customizable UI

  • Themeable with custom primary colors
  • Material Design 3 support
  • Responsive layout

🌍 Internationalization

  • Easy to customize all labels and strings
  • Support for multiple languages

Form Validation

  • Built-in field validation
  • Required field support
  • Form state management

📋 Complete Form Management

  • Add/remove questions dynamically
  • Add/remove options for multiple choice/checkbox questions
  • Save as draft functionality
  • Publish completed forms

Getting Started

Installation

Add this package to your pubspec.yaml:

dependencies:
  dynamic_intake_builder: ^0.1.0

Then run:

flutter pub get

Basic Usage

import 'package:dynamic_intake_builder/dynamic_intake_builder.dart';
import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Intake Builder Demo',
      theme: ThemeData(primarySwatch: Colors.teal),
      home: const MyHomePage(),
    );
  }
}

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

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

class _MyHomePageState extends State<MyHomePage> {
  late IntakeBuilderController _controller;

  @override
  void initState() {
    super.initState();
    _controller = IntakeBuilderController();
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Intake Form Builder')),
      body: DynamicIntakeBuilder(
        controller: _controller,
        translations: IntakeBuilderTranslations(),
        primaryColor: Colors.blue,
        onSave: () {
          print('Form saved!');
          print('Title: ${_controller.title}');
          print('Questions: ${_controller.questions.length}');
        },
        onPublish: () {
          print('Form published!');
        },
      ),
    );
  }
}

Usage Examples

Customizing Translations

DynamicIntakeBuilder(
  controller: _controller,
  translations: IntakeBuilderTranslations(
    title: 'My Custom Builder',
    formNameLabel: 'Nombre del Formulario*',
    addQuestionBtn: 'Agregar Pregunta',
    publishBtn: 'Publicar',
  ),
)

Accessing Form Data

final formData = {
  'title': _controller.title,
  'description': _controller.description,
  'questions': _controller.questions.map((q) => {
    'text': q.controller.text,
    'type': q.type.toString(),
    'required': q.isRequired,
    'options': q.options.map((o) => o.text).toList(),
  }).toList(),
};

Programmatically Adding Questions

// Add a text question
_controller.addQuestion();

// Convert it to multiple choice
_controller.updateQuestionType(0, IntakeQuestionType.multipleChoice);

// Add options
_controller.addOption(0);
_controller.addOption(0);

API Documentation

IntakeBuilderController

Main controller for managing form state.

Methods:

  • addQuestion() - Add a new question
  • removeQuestion(int index) - Remove a question
  • updateQuestionType(int index, IntakeQuestionType type) - Change question type
  • addOption(int index) - Add an option to multiple choice/checkbox
  • removeOption(int questionIndex, int optionIndex) - Remove an option
  • dispose() - Clean up resources

Properties:

  • title - Form title
  • description - Form description
  • questions - List of questions

IntakeQuestionType

Enum for question types:

  • text - Single line text input
  • multipleChoice - Multiple choice (single selection)
  • checkbox - Checkboxes (multiple selections)
  • rating - Rating scale

IntakeBuilderTranslations

Customizable UI strings. Default is English.

DynamicIntakeBuilder

Main widget for the UI.

Parameters:

  • controller (required) - IntakeBuilderController
  • translations (required) - IntakeBuilderTranslations
  • primaryColor - Theme color (default: Colors.teal)
  • onSave - Callback when save is pressed
  • onPublish - Callback when publish is pressed

Platform Support

  • ✅ iOS
  • ✅ Android
  • ✅ Web (Flutter web)
  • ✅ Windows
  • ✅ macOS
  • ✅ Linux

Requirements

  • Flutter >= 1.17.0
  • Dart >= 3.11.5

Best Practices

  1. Memory Management - Always dispose the controller:

    @override
    void dispose() {
      _controller.dispose();
      super.dispose();
    }
    
  2. Handle Form Data - Implement proper callbacks:

    onPublish: () {
      if (_validateForm()) {
        _submitFormData();
      }
    },
    
  3. Error Handling - Use try-catch for index operations:

    try {
      _controller.removeQuestion(0);
    } on RangeError {
      // Handle invalid index
    }
    

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

For issues, questions, or suggestions, please open an issue on GitHub.

Changelog

See CHANGELOG.md for release notes and version history.

Libraries

dynamic_intake_builder
A powerful and flexible Flutter package for building custom intake forms.