Skip to main content

JsonInputFieldAppi

A specialized input widget for editing and validating JSON data with syntax highlighting and interactive editing capabilities.

Overview

JsonInputFieldAppi provides a powerful interface for JSON data input and editing. It combines a text field trigger with a full-screen JSON editor dialog, offering syntax highlighting, validation, and support for both object and string data modes.

Features

  • 📝 Interactive JSON Editor - Full-screen editing with syntax highlighting
  • 🎨 Syntax Highlighting - Color-coded JSON elements for better readability
  • Built-in Validation - Automatic JSON validation and error handling
  • 📱 Modal Interface - Clean dialog-based editing experience
  • 🔄 Dual Mode Support - Object editing and raw string editing
  • 🎯 Form Integration - Seamless integration with Flutter forms
  • 🌈 Custom Theming - Customizable color schemes and styling
  • 💾 State Management - Automatic state preservation and validation

Basic Usage

JsonInputFieldAppi(
widgetKey: GlobalKey<FormFieldState<String>>(),
formKey: GlobalKey<FormState>(),
lable: 'Configuration',
hint: 'Enter JSON configuration',
title: 'Edit Configuration',
mandatory: true,
onChanged: (jsonData) {
print('JSON Data: $jsonData');
},
)

Properties

PropertyTypeDefaultDescription
widgetKeyGlobalKey<FormFieldState<String>>requiredForm field key for validation
formKeyGlobalKey<FormState>requiredForm key for form management
lableString?nullLabel text for the input field
hintString?nullHint text for the input field
titleString?nullTitle for the JSON editor dialog
mandatorybool?falseWhether the field is required
onChangedFunction(Map&lt;String, dynamic&gt;)?nullCallback for JSON object changes
onChangedStringFunction(String)?nullCallback for string data changes
initialValueMap&lt;String, dynamic&gt;?nullInitial JSON object value
initialStringString?nullInitial string value (for string mode)
suffixIconWidget?nullCustom suffix icon for the trigger field
preffixIconWidget?nullCustom prefix icon for the trigger field
stringDatabool?falseEnable string editing mode instead of object mode
textStyleTextStyle?nullText style for the trigger field

Examples

Basic JSON Object Editor

class JsonFormExample extends StatefulWidget {

_JsonFormExampleState createState() => _JsonFormExampleState();
}

class _JsonFormExampleState extends State<JsonFormExample> {
final _formKey = GlobalKey<FormState>();
final _jsonFieldKey = GlobalKey<FormFieldState<String>>();
Map&lt;String, dynamic&gt; configData = {};


Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: [
JsonInputFieldAppi(
widgetKey: _jsonFieldKey,
formKey: _formKey,
lable: 'Application Configuration',
hint: 'Click to edit JSON configuration',
title: 'Edit App Configuration',
mandatory: true,
initialValue: {
'theme': 'dark',
'language': 'en',
'features': ['notifications', 'analytics']
},
onChanged: (jsonData) {
setState(() {
configData = jsonData;
});
},
),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
print('Valid JSON: $configData');
}
},
child: Text('Save Configuration'),
),
],
),
);
}
}

String Mode Editor

JsonInputFieldAppi(
widgetKey: GlobalKey<FormFieldState<String>>(),
formKey: GlobalKey<FormState>(),
lable: 'Raw JSON Data',
hint: 'Enter raw JSON string',
title: 'Edit JSON String',
stringData: true, // Enable string mode
initialString: '{"key": "value"}',
onChangedString: (jsonString) {
print('JSON String: $jsonString');
// Parse and validate if needed
try {
final parsed = json.decode(jsonString);
print('Parsed successfully: $parsed');
} catch (e) {
print('Invalid JSON: $e');
}
},
)

With Custom Styling

JsonInputFieldAppi(
widgetKey: _fieldKey,
formKey: _formKey,
lable: 'API Response',
hint: 'Configure API response format',
title: 'API Response Editor',
textStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
),
suffixIcon: Icon(
Icons.code,
color: Colors.blue,
),
preffixIcon: Icon(
Icons.settings,
color: Colors.grey,
),
onChanged: (data) {
handleApiConfigChange(data);
},
)

Complex JSON Structure

JsonInputFieldAppi(
widgetKey: _complexFieldKey,
formKey: _formKey,
lable: 'Database Schema',
hint: 'Define database schema',
title: 'Database Schema Editor',
mandatory: true,
initialValue: {
'tables': {
'users': {
'columns': {
'id': {'type': 'integer', 'primary': true},
'name': {'type': 'string', 'required': true},
'email': {'type': 'string', 'unique': true}
}
},
'posts': {
'columns': {
'id': {'type': 'integer', 'primary': true},
'title': {'type': 'string', 'required': true},
'content': {'type': 'text'},
'user_id': {'type': 'integer', 'foreign_key': 'users.id'}
}
}
}
},
onChanged: (schema) {
validateAndSaveSchema(schema);
},
)

