Flutter SurveyJS
A Flutter package for rendering SurveyJS forms natively in Flutter applications. This package provides a complete solution for displaying dynamic surveys with support for all major question types.
Features
✅ Complete SurveyJS Integration - Render SurveyJS JSON definitions in Flutter
✅ Dynamic UI Generation - UI is automatically created from JSON
✅ 19+ Question Types - Text, radio, checkbox, dropdown, rating, matrix, slider, file upload, signature, and more
✅ Custom Question Types - Register your own flutter widgets for custom question types
✅ Nested Panels - Support for grouping questions in panels
✅ JSON Validation - Validates survey JSON structure before initialization
✅ Conditional Logic - Full support for SurveyJS visibility conditions and skip logic
✅ Validation - Built-in validation with error messages
✅ Multi-page Surveys - Navigate through survey pages with progress indicator
✅ Customizable Theme - Customize colors, fonts, and styling
✅ Media Support - File upload, image picker, and signature capture
✅ Cross-platform - Works on iOS, Android, and Web
Supported Question Types
Basic Input
- text - Single-line text input with various input types (email, number, tel, url)
- comment - Multi-line text area
- radiogroup - Single choice selection
- checkbox - Multiple choice selection
- dropdown - Dropdown selection
- boolean - Yes/No toggle buttons
- rating - Star or numeric rating scale
Advanced
- matrix - Matrix of radio buttons
- slider - Slider with customizable range
- tagbox - Multi-select with chips
- ranking - Drag-and-drop ranking
- multipletext - Multiple text inputs in one question
Media & Special
- file - File upload with camera capture
- imagepicker - Image selection from gallery or camera
- signaturepad - Signature drawing
- html - Display HTML content
- expression - Display calculated values
Complex
- matrixdropdown - Matrix with per-cell editor mapping from JSON column config
- matrixdynamic - Dynamic matrix with add/remove rows
- paneldynamic - Dynamic panels with template elements
Installation
Add this to your package's pubspec.yaml file:
dependencies:
surveyjs_flutter:
path: ../surveyjs_flutter # Use path dependency for now
Then run:
flutter pub get
Android Setup (Important)
Due to the complex nature of SurveyJS traversing thousands of UI Observables, the default flutter_js Android engine (QuickJS) is prone to locking the UI Thread and causing ANR crashes on heavy forms. This package forces JavaScriptCore (a JIT accelerated C++ engine) on Android to achieve identical performance to iOS.
To enable this engine bypass safely, you must link the JavaScriptCore binary inside your Android project:
- Add
jitpackto your project-levelandroid/build.gradle(orsettings.gradle):
allprojects {
repositories {
google()
mavenCentral()
maven { url "https://jitpack.io" }
}
}
- Add the native binary dependency to your app-level
android/app/build.gradle:
dependencies {
implementation "com.github.fast-development.android-js-runtimes:fastdev-jsruntimes-jsc:0.3.4"
}
Usage
Basic Example
import 'package:flutter/material.dart';
import 'package:surveyjs_flutter/surveyjs_flutter.dart';
class MySurveyPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SurveyScreen(
config: SurveyConfig(
surveyJson: {
"title": "Customer Satisfaction Survey",
"pages": [
{
"elements": [
{
"type": "rating",
"name": "satisfaction",
"title": "How satisfied are you with our service?",
"isRequired": true,
"rateMin": 1,
"rateMax": 5,
},
{
"type": "comment",
"name": "feedback",
"title": "Additional feedback",
},
]
}
]
},
onComplete: (result) {
print('Survey completed!');
print('Results: ${result.data}');
},
onValueChanged: (questionName, value) {
print('$questionName changed to: $value');
},
),
);
}
}
With Custom Theme
SurveyScreen(
config: SurveyConfig(
surveyJson: mySurveyJson,
theme: SurveyTheme(
primaryColor: Colors.blue,
errorColor: Colors.red,
questionTitleStyle: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
onComplete: (result) {
// Handle completion
},
),
)
Accessing Survey Results
onComplete: (SurveyResult result) {
// Get all data
final allData = result.data;
// Get specific answer
final satisfaction = result.getValue('satisfaction');
// Check if question was answered
if (result.hasAnswer('feedback')) {
print('User provided feedback');
}
// Get timestamp
print('Completed at: ${result.timestamp}');
}
Advanced Usage
Custom Question Types
You can register your own Flutter widgets for custom question types defined in your JSON.
// 1. Define your custom widget
class ColorPickerWidget extends StatelessWidget {
final Map<String, dynamic> question;
final ValueChanged<dynamic> onChanged;
const ColorPickerWidget({required this.question, required this.onChanged});
@override
Widget build(BuildContext context) {
// implementing custom color picker...
return Container();
}
}
// 2. Register it globally
QuestionFactory.register('colorpicker', (context, question, onChanged) {
return ColorPickerWidget(question: question, onChanged: onChanged);
});
// 3. Or register strictly for one survey
SurveyScreen(
config: SurveyConfig(
surveyJson: mySurveyJson,
customBuilders: {
'colorpicker': (context, question, onChanged) => ColorPickerWidget(...)
}
)
)
JSON Validation
By default, the package specifically validates your JSON structure before initialization to catch errors early.
SurveyScreen(
config: SurveyConfig(
surveyJson: mySurveyJson,
// Disable validation if needed
validateJson: false,
// Handle validation errors manually
onValidationError: (errors) {
print('Validation failed: $errors');
}
)
)
Example App
Check out the /example directory for a complete example app showcasing:
- Customer Satisfaction Survey
- Job Application Form
- Product Feedback
- Health Assessment
- Event Registration
- Media Input Survey (file upload, image picker, signature)
- Advanced Question Types
- Slider Showcase
Run the example:
cd example
flutter run
Requirements
- Flutter SDK: >=3.0.0
- Dart SDK: >=3.0.0
Dependencies
flutter_js- JavaScript runtime for SurveyJS enginefile_picker- File selectionimage_picker- Image selection and camera capturesignature- Signature drawingmime- MIME type detection
Limitations
- Some advanced SurveyJS features inside complex question types may be partially implemented
- Some advanced SurveyJS features may not be fully supported
- JavaScript execution may have performance implications on large surveys
Contributing
Contributions are welcome! Please feel free to submit issues or pull requests.
License
This package is licensed under the MIT License.
Additional Resources
Libraries
- surveyjs_flutter
- Flutter SurveyJS - A Flutter package for rendering SurveyJS forms