@@ -87,7 +87,7 @@ class TagInput extends BaseTextInput {
87
87
}
88
88
return null ;
89
89
}
90
-
90
+
91
91
@override
92
92
void setItemTemplate (Map ? maybeTemplate) {
93
93
_controller.itemTemplate = LabelValueItemTemplate .from (maybeTemplate);
@@ -103,15 +103,7 @@ abstract class BaseTextInput extends StatefulWidget
103
103
BaseTextInput ({Key ? key}) : super (key: key);
104
104
105
105
// 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 ();
115
107
final TagInputController _controller = TagInputController ();
116
108
117
109
@override
@@ -350,6 +342,7 @@ class TagInputState extends FormFieldWidgetState<BaseTextInput>
350
342
with TickerProviderStateMixin , TextInputFieldAction , TemplatedWidgetState {
351
343
final focusNode = FocusNode ();
352
344
List ? dataList;
345
+ String ? tagQuery;
353
346
354
347
// for this widget we will implement onChange if the text changes AND:
355
348
// 1. the field loses focus next (tabbing out, ...)
@@ -539,19 +532,11 @@ class TagInputState extends FormFieldWidgetState<BaseTextInput>
539
532
return formattedTag;
540
533
},
541
534
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
+ });
553
538
},
554
- // triggerCharacterAndStyles: widget.controller.triggers.map((key, value) => MapEntry(key, value ?? const TextStyle() )),
539
+ triggerCharacterAndStyles: widget.controller.triggers.map ((key, value) => MapEntry (key, value! )),
555
540
triggerStrategy: TriggerStrategy .eager,
556
541
overlayHeight: widget._controller.overlayHeight ?? 200.0 ,
557
542
overlay:
@@ -561,7 +546,7 @@ class TagInputState extends FormFieldWidgetState<BaseTextInput>
561
546
child: Container (
562
547
decoration: widget._controller.overlayStyle,
563
548
child: buildItems (widget.controller.tags,
564
- widget.controller.itemTemplate, dataList),
549
+ widget.controller.itemTemplate, dataList, tagQuery ),
565
550
),
566
551
)),
567
552
builder: (context, containerKey) {
@@ -672,13 +657,19 @@ class TagInputState extends FormFieldWidgetState<BaseTextInput>
672
657
}
673
658
674
659
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 (
682
673
leading: item.image != null
683
674
? CircleAvatar (
684
675
backgroundImage: NetworkImage (item.image! ),
@@ -689,62 +680,55 @@ class TagInputState extends FormFieldWidgetState<BaseTextInput>
689
680
style: widget._controller.tagSelectionStyle,
690
681
),
691
682
onTap: () {
692
- // Use insertMention instead of addTag to ensure styles are applied
693
683
widget._taggerController.addTag (
694
684
id: item.id.toString (),
695
685
name: item.key,
696
686
);
687
+ focusNode.requestFocus ();
697
688
},
698
- ));
699
- }
700
- }
701
- // then add the templated list
689
+ )),
690
+ );
691
+ }
692
+
693
+ // Filter the templated list
702
694
if (itemTemplate != null && dataList != null ) {
703
695
ScopeManager ? parentScope = DataScopeWidget .getScope (context);
704
696
if (parentScope != null ) {
705
- results ?? = [];
706
697
for (var itemData in dataList) {
707
698
ScopeManager templatedScope = parentScope.createChildScope ();
708
- templatedScope.dataContext
709
- .addDataContextById (itemTemplate.name, itemData);
699
+ templatedScope.dataContext.addDataContextById (itemTemplate.name, itemData);
710
700
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)) {
711
705
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
+
717
710
results.add (ListTile (
718
711
title: labelWidget,
719
712
hoverColor: Colors .pink,
720
- // value: templatedScope.dataContext.eval(itemTemplate.value),
721
713
onTap: () {
722
- // Use insertMention instead of addTag to ensure styles are applied
723
714
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
+ );
727
718
focusNode.requestFocus ();
728
-
729
- // WidgetsBinding.instance.addPostFrameCallback((_) {
730
- // widget._taggerController.closeOverlay();
731
- // });
732
719
},
733
720
));
734
721
}
735
722
}
736
723
}
737
-
738
- ListView finalList = ListView .builder (
739
- itemCount: results! .length,
740
- itemBuilder: (context, index) {
741
- return results! [index];
742
- },
743
- );
744
-
745
- return finalList;
746
724
}
747
725
726
+ return ListView .builder (
727
+ itemCount: results.length,
728
+ itemBuilder: (context, index) => results[index],
729
+ );
730
+ }
731
+
748
732
Debouncer ? _delayedKeyPressDebouncer;
749
733
Duration ? _lastDelayedKeyPressDuration;
750
734
0 commit comments