A set of widgets specifically designed to work with elite_orm.
In your flutter project add the dependency:
dependencies:
...
elite_orm_editor:
Import elite_orm_editor.dart
import 'package:elite_orm_editor/elite_orm_editor.dart';
Your widget class will extend EliteORMEditor
.
class TeamEdit extends EliteORMEditor {
final Team? team;
const TeamEdit({super.key, this.team});
@override
State<TeamEdit> createState() => _TeamEditState();
}
This class will do the bulk of your editor widget.
class _TeamEditState extends EliteORMEditorState<TeamEdit> {
Team storage = Team();
final List<ControlGroup> _groups = [];
@override
void initState() {
super.initState();
createDefaultControls(storage);
// Fill in the widgets with data.
if (widget.team != null) {
initializeControlValues(widget.widget!);
}
}
void _saveTeam() async {
try {
final SaveStatus status = await save(teamBloc, widget.team, storage);
String message;
switch (status) {
case SaveStatus.created:
message = "Team Saved";
modified = false;
break;
case SaveStatus.updated:
message = "Team Updated";
modified = false;
break;
case SaveStatus.invalid:
message = "Invalid Team";
break;
}
// Because we're using the build context after an await, we need to
// ensure that this widget is still mounted before using it.
if (!modified && mounted) {
Navigator.pop(context);
}
// Same here.
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message)),
);
}
} catch (err) {
ErrorDialog.show(context, err.toString());
}
}
@override
List<Widget> buildGroups() {
// Initialize your control groups here instead of in initState() in the
// event that you use AppLocalizations.of(context) to support
// internationalization.
if (_groups.isEmpty) {
_groups.add(ControlGroup(title: "Team Name", items: [controls[0]]));
_groups.add(ControlGroup(title: "Schedule Website", items: [controls[1]]));
_groups.add(ControlGroup(title: "Teammates", items: [controls[2]]));
}
return translateGroups(_groups);
}
@override
String get title => "Edit Team";
}
Click here to see a more detailed example.
Extend the EliteORMEditor
class instead of the StatefulWidget
class.
Extend the EliteORMEditorState
class instead of the State
class. It will provide a framework for creating an editor screen for a single type of database Entity.
String get title
This abstract attribute provides the title of the editing screen.
List<Widget> buildGroups()
This abstract method is how you provide information to the library to ensure that the editing controls get grouped together properly.
If you have a list of groups, your implementation can typically return the result of translateGroups
.
EliteORMEditorStyle get style
The default implementation provides an EliteORMEditorStyle
object containing methods that help determine the appearance of the editor screen.
void createDefaultControls(Entity entity)
This method creates a set of default controls to be used to modify the individual data members within the entity.
void initializeControlValues(Entity initial)
Sets each control in the controls
array to an initial value that comes from the Entity passed in.
void addListeners(Function() listener)
Add a listener to every single control in the controls
array.
DBMemberControl? getControl(String key)
Get a control from the controls
array based on the key of the database member of the Entity.
void renderTextAdder({required String title, required bool Function(String) adder, required TextField field, String? addText, String? cancelText})
This method creates a modal bottom sheet with a single text field entry. It is used to add text items to a list.
List<Widget> translateGroup(ControlGroup group)
Translate a single ControlGroup into a list of widgets to be used to make up a portion of the editing screen.
List<Widget> translateGroups(List<ControlGroup> groups)
Translate a list of groups into a Widget list. Use this method in your implementation of buildGroups()
.
Future<void> renderListChooser({ required DBMemberControl control, required String title, required List items, Function? toString, Function? toSubtitle, }) async
Future<bool> onWillPop() async
Override this in your child class. It will allow you to prompt the user to save their changes if they haven't already done so.
Widget renderContent()
The default implementation creates a ListView
with the buildGroups()
result.
bool isValid(Entity entity)
The default implementation looks at all parts of the primary key that are of type String and checks to see if any are empty. If one or more is empty, it returns false. Otherwise, it returns true.
bool hasPrimaryChanged(Entity? original, Entity entity)
Does a comparison of each part of the primary key. If any have changed, it returns true.
Future<SaveStatus> save(Bloc bloc, Entity? original, Entity entity) async
This method will either create or update the database entry based on entity
, if it is deemed valid, and return status.
Row? renderBottomIcons()
Override this in your child class and return a Row containing a list of widgets to show a bottom navigation bar.
The default implementation returns null.
Widget? renderBottomNavigationBar()
This method creates a BottomAppBar
if renderBottomIcons()
does not return null.
PreferredSizeWidget renderAppBar()
The default implementation returns an AppBar widget with a text title.
Widget build(BuildContext context)
The default implementation uses a simple Scaffold wrapped by a WillPopScope. Override this in your child class if this implementation does not suit your needs.
Extend the EliteORMList
class instead of the StatefulWidget
class.
Extend the EliteORMListState
class instead of the State
class. It will provide a framework for creating a list of Card widgets that represent each Entity in the database.
Bloc get bloc
Provide the bloc for your database entities.
String get title
This abstract attribute provides the title of the list screen.
Widget getEditor([Entity? entity])
Return a widget that will create an "editing" screen when the individual card is tapped.
String getEntityTitle(Entity entity)
Return a string that will be used as the Card title.
String get loading
Returns a string to indicate to the user that the data is loading.
String? getEntitySubtitle(Entity entity)
Override this method to return a Card subtitle, if desired.
EliteORMEditorStyle get style
The default implementation provides an EliteORMEditorStyle
object containing methods that help determine the appearance of the list screen.
int sorter(Entity a, Entity b)
Implements a sorter for use with List.sort() for two database entities. It uses the getEntityTitle
to extract the title from both entities and sorts based on those.
Widget renderEntity(Entity entity)
Renders a widget to display information about the database entity.
Widget renderEntities(AsyncSnapshot<List<Entity>> snapshot)
Renders the list of entities or a "loading" circular progress indicator.
Row? renderBottomIcons()
Override this in your child class and return a Row containing a list of widgets to show a bottom navigation bar.
The default implementation returns a Row with a single "plus" icon to create new database Entity objects.
Widget? renderBottomNavigationBar()
This method creates a BottomAppBar
if renderBottomIcons()
does not return null.
PreferredSizeWidget renderAppBar()
The default implementation returns an AppBar widget with a text title.
Widget build(BuildContext context)
The default implementation uses a simple Scaffold. Override this in your child class if this implementation does not suit your needs.