dynamic_json_form_builder 1.2.1 copy "dynamic_json_form_builder: ^1.2.1" to clipboard
dynamic_json_form_builder: ^1.2.1 copied to clipboard

A highly advanced, reusable, JSON-driven form builder for Flutter. Supports sections, all major field types (text, dropdown, date, slider, rating, color), custom theming, validation, conditional logic [...]

example/main.dart

import 'package:flutter/material.dart';
import 'package:dynamic_json_form_builder/json_form_builder.dart';

void main() => runApp(const MyApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Dynamic JSON Form Builder - Complete Demo',
      theme: ThemeData(
        primarySwatch: Colors.deepPurple,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      darkTheme: ThemeData.dark().copyWith(
        primaryColor: Colors.deepPurple[200],
      ),
      home: const ComprehensiveFormDemo(),
    );
  }
}

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

  @override
  State<ComprehensiveFormDemo> createState() => _ComprehensiveFormDemoState();
}

class _ComprehensiveFormDemoState extends State<ComprehensiveFormDemo> {
  final Map<String, dynamic> _formData = {};
  final Map<String, String?> _validationErrors = {};
  bool _isDarkMode = false;

  // Comprehensive form configuration showcasing ALL features
  final Map<String, dynamic> formConfig = {
    "id": "comprehensive_demo_form",
    "title": "🚀 Dynamic JSON Form Builder - Complete Demo",
    "description": "This form demonstrates ALL field types, validation, conditional logic, theming, and features available in the dynamic JSON form builder package.",
    "sections": [
      {
        "id": "basic_text_fields",
        "title": "📝 Text Input Fields",
        "description": "Various text input types with validation",
        "collapsible": true,
        "initiallyExpanded": true,
        "fields": [
          {
            "key": "fullName",
            "type": "text",
            "label": "Full Name",
            "placeholder": "Enter your full name...",
            "required": true,
            "minLength": 2,
            "maxLength": 50,
            "helperText": "First and last name required"
          },
          {
            "key": "email",
            "type": "email",
            "label": "Email Address",
            "placeholder": "your.email@example.com",
            "required": true,
            "helperText": "We'll never share your email"
          },
          {
            "key": "phone",
            "type": "phone",
            "label": "Phone Number",
            "placeholder": "+1 (555) 123-4567",
            "required": true,
            "helperText": "Include country code"
          },
          {
            "key": "website",
            "type": "text",
            "label": "Website URL",
            "placeholder": "https://your-website.com",
            "pattern": r"^https?:\/\/.+",
            "patternError": "Please enter a valid URL starting with http:// or https://",
            "helperText": "Optional: Your personal or business website"
          },
          {
            "key": "age",
            "type": "number",
            "label": "Age",
            "placeholder": "Enter your age",
            "required": true,
            "min": 13,
            "max": 120,
            "helperText": "Must be 13 or older"
          },
          {
            "key": "password",
            "type": "password",
            "label": "Password",
            "placeholder": "Create a secure password",
            "required": true,
            "minLength": 8,
            "helperText": "Minimum 8 characters"
          },
          {
            "key": "bio",
            "type": "multiline",
            "label": "Bio / About You",
            "placeholder": "Tell us about yourself...",
            "maxLength": 500,
            "helperText": "Optional: Brief description about yourself"
          }
        ]
      },
      {
        "id": "selection_fields",
        "title": "🎯 Selection & Choice Fields",
        "description": "Dropdowns, radio buttons, checkboxes, and multi-select",
        "collapsible": true,
        "initiallyExpanded": true,
        "fields": [
          {
            "key": "country",
            "type": "dropdown",
            "label": "Country",
            "options": ["United States", "Canada", "United Kingdom", "Australia", "Germany", "France", "Japan", "India", "Brazil", "Other"],
            "placeholder": "Select your country",
            "required": true,
            "helperText": "Your country of residence"
          },
          {
            "key": "gender",
            "type": "radio",
            "label": "Gender",
            "options": ["Male", "Female", "Non-binary", "Prefer not to say"],
            "required": true,
            "helperText": "Select your gender identity"
          },
          {
            "key": "interests",
            "type": "multi_select",
            "label": "Interests & Hobbies",
            "options": ["Technology", "Sports", "Music", "Art", "Travel", "Cooking", "Reading", "Gaming", "Photography", "Fitness"],
            "helperText": "Select all that apply"
          },
          {
            "key": "newsletter",
            "type": "checkbox",
            "label": "Subscribe to Newsletter",
            "helperText": "Receive updates about new features and releases"
          },
          {
            "key": "terms",
            "type": "checkbox",
            "label": "I agree to the Terms and Conditions",
            "required": true,
            "helperText": "Required to proceed"
          }
        ]
      },
      {
        "id": "interactive_fields",
        "title": "🎛️ Interactive & Rating Fields",
        "description": "Sliders, ratings, and color pickers",
        "collapsible": true,
        "initiallyExpanded": true,
        "fields": [
          {
            "key": "satisfaction",
            "type": "rating",
            "label": "Overall Satisfaction",
            "maxRating": 5,
            "allowHalfRating": true,
            "showLabels": true,
            "labels": ["Poor", "Fair", "Good", "Very Good", "Excellent"],
            "helperText": "Rate your experience with form builders",
            "required": true
          },
          {
            "key": "experience",
            "type": "rating",
            "label": "Development Experience (Years)",
            "maxRating": 10,
            "allowHalfRating": false,
            "showValue": true,
            "starSize": 35,
            "helperText": "How many years of development experience?"
          },
          {
            "key": "priority",
            "type": "slider",
            "label": "Project Priority",
            "min": 1,
            "max": 10,
            "divisions": 9,
            "showLabels": true,
            "showValue": true,
            "suffix": "/10",
            "helperText": "How important is this project? (1=Low, 10=Critical)",
            "required": true
          },
          {
            "key": "budget",
            "type": "slider",
            "label": "Budget Range",
            "min": 0,
            "max": 10000,
            "divisions": 20,
            "showLabels": true,
            "showValue": true,
            "prefix": r"$",
            "helperText": "Project budget in USD"
          },
          {
            "key": "completion",
            "type": "slider",
            "label": "Project Completion",
            "min": 0,
            "max": 100,
            "divisions": 10,
            "showLabels": true,
            "showValue": true,
            "suffix": "%",
            "helperText": "Current project completion percentage"
          },
          {
            "key": "themeColor",
            "type": "color",
            "label": "Preferred Theme Color",
            "showHexValue": true,
            "helperText": "Choose your preferred UI theme color"
          },
          {
            "key": "accentColor",
            "type": "color",
            "label": "Accent Color",
            "showHexValue": true,
            "helperText": "Secondary color for highlights"
          }
        ]
      },
      {
        "id": "datetime_fields",
        "title": "📅 Date & Time Fields",
        "description": "Date pickers and time selection",
        "collapsible": true,
        "initiallyExpanded": true,
        "fields": [
          {
            "key": "birthDate",
            "type": "date",
            "label": "Date of Birth",
            "placeholder": "Select your birth date",
            "required": true,
            "helperText": "Used for age verification"
          },
          {
            "key": "projectStart",
            "type": "date",
            "label": "Project Start Date",
            "placeholder": "When will the project start?",
            "helperText": "Estimated project start date"
          },
          {
            "key": "deadline",
            "type": "date",
            "label": "Project Deadline",
            "placeholder": "Project completion deadline",
            "helperText": "Final delivery date"
          }
        ]
      },
      {
        "id": "file_upload",
        "title": "📎 File Upload Fields",
        "description": "File upload capabilities",
        "collapsible": true,
        "initiallyExpanded": false,
        "fields": [
          {
            "key": "profilePicture",
            "type": "file",
            "label": "Profile Picture",
            "multiple": false,
            "helperText": "Upload your profile picture (JPG, PNG)"
          },
          {
            "key": "documents",
            "type": "file",
            "label": "Project Documents",
            "multiple": true,
            "helperText": "Upload relevant project documents"
          }
        ]
      },
      {
        "id": "conditional_fields",
        "title": "🔀 Conditional Logic Demo",
        "description": "Fields that show/hide based on other field values",
        "collapsible": true,
        "initiallyExpanded": false,
        "fields": [
          {
            "key": "hasExperience",
            "type": "radio",
            "label": "Do you have development experience?",
            "options": ["Yes", "No"],
            "required": true,
            "helperText": "This will show different fields below"
          },
          {
            "key": "yearsExperience",
            "type": "number",
            "label": "Years of Experience",
            "placeholder": "Enter number of years",
            "visibleIf": {
              "hasExperience": "Yes"
            },
            "required": true,
            "helperText": "Only visible if you have experience"
          },
          {
            "key": "technologies",
            "type": "multi_select",
            "label": "Technologies You Know",
            "options": ["Flutter", "React", "Vue.js", "Angular", "Node.js", "Python", "Java", "C#", "Swift", "Kotlin"],
            "visibleIf": {
              "hasExperience": "Yes"
            },
            "helperText": "Select all technologies you're familiar with"
          },
          {
            "key": "learningGoals",
            "type": "multiline",
            "label": "What do you want to learn?",
            "placeholder": "Describe your learning goals...",
            "visibleIf": {
              "hasExperience": "No"
            },
            "helperText": "Only visible if you're new to development"
          },
          {
            "key": "contactMethod",
            "type": "dropdown",
            "label": "Preferred Contact Method",
            "options": ["Email", "Phone", "SMS", "Video Call"],
            "required": true,
            "helperText": "How would you like us to contact you?"
          },
          {
            "key": "phoneForContact",
            "type": "phone",
            "label": "Phone Number for Contact",
            "placeholder": "Enter phone number",
            "visibleIf": {
              "contactMethod": "Phone"
            },
            "required": true,
            "helperText": "Visible only if phone contact is selected"
          },
          {
            "key": "videoCallTime",
            "type": "text",
            "label": "Preferred Video Call Time",
            "placeholder": "e.g., Weekdays 2-4 PM EST",
            "visibleIf": {
              "contactMethod": "Video Call"
            },
            "helperText": "When are you available for video calls?"
          }
        ]
      },
      {
        "id": "advanced_validation",
        "title": "✅ Advanced Validation Demo",
        "description": "Custom validation patterns and rules",
        "collapsible": true,
        "initiallyExpanded": false,
        "fields": [
          {
            "key": "username",
            "type": "text",
            "label": "Username",
            "placeholder": "Enter username (letters, numbers, underscore only)",
            "required": true,
            "pattern": r"^[a-zA-Z0-9_]{3,20}$",
            "patternError": "Username must be 3-20 characters, letters/numbers/underscore only",
            "helperText": "3-20 characters, alphanumeric and underscore only"
          },
          {
            "key": "zipCode",
            "type": "text",
            "label": "ZIP/Postal Code",
            "placeholder": "Enter ZIP code",
            "pattern": r"^\d{5}(-\d{4})?$",
            "patternError": "Please enter a valid ZIP code (12345 or 12345-6789)",
            "helperText": "US ZIP code format"
          },
          {
            "key": "confirmEmail",
            "type": "email",
            "label": "Confirm Email",
            "placeholder": "Re-enter your email address",
            "required": true,
            "helperText": "Must match the email address above"
          }
        ]
      }
    ]
  };

