SchemaForm class
StatelessWidget
for building forms dynamically from JSON schema interpretation.
It takes two JSONs to build the form. A third JSON can be used as a data
source, which in turn needs to be in accordance with the data schema.
Examples
Minimal
JsonSchemaBloc jsonSchemaBloc = JsonSchemaBloc(formContext: context);
SchemaForm schemaForm = SchemaForm(jsonSchemaBloc: jsonSchemaBloc);
File layoutSchemaFile = new File("layoutSchema.json");
File dataSchemaFile = new File("dataSchema.json");
File dataValueFile = new File("dataValue.json");
String layoutSchemaContent = layoutSchemaFile.readAsStringSync();
String dataSchemaContent = dataSchemaFile.readAsStringSync();
String dataValueContent = dataValueFile.readAsStringSync();
Map<String, dynamic> layoutSchemaMap = json.decode(layoutSchemaContent);
Map<String, dynamic> dataSchemaMap = json.decode(dataSchemaContent);
Map<String, dynamic> dataValueMap = json.decode(dataValueContent);
JsonSchema dataJsonSchema = JsonSchema.createSchema(dataSchemaMap);
jsonSchemaBloc.add(LoadLayoutSchemaEvent(layout: layoutSchemaMap));
jsonSchemaBloc.add(LoadDataSchemaEvent(dataSchema: dataJsonSchema));
jsonSchemaBloc.add(LoadDataEvent(data: dataValueMap));
Complete
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:json_schema/json_schema.dart';
import 'package:schema_form/bloc/json_schema_bl.dart';
import 'package:schema_form/schema_form.dart';
void main() => runApp(MyApp());
enum FileLocate { asset, storage, url }
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final appTitle = 'Flutter JsonSchema Demo';
JsonSchemaBloc jsonSchemaBloc = JsonSchemaBloc(formContext: context);
loadSchemasFrom(
FileLocate.asset,
context,
jsonSchemaBloc,
);
return MaterialApp(
locale: Locale("pt", "BR"),
title: appTitle,
home: Scaffold(
appBar: AppBar(
title: Text(appTitle),
),
drawer: Drawer(
child: ListView(
// Important: Remove any padding from the ListView.
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text(appTitle),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('Load from Asset'),
onTap: () => loadSchemasFrom(
FileLocate.asset,
context,
jsonSchemaBloc,
),
),
ListTile(
title: Text('Load from Storage'),
onTap: () => loadSchemasFrom(
FileLocate.storage,
context,
jsonSchemaBloc,
),
),
ListTile(
title: Text('Load from URL'),
onTap: () => loadSchemasFrom(
FileLocate.url,
context,
jsonSchemaBloc,
),
),
],
),
),
body: SchemaForm(jsonSchemaBloc: jsonSchemaBloc),
),
);
}
void loadSchemasFrom(FileLocate fileLocate, BuildContext context,
JsonSchemaBloc jsonSchemaBloc) {
loadJsonFrom(fileLocate, context, "testLayoutSchema.json").then(
(Map<String, dynamic> layoutSchema) =>
jsonSchemaBloc.add(LoadLayoutSchemaEvent(layout: layoutSchema)));
loadJsonFrom(fileLocate, context, "testDataSchema.json").then(
(Map<String, dynamic> jsonMap) =>
jsonSchemaBloc.add(
LoadDataSchemaEvent(dataSchema: JsonSchema.createSchema(jsonMap))));
loadJsonFrom(fileLocate, context, "testDataValue.json").then(
(Map<String, dynamic> dataValue) =>
jsonSchemaBloc.add(LoadDataEvent(data: dataValue)));
}
Future<Map<String, dynamic>> loadJsonFrom(FileLocate fileLocate,
BuildContext context, String fileName) async {
switch (fileLocate) {
case FileLocate.asset:
return await loadJsonFromAsset(context, 'assets/$fileName');
case FileLocate.storage:
return await loadJsonFromStorage(
context, '/storage/emulated/0/Json/files/$fileName');
case FileLocate.url:
return await loadJsonFromUrl(context,
'https://legytma-platform-open-api-back.herokuapp.com/schema/mongo/$fileName');
default:
throw "Não implementado!";
}
}
Future<Map<String, dynamic>> loadJsonFromAsset(BuildContext context,
String filePath) async {
print("filePath: $filePath");
String content = await DefaultAssetBundle.of(context).loadString(filePath);
print("content: $content");
Map<String, dynamic> jsonMap = json.decode(content);
return jsonMap;
}
Future<Map<String, dynamic>> loadJsonFromStorage(BuildContext context,
String filePath) async {
print("filePath: $filePath");
File file = new File(filePath);
if (file.existsSync()) {
String content = file.readAsStringSync();
print("content: $content");
Map<String, dynamic> jsonMap = json.decode(content);
return jsonMap;
}
throw "File not found!";
}
Future<Map<String, dynamic>> loadJsonFromUrl(BuildContext context,
String filePath) async {
print("filePath: $filePath");
String username = '';
String password = '';
String basicAuth =
'Basic ' + base64Encode(utf8.encode('$username:$password'));
print('basicAuth: $basicAuth');
http.Response response = await http.get(Uri.encodeFull(filePath), headers: {
"Accept": "application/json",
"Authorization": basicAuth,
});
if (response.statusCode == 200) {
Map<String, dynamic> jsonMap = json.decode(response.body);
return jsonMap;
}
throw "${response.statusCode} - ${response.reasonPhrase}: ${response.body}";
}
}
Expected Outcome
Constructors
- SchemaForm({Key key, JsonSchemaBloc jsonSchemaBloc })
- Create a SchemaForm using JsonSchemaBloc. [...]
Properties
- jsonSchemaBloc → JsonSchemaBloc
-
SchemaForm Business Logic Object. [...]
final
- hashCode → int
-
The hash code for this object. [...]
read-only, inherited
- key → Key
-
Controls how one widget replaces another widget in the tree. [...]
final, inherited
- runtimeType → Type
-
A representation of the runtime type of the object.
read-only, inherited
Methods
-
build(
BuildContext context) → Widget - Describes the part of the user interface represented by this widget. [...]
-
createElement(
) → StatelessElement -
Creates a
StatelessElement
to manage this widget's location in the tree. [...]inherited -
debugDescribeChildren(
) → List< DiagnosticsNode> -
Returns a list of
DiagnosticsNode
objects describing this node's children. [...]@protected, inherited -
debugFillProperties(
DiagnosticPropertiesBuilder properties) → void -
Add additional properties associated with the node. [...]
inherited
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a non-existent method or property is accessed. [...]
inherited
-
toDiagnosticsNode(
{String name, DiagnosticsTreeStyle style }) → DiagnosticsNode -
Returns a debug representation of the object that is used by debugging
tools and by DiagnosticsNode.toStringDeep. [...]
inherited
-
toString(
{DiagnosticLevel minLevel: DiagnosticLevel.debug }) → String -
Returns a string representation of this object.
inherited
-
toStringDeep(
{String prefixLineOne: '', String prefixOtherLines, DiagnosticLevel minLevel: DiagnosticLevel.debug }) → String -
Returns a string representation of this node and its descendants. [...]
inherited
-
toStringShallow(
{String joiner: ', ', DiagnosticLevel minLevel: DiagnosticLevel.debug }) → String -
Returns a one-line detailed description of the object. [...]
inherited
-
toStringShort(
) → String -
A short, textual description of this widget.
inherited
Operators
-
operator ==(
dynamic other) → bool -
The equality operator. [...]
inherited