JSON Editor Features

Syntax Highlighting

The JSON editor provides color-coded syntax highlighting:

  • Keys: White text for object keys
  • Strings: Orange text for string values
  • Numbers: Red text for numeric values
  • Booleans: Purple text for true/false values
  • Brackets: Blue text for structural elements
  • Comments: Grey text for comments (if supported)
  • Errors: Red highlighting for syntax errors

Theme Customization

The editor uses a dark theme optimized for JSON editing:

JsonEditorThemeData(
lightTheme: JsonTheme(
defaultStyle: TextStyle(
color: Colors.yellow,
fontSize: 20,
fontWeight: FontWeight.w600,
),
bracketStyle: TextStyle(color: Colors.blue, fontSize: 20),
numberStyle: TextStyle(color: Colors.red),
stringStyle: TextStyle(color: Colors.orange),
boolStyle: TextStyle(color: Colors.purple),
keyStyle: TextStyle(color: Colors.white),
commentStyle: TextStyle(color: Colors.grey),
errorStyle: TextStyle(color: Colors.red),
),
)

Validation

Automatic Validation

The widget automatically validates JSON structure and provides feedback:

JsonInputFieldAppi(
// ... other properties
mandatory: true,
onChanged: (data) {
// Validation happens automatically
// Invalid JSON will trigger form validation errors
},
)

Custom Validation

Implement additional validation logic:

bool validateJsonStructure(Map&lt;String, dynamic&gt; data) {
// Custom validation logic
if (!data.containsKey('required_field')) {
return false;
}

if (data['version'] == null || data['version'] < 1.0) {
return false;
}

return true;
}

JsonInputFieldAppi(
// ... other properties
onChanged: (data) {
if (validateJsonStructure(data)) {
// Valid structure
saveConfiguration(data);
} else {
// Show error message
showErrorDialog('Invalid JSON structure');
}
},
)

Integration Patterns

With State Management

// Using Provider
class ConfigProvider extends ChangeNotifier {
Map&lt;String, dynamic&gt; _config = {};

Map&lt;String, dynamic&gt; get config => _config;

void updateConfig(Map&lt;String, dynamic&gt; newConfig) {
_config = newConfig;
notifyListeners();
}
}

// In your widget
Consumer<ConfigProvider>(
builder: (context, provider, child) {
return JsonInputFieldAppi(
initialValue: provider.config,
onChanged: (data) {
provider.updateConfig(data);
},
// ... other properties
);
},
)

With API Integration

class ApiConfigWidget extends StatefulWidget {

_ApiConfigWidgetState createState() => _ApiConfigWidgetState();
}

class _ApiConfigWidgetState extends State<ApiConfigWidget> {
Map&lt;String, dynamic&gt; apiConfig = {};
bool isLoading = false;

Future<void> saveConfig() async {
setState(() => isLoading = true);

try {
await ApiService.updateConfiguration(apiConfig);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Configuration saved successfully')),
);
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error saving configuration: $e')),
);
} finally {
setState(() => isLoading = false);
}
}


Widget build(BuildContext context) {
return Column(
children: [
JsonInputFieldAppi(
widgetKey: GlobalKey<FormFieldState<String>>(),
formKey: GlobalKey<FormState>(),
lable: 'API Configuration',
title: 'Edit API Settings',
onChanged: (data) {
setState(() {
apiConfig = data;
});
},
),
SizedBox(height: 16),
ElevatedButton(
onPressed: isLoading ? null : saveConfig,
child: isLoading
? CircularProgressIndicator()
: Text('Save Configuration'),
),
],
);
}
}

Best Practices

  1. Validation: Always implement proper validation for critical JSON data
  2. Error Handling: Provide clear error messages for invalid JSON
  3. Performance: For large JSON objects, consider implementing lazy loading
  4. User Experience: Use meaningful titles and labels for the editor dialog
  5. Data Backup: Consider implementing auto-save or draft functionality
  6. Security: Validate and sanitize JSON data before processing

Common Use Cases

  • Configuration Management: App settings and configuration files
  • API Testing: Request/response body editing
  • Data Import/Export: Structured data manipulation
  • Schema Definition: Database or API schema configuration
  • Template Editing: JSON-based template systems
  • Metadata Management: File or content metadata editing

Migration Notes

When upgrading from basic text fields:

  1. Replace text controllers with form keys for proper validation
  2. Update callbacks to handle Map<String, dynamic> instead of strings
  3. Implement proper error handling for JSON parsing
  4. Consider using string mode for backward compatibility

Ready for rich text editing? Check out QuillEditorAppi for advanced text formatting capabilities!