mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-08-24 14:42:28 +00:00
Refactor SpaceDetailsForm to use StatefulWidget for form validation and improve user experience with dynamic save button state, and added space name validation to not be longer than 50 characters.
This commit is contained in:
@ -10,7 +10,7 @@ import 'package:syncrow_web/pages/space_management_v2/modules/update_space/prese
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
|
||||
class SpaceDetailsForm extends StatelessWidget {
|
||||
class SpaceDetailsForm extends StatefulWidget {
|
||||
const SpaceDetailsForm({
|
||||
required this.title,
|
||||
required this.space,
|
||||
@ -22,24 +22,52 @@ class SpaceDetailsForm extends StatelessWidget {
|
||||
final SpaceDetailsModel space;
|
||||
final void Function(SpaceDetailsModel space) onSave;
|
||||
|
||||
@override
|
||||
State<SpaceDetailsForm> createState() => _SpaceDetailsFormState();
|
||||
}
|
||||
|
||||
class _SpaceDetailsFormState extends State<SpaceDetailsForm> {
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
bool _isFormValid = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
final initialName = widget.space.spaceName;
|
||||
_isFormValid = initialName.isNotEmpty &&
|
||||
initialName.length <= 50 &&
|
||||
!widget.space.subspaces.any((subspace) => subspace.name == initialName);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => SpaceDetailsModelBloc(initialState: space),
|
||||
create: (context) => SpaceDetailsModelBloc(initialState: widget.space),
|
||||
child: BlocBuilder<SpaceDetailsModelBloc, SpaceDetailsModel>(
|
||||
buildWhen: (previous, current) => previous != current,
|
||||
builder: (context, space) {
|
||||
return AlertDialog(
|
||||
title: DefaultTextStyle(
|
||||
style: context.textTheme.titleLarge!.copyWith(
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: ColorsManager.blackColor,
|
||||
),
|
||||
child: title,
|
||||
buildWhen: (previous, current) => previous != current,
|
||||
builder: (context, space) {
|
||||
return AlertDialog(
|
||||
title: DefaultTextStyle(
|
||||
style: context.textTheme.titleLarge!.copyWith(
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: ColorsManager.blackColor,
|
||||
),
|
||||
backgroundColor: ColorsManager.white,
|
||||
content: SizedBox(
|
||||
child: widget.title,
|
||||
),
|
||||
backgroundColor: ColorsManager.white,
|
||||
content: Form(
|
||||
key: _formKey,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
onChanged: () {
|
||||
final isValid = _formKey.currentState?.validate() ?? false;
|
||||
if (_isFormValid != isValid) {
|
||||
setState(() {
|
||||
_isFormValid = isValid;
|
||||
});
|
||||
}
|
||||
},
|
||||
child: SizedBox(
|
||||
height: context.screenHeight * 0.3,
|
||||
width: context.screenWidth * 0.4,
|
||||
child: Row(
|
||||
@ -70,14 +98,16 @@ class SpaceDetailsForm extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
SpaceDetailsActionButtons(
|
||||
onSave: () => onSave(space),
|
||||
onCancel: Navigator.of(context).pop,
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
actions: [
|
||||
SpaceDetailsActionButtons(
|
||||
onSave: _isFormValid ? () => widget.onSave(space) : null,
|
||||
onCancel: Navigator.of(context).pop,
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -33,12 +33,13 @@ class _SpaceNameTextFieldState extends State<SpaceNameTextField> {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
String? _validateName(String? value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return '*Space name should not be empty.';
|
||||
}
|
||||
if (value.length > 50) {
|
||||
return '*Space name cannot be longer than 50 characters.';
|
||||
}
|
||||
if (widget.isNameFieldExist(value)) {
|
||||
return '*Name already exists';
|
||||
}
|
||||
@ -47,30 +48,26 @@ class _SpaceNameTextFieldState extends State<SpaceNameTextField> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Form(
|
||||
key: _formKey,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
child: TextFormField(
|
||||
controller: _controller,
|
||||
onChanged: (value) => context.read<SpaceDetailsModelBloc>().add(
|
||||
UpdateSpaceDetailsName(value),
|
||||
),
|
||||
validator: _validateName,
|
||||
style: context.textTheme.bodyMedium,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Please enter the name',
|
||||
hintStyle: context.textTheme.bodyMedium!.copyWith(
|
||||
color: ColorsManager.lightGrayColor,
|
||||
),
|
||||
filled: true,
|
||||
fillColor: ColorsManager.boxColor,
|
||||
enabledBorder: _buildBorder(context, ColorsManager.vividBlue),
|
||||
focusedBorder: _buildBorder(context, ColorsManager.primaryColor),
|
||||
errorBorder: _buildBorder(context, context.theme.colorScheme.error),
|
||||
focusedErrorBorder: _buildBorder(context, context.theme.colorScheme.error),
|
||||
errorStyle: context.textTheme.bodySmall?.copyWith(
|
||||
color: context.theme.colorScheme.error,
|
||||
return TextFormField(
|
||||
controller: _controller,
|
||||
onChanged: (value) => context.read<SpaceDetailsModelBloc>().add(
|
||||
UpdateSpaceDetailsName(value),
|
||||
),
|
||||
validator: _validateName,
|
||||
style: context.textTheme.bodyMedium,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Please enter the name',
|
||||
hintStyle: context.textTheme.bodyMedium!.copyWith(
|
||||
color: ColorsManager.lightGrayColor,
|
||||
),
|
||||
filled: true,
|
||||
fillColor: ColorsManager.boxColor,
|
||||
enabledBorder: _buildBorder(context, ColorsManager.vividBlue),
|
||||
focusedBorder: _buildBorder(context, ColorsManager.primaryColor),
|
||||
errorBorder: _buildBorder(context, context.theme.colorScheme.error),
|
||||
focusedErrorBorder: _buildBorder(context, context.theme.colorScheme.error),
|
||||
errorStyle: context.textTheme.bodySmall?.copyWith(
|
||||
color: context.theme.colorScheme.error,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
Reference in New Issue
Block a user