  FormTheme getFormTheme() {
    return _isDarkMode ? FormTheme.dark() : FormTheme.light();
  }

  void _handleFormChanged(Map<String, dynamic> data) {
    setState(() {
      _formData.clear();
      _formData.addAll(data);
    });
    print('📝 Form data changed: ${data.keys.length} fields updated');
  }

  void _handleValidationChanged(Map<String, String?> errors) {
    setState(() {
      _validationErrors.clear();
      _validationErrors.addAll(errors);
    });
    final errorCount = errors.values.where((e) => e != null && e.isNotEmpty).length;
    if (errorCount > 0) {
      print('❌ Validation errors: $errorCount fields have errors');
    }
  }

  void _handleFormSubmit(Map<String, dynamic> data) {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Row(
          children: [
            Icon(Icons.check_circle, color: Colors.green),
            SizedBox(width: 8),
            Text('Form Submitted Successfully!'),
          ],
        ),
        content: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisSize: MainAxisSize.min,
            children: [
              Text('✅ Form submitted with ${data.keys.length} fields'),
              const SizedBox(height: 16),
              const Text('📊 Form Data Summary:', 
                style: TextStyle(fontWeight: FontWeight.bold)),
              const SizedBox(height: 8),
              ...data.entries.take(10).map((entry) => Padding(
                padding: const EdgeInsets.only(bottom: 4),
                child: RichText(
                  text: TextSpan(
                    style: Theme.of(context).textTheme.bodyMedium,
                    children: [
                      TextSpan(
                        text: '${entry.key}: ',
                        style: const TextStyle(fontWeight: FontWeight.w600),
                      ),
                      TextSpan(
                        text: entry.value?.toString() ?? 'null',
                      ),
                    ],
                  ),
                ),
              )),
              if (data.keys.length > 10)
                Text('... and ${data.keys.length - 10} more fields'),
            ],
          ),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text('Close'),
          ),
          ElevatedButton(
            onPressed: () {
              Navigator.pop(context);
              print('💾 Complete form data: $data');
            },
            child: const Text('View Full Data in Console'),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final errorCount = _validationErrors.values.where((e) => e != null && e.isNotEmpty).length;
    final filledFields = _formData.values.where((v) => v != null && v.toString().isNotEmpty).length;
    
    return Scaffold(
      appBar: AppBar(
        title: const Text('🚀 Dynamic JSON Form Builder'),
        backgroundColor: _isDarkMode ? Colors.grey[900] : Colors.deepPurple,
        foregroundColor: Colors.white,
        elevation: 0,
        actions: [
          IconButton(
            icon: Icon(_isDarkMode ? Icons.light_mode : Icons.dark_mode),
            onPressed: () {
              setState(() {
                _isDarkMode = !_isDarkMode;
              });
            },
            tooltip: 'Toggle theme',
          ),
          IconButton(
            icon: const Icon(Icons.info_outline),
            onPressed: () {
              showDialog(
                context: context,
                builder: (context) => AlertDialog(
                  title: const Text('📚 Demo Information'),
                  content: const SingleChildScrollView(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Text('This demo showcases ALL features of the Dynamic JSON Form Builder:'),
                        SizedBox(height: 8),
                        Text('✅ All field types (text, email, dropdown, rating, slider, color, etc.)'),
                        Text('✅ Sections with collapsible/expandable functionality'),
                        Text('✅ Advanced validation with custom patterns'),
                        Text('✅ Conditional logic (fields show/hide based on other values)'),
                        Text('✅ Custom theming (light/dark mode)'),
                        Text('✅ Form state management'),
                        Text('✅ File upload simulation'),
                        Text('✅ Real-time form data updates'),
                        SizedBox(height: 12),
                        Text('🎯 Try interacting with different fields to see conditional logic in action!'),
                      ],
                    ),
                  ),
                  actions: [
                    TextButton(
                      onPressed: () => Navigator.pop(context),
                      child: const Text('Got it!'),
                    ),
                  ],
                ),
              );
            },
            tooltip: 'Show demo info',
          ),
        ],
      ),
      body: Column(
        children: [
          // Status bar
          Container(
            width: double.infinity,
            padding: const EdgeInsets.all(16),
            color: _isDarkMode ? Colors.grey[850] : Colors.deepPurple[50],
            child: Row(
              children: [
                Expanded(
                  child: Text(
                    '📊 Status: $filledFields fields filled',
                    style: TextStyle(
                      fontWeight: FontWeight.w600,
                      color: _isDarkMode ? Colors.white : Colors.deepPurple[700],
                    ),
                  ),
                ),
                if (errorCount > 0)
                  Container(
                    padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
                    decoration: BoxDecoration(
                      color: Colors.red[100],
                      borderRadius: BorderRadius.circular(12),
                    ),
                    child: Text(
                      '❌ $errorCount errors',
                      style: const TextStyle(
                        color: Colors.red,
                        fontWeight: FontWeight.w600,
                        fontSize: 12,
                      ),
                    ),
                  ),
                if (errorCount == 0 && filledFields > 0)
                  Container(
                    padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
                    decoration: BoxDecoration(
                      color: Colors.green[100],
                      borderRadius: BorderRadius.circular(12),
                    ),
                    child: const Text(
                      '✅ All valid',
                      style: TextStyle(
                        color: Colors.green,
                        fontWeight: FontWeight.w600,
                        fontSize: 12,
                      ),
                    ),
                  ),
              ],
            ),
          ),
          // Form
          Expanded(
            child: SingleChildScrollView(
              padding: const EdgeInsets.all(16),
              child: JsonFormBuilder(
                config: formConfig,
                theme: getFormTheme(),
                onChanged: _handleFormChanged,
                onValidation: _handleValidationChanged,
                onSubmit: _handleFormSubmit,
              ),
            ),
          ),
          // Submit button
          Container(
            width: double.infinity,
            padding: const EdgeInsets.all(16),
            child: ElevatedButton(
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.deepPurple,
                foregroundColor: Colors.white,
                padding: const EdgeInsets.symmetric(vertical: 16),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(12),
                ),
              ),
              onPressed: errorCount == 0 && filledFields > 0
                  ? () => _handleFormSubmit(_formData)
                  : null,
              child: Text(
                errorCount > 0
                    ? '❌ Fix $errorCount errors to submit'
                    : filledFields == 0
                        ? '📝 Fill out the form to submit'
                        : '🚀 Submit Form ($filledFields fields)',
                style: const TextStyle(
                  fontSize: 16,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
2
likes
130
points
32
downloads

Publisher

unverified uploader

Weekly Downloads

A highly advanced, reusable, JSON-driven form builder for Flutter. Supports sections, all major field types (text, dropdown, date, slider, rating, color), custom theming, validation, conditional logic, and custom user-defined fields.

Repository (GitHub)
View/report issues

Topics

#form #json #dynamic #builder #flutter

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

auto_size_text, flutter

More

Packages that depend on dynamic_json_form_builder