|
|
|
|
@ -144,29 +144,66 @@ class _SingleItemDropDownMenuState<T extends Base, X extends LoadingListNotifier
|
|
|
|
|
void didUpdateWidget(covariant SingleItemDropDownMenu<T, X> oldWidget) {
|
|
|
|
|
super.didUpdateWidget(oldWidget);
|
|
|
|
|
|
|
|
|
|
if (oldWidget.initialValue == widget.initialValue) return;
|
|
|
|
|
// Get old and new items lists
|
|
|
|
|
final List<T>? oldItems = (X == NullableLoadingProvider ? oldWidget.staticData : provider?.items)?.cast<T>();
|
|
|
|
|
final List<T>? newItems = (X == NullableLoadingProvider ? widget.staticData : provider?.items)?.cast<T>();
|
|
|
|
|
|
|
|
|
|
// Check if items list has changed (provider loaded new data)
|
|
|
|
|
final bool itemsChanged = (oldItems?.length ?? 0) != (newItems?.length ?? 0);
|
|
|
|
|
|
|
|
|
|
// Skip update only if initialValue hasn't changed AND items haven't changed AND we already have a selected item
|
|
|
|
|
if (oldWidget.initialValue == widget.initialValue && !itemsChanged && _selectedItem != null) return;
|
|
|
|
|
|
|
|
|
|
if (widget.initialValue == null) {
|
|
|
|
|
_selectedItem = null;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
final List<T>? items = (X == NullableLoadingProvider ? widget.staticData : provider?.items)?.cast<T>();
|
|
|
|
|
|
|
|
|
|
T? matchedItem;
|
|
|
|
|
|
|
|
|
|
if (items != null && items.isNotEmpty) {
|
|
|
|
|
final Iterable<T> matches = items.where((e) => _isSameItem(e, widget.initialValue!));
|
|
|
|
|
if (newItems != null && newItems.isNotEmpty) {
|
|
|
|
|
final Iterable<T> matches = newItems.where((e) => _isSameItem(e, widget.initialValue!));
|
|
|
|
|
|
|
|
|
|
if (matches.isNotEmpty) matchedItem = matches.first;
|
|
|
|
|
}
|
|
|
|
|
_selectedItem = matchedItem;
|
|
|
|
|
if (widget.onSelect != null && !_isSameItem(widget.initialValue!, _selectedItem ?? widget.initialValue!)) {
|
|
|
|
|
|
|
|
|
|
// Only update if we found a match or if _selectedItem was previously null
|
|
|
|
|
if (matchedItem != null || _selectedItem == null) {
|
|
|
|
|
_selectedItem = matchedItem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Only call onSelect if the matched item is different from what we had before
|
|
|
|
|
if (widget.onSelect != null && matchedItem != null && !_isSameItem(widget.initialValue!, _selectedItem ?? widget.initialValue!)) {
|
|
|
|
|
widget.onSelect!(_selectedItem);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
// If using a provider, wrap with Consumer to react to changes
|
|
|
|
|
if (X != NullableLoadingProvider && provider != null) {
|
|
|
|
|
return Consumer<X>(
|
|
|
|
|
builder: (context, providerValue, child) {
|
|
|
|
|
// When provider items change, try to match the initialValue
|
|
|
|
|
final List<T>? items = providerValue.items?.cast<T>();
|
|
|
|
|
if (widget.initialValue != null && items != null && items.isNotEmpty && _selectedItem == null) {
|
|
|
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
|
|
|
final Iterable<T> matches = items.where((e) => _isSameItem(e, widget.initialValue!));
|
|
|
|
|
if (matches.isNotEmpty) {
|
|
|
|
|
setState(() {
|
|
|
|
|
_selectedItem = matches.first;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return _buildFormField(context);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return _buildFormField(context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget _buildFormField(BuildContext context) {
|
|
|
|
|
final isEmpty = (X == NullableLoadingProvider ? widget.staticData : provider?.items)?.isEmpty ?? true;
|
|
|
|
|
return FormField<T>(
|
|
|
|
|
validator: widget.validator,
|
|
|
|
|
|