created clearing dropdown menus
This commit is contained in:
81
lib/widgets/clearing_dropdown_menu.dart
Normal file
81
lib/widgets/clearing_dropdown_menu.dart
Normal file
@@ -0,0 +1,81 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ClearingDropdownMenu<T> extends StatefulWidget {
|
||||
final List<DropdownMenuEntry<T>> entries;
|
||||
final T? initialValue;
|
||||
final void Function(T? item)? onSelected;
|
||||
final String? label;
|
||||
|
||||
const ClearingDropdownMenu({
|
||||
super.key,
|
||||
required this.entries,
|
||||
this.initialValue,
|
||||
this.onSelected,
|
||||
this.label,
|
||||
});
|
||||
|
||||
@override
|
||||
State<ClearingDropdownMenu<T>> createState() =>
|
||||
_ClearingDropdownMenuState<T>();
|
||||
}
|
||||
|
||||
class _ClearingDropdownMenuState<T> extends State<ClearingDropdownMenu<T>> {
|
||||
late final TextEditingController _controller;
|
||||
final FocusNode _focusNode = FocusNode();
|
||||
T? _selectedValue;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_selectedValue = widget.initialValue;
|
||||
_controller = TextEditingController(
|
||||
text: _selectedValue != null
|
||||
? widget.entries
|
||||
.firstWhere((entry) => entry.value == _selectedValue)
|
||||
.label
|
||||
: '');
|
||||
|
||||
_focusNode.addListener(_onFocusChange);
|
||||
}
|
||||
|
||||
void _onFocusChange() {
|
||||
if (!_focusNode.hasFocus) {
|
||||
// Check if the current text matches any entry
|
||||
final validEntry = widget.entries.any((entry) =>
|
||||
entry.label.toLowerCase() == _controller.text.toLowerCase());
|
||||
|
||||
if (!validEntry) {
|
||||
// Clear the text and selection
|
||||
_controller.clear();
|
||||
setState(() {
|
||||
_selectedValue = null;
|
||||
});
|
||||
widget.onSelected?.call(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DropdownMenu<T>(
|
||||
controller: _controller,
|
||||
focusNode: _focusNode,
|
||||
initialSelection: widget.initialValue,
|
||||
onSelected: (T? value) {
|
||||
setState(() {
|
||||
_selectedValue = value;
|
||||
});
|
||||
widget.onSelected?.call(value);
|
||||
},
|
||||
dropdownMenuEntries: widget.entries,
|
||||
label: widget.label != null ? Text(widget.label!) : null,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
_focusNode.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user