Skip to content

Commit 7875e4f

Browse files
committed
Added: Search Tag
1 parent 5ea49fd commit 7875e4f

File tree

1 file changed

+45
-61
lines changed

1 file changed

+45
-61
lines changed

modules/ensemble/lib/widget/input/taginput/taginput.dart

+45-61
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ class TagInput extends BaseTextInput {
8787
}
8888
return null;
8989
}
90-
90+
9191
@override
9292
void setItemTemplate(Map? maybeTemplate) {
9393
_controller.itemTemplate = LabelValueItemTemplate.from(maybeTemplate);
@@ -103,15 +103,7 @@ abstract class BaseTextInput extends StatefulWidget
103103
BaseTextInput({Key? key}) : super(key: key);
104104

105105
// textController manages 'value', while _controller manages the rest
106-
final FlutterTaggerController _taggerController = FlutterTaggerController(
107-
//Initial text value with tag is formatted internally
108-
//following the construction of FlutterTaggerController.
109-
//After this controller is constructed, if you
110-
//wish to update its text value with raw tag string,
111-
//call (_controller.formatTags) after that.
112-
text:
113-
"Hey @11a27531b866ce0016f9e582#brad#. It's time to #93f27531f294jp0016f9k013#Flutter#!",
114-
);
106+
final FlutterTaggerController _taggerController = FlutterTaggerController();
115107
final TagInputController _controller = TagInputController();
116108

117109
@override
@@ -350,6 +342,7 @@ class TagInputState extends FormFieldWidgetState<BaseTextInput>
350342
with TickerProviderStateMixin, TextInputFieldAction, TemplatedWidgetState {
351343
final focusNode = FocusNode();
352344
List? dataList;
345+
String? tagQuery;
353346

354347
// for this widget we will implement onChange if the text changes AND:
355348
// 1. the field loses focus next (tabbing out, ...)
@@ -539,19 +532,11 @@ class TagInputState extends FormFieldWidgetState<BaseTextInput>
539532
return formattedTag;
540533
},
541534
onSearch: (query, triggerCharacter) async {
542-
final results = widget.controller.tags!
543-
.where((item) =>
544-
item.label.toLowerCase().contains(query.toLowerCase()))
545-
.map(
546-
(item) => item.label) // Return full titles including spaces
547-
.toList();
548-
return Future.value(results);
549-
},
550-
triggerCharacterAndStyles: const {
551-
"@": TextStyle(color: Colors.pinkAccent),
552-
"#": TextStyle(color: Colors.blueAccent),
535+
setState(() {
536+
tagQuery = query;
537+
});
553538
},
554-
// triggerCharacterAndStyles: widget.controller.triggers.map((key, value) => MapEntry(key, value ?? const TextStyle())),
539+
triggerCharacterAndStyles: widget.controller.triggers.map((key, value) => MapEntry(key, value!)),
555540
triggerStrategy: TriggerStrategy.eager,
556541
overlayHeight: widget._controller.overlayHeight ?? 200.0,
557542
overlay:
@@ -561,7 +546,7 @@ class TagInputState extends FormFieldWidgetState<BaseTextInput>
561546
child: Container(
562547
decoration: widget._controller.overlayStyle,
563548
child: buildItems(widget.controller.tags,
564-
widget.controller.itemTemplate, dataList),
549+
widget.controller.itemTemplate, dataList, tagQuery),
565550
),
566551
)),
567552
builder: (context, containerKey) {
@@ -672,13 +657,19 @@ class TagInputState extends FormFieldWidgetState<BaseTextInput>
672657
}
673658

674659
ListView? buildItems(List<MentionItem>? items,
675-
LabelValueItemTemplate? itemTemplate, List? dataList) {
676-
List<ListTile>? results;
677-
// first add the static list
678-
if (items != null) {
679-
results = [];
680-
for (MentionItem item in items) {
681-
results.add(ListTile(
660+
LabelValueItemTemplate? itemTemplate, List? dataList, String? tagQuery) {
661+
List<ListTile> results = [];
662+
663+
// Normalize the query
664+
String query = tagQuery?.toLowerCase() ?? '';
665+
666+
// Filter the static list
667+
if (items != null) {
668+
results.addAll(
669+
items.where((item) {
670+
return item.label.toLowerCase().contains(query) ||
671+
item.key.toLowerCase().contains(query);
672+
}).map((item) => ListTile(
682673
leading: item.image != null
683674
? CircleAvatar(
684675
backgroundImage: NetworkImage(item.image!),
@@ -689,62 +680,55 @@ class TagInputState extends FormFieldWidgetState<BaseTextInput>
689680
style: widget._controller.tagSelectionStyle,
690681
),
691682
onTap: () {
692-
// Use insertMention instead of addTag to ensure styles are applied
693683
widget._taggerController.addTag(
694684
id: item.id.toString(),
695685
name: item.key,
696686
);
687+
focusNode.requestFocus();
697688
},
698-
));
699-
}
700-
}
701-
// then add the templated list
689+
)),
690+
);
691+
}
692+
693+
// Filter the templated list
702694
if (itemTemplate != null && dataList != null) {
703695
ScopeManager? parentScope = DataScopeWidget.getScope(context);
704696
if (parentScope != null) {
705-
results ??= [];
706697
for (var itemData in dataList) {
707698
ScopeManager templatedScope = parentScope.createChildScope();
708-
templatedScope.dataContext
709-
.addDataContextById(itemTemplate.name, itemData);
699+
templatedScope.dataContext.addDataContextById(itemTemplate.name, itemData);
710700

701+
String label = templatedScope.dataContext.eval(itemTemplate.label!);
702+
String value = templatedScope.dataContext.eval(itemTemplate.value);
703+
704+
if (label.toLowerCase().contains(query) || value.toLowerCase().contains(query)) {
711705
var labelWidget = DataScopeWidget(
712-
scopeManager: templatedScope,
713-
child: itemTemplate.label != null
714-
? Text(templatedScope.dataContext.eval(itemTemplate.label!))
715-
: templatedScope
716-
.buildWidgetFromDefinition(itemTemplate.labelWidget));
706+
scopeManager: templatedScope,
707+
child: Text(label),
708+
);
709+
717710
results.add(ListTile(
718711
title: labelWidget,
719712
hoverColor: Colors.pink,
720-
// value: templatedScope.dataContext.eval(itemTemplate.value),
721713
onTap: () {
722-
// Use insertMention instead of addTag to ensure styles are applied
723714
widget._taggerController.addTag(
724-
id: templatedScope.dataContext.eval(itemTemplate.value),
725-
name: templatedScope.dataContext.eval(itemTemplate.label));
726-
715+
id: value,
716+
name: label,
717+
);
727718
focusNode.requestFocus();
728-
729-
// WidgetsBinding.instance.addPostFrameCallback((_) {
730-
// widget._taggerController.closeOverlay();
731-
// });
732719
},
733720
));
734721
}
735722
}
736723
}
737-
738-
ListView finalList = ListView.builder(
739-
itemCount: results!.length,
740-
itemBuilder: (context, index) {
741-
return results![index];
742-
},
743-
);
744-
745-
return finalList;
746724
}
747725

726+
return ListView.builder(
727+
itemCount: results.length,
728+
itemBuilder: (context, index) => results[index],
729+
);
730+
}
731+
748732
Debouncer? _delayedKeyPressDebouncer;
749733
Duration? _lastDelayedKeyPressDuration;
750734

0 commit comments

Comments
 (0)