Skip to content

Commit 640bb38

Browse files
committed
ThemedTable2 issues on search field fixed
1 parent 84eb9bc commit 640bb38

5 files changed

Lines changed: 59 additions & 41 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
# Changelog
22

3+
## 7.4.6
4+
5+
- Fixed an issue with the `ThemedTable2` where the filtering was not working correctly after the last changes.
6+
- Changed behavior on `dispose()` on `ThemedTextInput` to only dispose the internal controller and focus node when they are not provided externally.
7+
38
## 7.4.5
9+
410
- Added `initialPosition` and `onTabIndex` in `ThemedTabView`
11+
512
## 7.4.4
13+
614
- Solved extremely weird bug using the `ThemedTable2`, now creates a copy of the items list to prevent issues when filtering and sorting the data. (Discovered by @ManuelRomeroA)
715

816
## 7.4.3

example/pubspec.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ packages:
374374
path: ".."
375375
relative: true
376376
source: path
377-
version: "7.4.4"
377+
version: "7.4.6"
378378
leak_tracker:
379379
dependency: transitive
380380
description:

lib/src/inputs/src/general/text_input.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,8 @@ class _ThemedTextInputState extends State<ThemedTextInput> with TickerProviderSt
201201
@override
202202
void dispose() {
203203
_entry?.remove();
204-
_controller.dispose();
205-
_focusNode.dispose();
204+
if (widget.controller == null) _controller.dispose();
205+
if (widget.focusNode == null) _focusNode.dispose();
206206
_animationController.dispose();
207207
super.dispose();
208208
}

lib/src/table2/src/table.dart

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,8 @@ class _ThemedTable2State<T> extends State<ThemedTable2<T>> {
153153
/// [_sortIconSize] is the size of the sort icon
154154
double get _sortIconSize => 16;
155155

156-
/// [_search] holds the current search query used to filter items.
157-
String _search = '';
156+
/// [_searchController] holds the current search query used to filter items.
157+
final TextEditingController _searchController = TextEditingController();
158158

159159
/// [_filteredData] holds the filtered and sorted data currently displayed in the table.
160160
final ValueNotifier<List<T>> _filteredData = ValueNotifier<List<T>>([]);
@@ -225,6 +225,7 @@ class _ThemedTable2State<T> extends State<ThemedTable2<T>> {
225225
void dispose() {
226226
_isLoading.dispose();
227227
_filteredData.dispose();
228+
_searchController.dispose();
228229

229230
_debounce?.cancel();
230231

@@ -312,10 +313,13 @@ class _ThemedTable2State<T> extends State<ThemedTable2<T>> {
312313
if (widget.canSearch) ...[
313314
SizedBox(
314315
width: double.infinity,
315-
child: ThemedSearchInput(
316-
value: _search,
317-
onSearch: _onSearchChanged,
318-
asField: true,
316+
child: ThemedTextInput(
317+
labelText: LayrzAppLocalizations.maybeOf(context)?.t('actions.search') ?? 'Search...',
318+
prefixIcon: LayrzIcons.solarOutlineMagnifier,
319+
padding: EdgeInsets.zero,
320+
controller: _searchController,
321+
onChanged: _onSearchChanged,
322+
dense: true,
319323
),
320324
),
321325
const SizedBox(height: 8),
@@ -728,44 +732,50 @@ class _ThemedTable2State<T> extends State<ThemedTable2<T>> {
728732
}
729733

730734
void _filterAndSort(String source) async {
731-
List<T> items = List<T>.from(widget.items, growable: true);
732-
if (widget.items.isEmpty) return;
733-
734-
debugPrint("layrz_theme/ThemedTable2: Precomputing data from $source...");
735-
_itemsStrings = {};
736-
for (final item in widget.items) {
737-
int rowHashCode = item.hashCode;
738-
_itemsStrings[rowHashCode] = {};
739-
740-
for (final col in widget.columns) {
741-
final colHashCode = col.hashCode;
742-
_itemsStrings[rowHashCode]![colHashCode] = col.valueBuilder(item);
735+
try {
736+
List<T> items = List<T>.from(widget.items, growable: true);
737+
if (widget.items.isEmpty) return;
738+
739+
debugPrint("layrz_theme/ThemedTable2: Precomputing data from $source...");
740+
_itemsStrings = {};
741+
for (final item in widget.items) {
742+
int rowHashCode = item.hashCode;
743+
_itemsStrings[rowHashCode] = {};
744+
745+
for (final col in widget.columns) {
746+
final colHashCode = col.hashCode;
747+
_itemsStrings[rowHashCode]![colHashCode] = col.valueBuilder(item);
748+
}
743749
}
744-
}
745750

746-
if (_search.isNotEmpty) {
747-
debugPrint("layrz_theme/ThemedTable2: Filtering data...");
748-
final searchLower = _search.toLowerCase();
749-
items = items.where((row) {
750-
final rowHashCode = row.hashCode;
751-
final cols = _itemsStrings[rowHashCode];
752-
if (cols == null) return false;
753-
for (final entry in cols.entries) {
754-
if (entry.value.toLowerCase().contains(searchLower)) return true;
755-
}
756-
return false;
757-
}).toList();
758-
}
751+
debugPrint("layrz_theme/ThemedTable2: Filtering data from $source - ${_searchController.text}...");
752+
if (_searchController.text.isNotEmpty) {
753+
debugPrint("layrz_theme/ThemedTable2: Filtering data...");
754+
final searchLower = _searchController.text.toLowerCase();
755+
items = items.where((row) {
756+
final rowHashCode = row.hashCode;
757+
final cols = _itemsStrings[rowHashCode];
758+
if (cols == null) return false;
759+
for (final entry in cols.entries) {
760+
if (entry.value.toLowerCase().contains(searchLower)) return true;
761+
}
762+
return false;
763+
}).toList();
764+
}
759765

760-
debugPrint("layrz_theme/ThemedTable2: Sorting data...");
761-
items.sort(colSelected.customSort ?? _defaultSort);
762-
_filteredData.value = items;
766+
debugPrint("layrz_theme/ThemedTable2: Sorting data...");
767+
items.sort(colSelected.customSort ?? _defaultSort);
768+
_filteredData.value = items;
769+
} finally {
770+
debugPrint("layrz_theme/ThemedTable2: Finished filtering and sorting from $source, removing debouncer...");
771+
_debounce?.cancel();
772+
_debounce = null;
773+
if (mounted) WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {}));
774+
}
763775
}
764776

765777
void _onSearchChanged(String value) {
766-
if (_debounce?.isActive ?? false) _debounce!.cancel();
767778
_debounce = Timer(const Duration(milliseconds: 300), () {
768-
_search = value;
769779
_filterAndSort('SEARCH');
770780
});
771781
WidgetsBinding.instance.addPostFrameCallback((_) {

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: layrz_theme
22
description: Layrz standard styling library for Flutter. Widget library following the Material Design 3 guidelines, with a focus on reliavility and functionality.
3-
version: "7.4.5"
3+
version: "7.4.6"
44
homepage: https://theme.layrz.com
55
repository: https://github.com/goldenm-software/layrz_theme
66

0 commit comments

Comments
 (0)