-
-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
onSuggestionTap onsubmit are invoked both #165
Comments
Hi @hpp0hpp Thanks for filing the issue. Thanks |
I'm encountering the same issue. Here is the code (for flutter web) that can reproduce the issue. Steps to reproduce the issue:
Console log: Source code: import 'package:flutter/material.dart';
import 'package:searchfield/searchfield.dart';
import 'dart:developer' as d;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final focus = FocusNode();
final _controller = TextEditingController();
@override
void initState() {
super.initState();
suggestions = getSuggestions();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
var suggestions = <String>[];
@override
Widget build(BuildContext context) {
Widget searchChild(x) => Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0, horizontal: 12),
child: Text(x, style: Theme.of(context).textTheme.bodyMedium!),
);
SuggestionDecoration suggestionDecoration = SuggestionDecoration(
elevation: 16.0,
color: Colors.white54,
borderRadius: BorderRadius.circular(24),
);
return Scaffold(
appBar: AppBar(centerTitle: true, automaticallyImplyLeading: true, title: const Text('test')),
body: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: SizedBox(
height: double.infinity,
width: double.infinity,
child: Column(
children: [
SizedBox(
width: 400,
child: SearchField(
controller: _controller,
onSearchTextChanged: (query) {
List<String> filter;
query = query.trim();
if (query.isEmpty) {
filter = suggestions = getSuggestions();
} else {
filter = suggestions
.where((element) => element.toLowerCase().contains(query.toLowerCase()))
.toList();
}
return filter.map((e) => SearchFieldListItem<String>(e, child: searchChild(e))).toList();
},
onSubmit: (str) async {
d.log('[onSubmit] $str');
},
initialValue: null,
onTap: () async {
suggestions = getSuggestions();
setState(() {});
},
showEmpty: false,
emptyWidget: Container(
decoration: suggestionDecoration, height: 200, child: const Center(child: Text('Empty'))),
key: const Key('searchfield'),
searchStyle: Theme.of(context).textTheme.bodyMedium!,
dynamicHeight: true,
maxSuggestionBoxHeight: 300,
scrollbarDecoration: ScrollbarDecoration(minThumbLength: 30, thickness: 10),
onTapOutside: null,
suggestionDirection: SuggestionDirection.down,
suggestionStyle: Theme.of(context).textTheme.bodyMedium!,
searchInputDecoration: InputDecoration(
prefixIcon: const Icon(Icons.search),
fillColor: Colors.white38,
suffixIcon: IconButton(
onPressed: _controller.clear,
icon: const Icon(Icons.clear),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(24),
borderSide: const BorderSide(
width: 1,
color: Colors.grey,
style: BorderStyle.solid,
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(24),
borderSide: const BorderSide(
width: 1,
color: Colors.black,
style: BorderStyle.solid,
),
),
filled: true,
contentPadding: const EdgeInsets.symmetric(
horizontal: 20,
),
),
suggestionsDecoration: suggestionDecoration,
suggestions:
suggestions.map((e) => SearchFieldListItem<String>(e, child: searchChild(e))).toList(),
focusNode: focus,
suggestionState: Suggestion.expand,
onSuggestionTap: (SearchFieldListItem<String> x) {
focus.unfocus();
d.log('[onSuggestionTap] selected ${x.searchKey}');
},
)),
],
))));
}
List<String> getSuggestions() {
return ["OPtion1", "OPtion2", "OPtion3", "OPtion4", "OPtion5"];
}
} |
I tried further with the above code by deleting one character at a time and pressing the enter key. It seems "Option1" stays selected even when I deleted characters. See the log below: [log] [onSuggestionTap] selected OPtion1 [log] [onSuggestionTap] selected OPtion1 [log] [onSuggestionTap] selected OPtion1 [log] [onSuggestionTap] selected OPtion1 |
@twfungi Thanks for the code sample I will take a look at it, I have published a new release with few fixes v1.1.1. However this issue has not been taken care of yet, I am not really sure if this is an issue. I need to rethink about the expected behavior or perhaps a race condition I believe? Your suggestions are welcome! I would appreciate your feedback based on the latest version of the package. Thanks |
I'd suggest we fire either one, but not both. It depends on how you define these two events. Through my observation onSuggestionTap is always fired before onSubmit. What I did to workaround this "issue" is to delay 200ms in onSuggestionTap before we make sure onSubmit is not fired. Something like: onSubmit: (str) async {
d.log('[onSubmit] $str');
submitted = true;
// perform the onSubmit action
}, },
onSuggestionTap: (SearchFieldListItem<String> x) {
submitted = false;
focus.unfocus();
d.log('[onSuggestionTap] selected ${x.searchKey}');
Future.delayed(const Duration(milliseconds: 200), () async {
if (!submitted) {
// perform onSuggestionTap action
}
});
}, |
This is released in searchfield: ^1.1.2 |
verified the fix in 1.1.3, thanks! |
With 1.1.3, there's a side effect that, if the user inputs a string that partially matches something in the suggestion list and enters to fire submit, it always fires the matched item in the suggestion list instead of the string the user entered in the textedit. I think we should allow the user to choose which text to fire, either the string the user enters in the textedit or the partially matched text. What do you think, @maheshj01 ? |
That seems reasonable, We should make this configurable to allow Submitting custom input with an enum
Let me know if this seems like a valid approach. |
sgtm |
This is possible in latest release v1.1.4, we don't need a enum
|
Bumping down the priority and keeping this issue open for discussion and feedback. |
May I know how we can achieve this with v1.1.5? I just tried it and it still fires the matched suggestion instead of the entered text. |
@twfungi Looks like I misunderstood, It is only partially possible as of now OnSubmit fires the entered takes when the searchresult is empty, Note for self |
The problem here is, searchfield will just try to match one in the suggestion list and select it automatically and replace the user entered text with the auto-selected one when firing the onSubmit. This is not always helpful when the use case is to get the exact user input string and perform something else. One solution without adding the enum is, we still fire both onSuggestion and onSubmit. On the onSuggestion event, the searchkey is the selected one, while on the other, the onSubmit string is the user entered string. Leave the decision to the user which one to use. If this is not the one you prefer, I'm also fine with the enum proposal you mentioned earlier. |
Thanks for clarifying that @twfungi, I think would probably work on this over a weekend, if you are interested please feel free to make a PR. |
@maheshj01 sir when i close the keyboard all the suggestion showing from scratch not showing hat i have entered char in the textfield |
Describe the bug
when I input something in the searchfield, and I use key to select one suggestion, when I press Enter, onSuggestionTap and onsubmit are invoked the same time, while only onSuggestionTap is expect to be invoked
To Reproduce
Steps to reproduce the behavior:
when I input something in the searchfield, and I use key to select one suggestion, when I press Enter, onSuggestionTap and onsubmit are invoked the same time, while only onSuggestionTap is expect to be invoked
[.] By clicking this checkbox, I confirm I am using the latest version of the package found on pub.dev/searchfield
Expected behavior
A clear and concise description of what you expected to happen.
Actual behavior
What you actually saw instead of the expected behavior.
Screenshots
If applicable, add screenshots to help explain your problem.
Code sample
Show code sample
Paste minimal and complete code sample here to investigate the issue.
Additional context
Add any other context about the problem here.
The text was updated successfully, but these errors were encountered: