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!