GithubHelp home page GithubHelp logo

abdulrahmanalhamali / flutter_typeahead Goto Github PK

View Code? Open in Web Editor NEW
794.0 794.0 332.0 30.97 MB

A TypeAhead widget for Flutter, where you can show suggestions to users as they type

License: BSD 2-Clause "Simplified" License

Dart 100.00%

flutter_typeahead's People

Contributors

abdulrahmanalhamali avatar alexanderfell avatar alphamikle avatar articmoon avatar awhitford avatar benjifarquhar avatar c1rdec avatar clragon avatar davidmartos96 avatar eivihnd avatar felipecastrosales avatar ivofernandes avatar kayblitz avatar krille-chan avatar lukaszdebowski avatar masewo avatar mideb avatar natesitton80 avatar nathaliars avatar nealsoni00 avatar pierre-monier avatar puduru avatar sahandevs avatar seriousmonk avatar sjmcdowall avatar sterlp avatar sumitsharansatsangi avatar vasilich6107 avatar wwwdata avatar xor22h avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flutter_typeahead's Issues

Do you think Flutter TypeAhead needs a backend-communication component?

The TypeAheadField and TypeAheadFormField widgets, in their current state, provide a suggestionsCallback function, which expects the user of the widget to go and fetch the suggestions from somewhere, and return them either synchronously or asynchronously.

But is there a better, perhaps more standard, approach that we can implement? Some typeahead widgets on other platforms provide an additional component to communicate with the backend, or whatever source the data is being fetched from. Is there any added value to that? What do you think?

Suggestion box height not adjusting after SlideTransition

When triggering a SlideTransition by selecting the TypeAhead, the height of the suggestion box is not recalculated.

Slide Transition moved the TypeAhead in the direction of the arrow:
screenshot_modified

I looked at the way TypeAhead handles this on scrolling, but there is no Animation equivalent of Scrollable.of() that I am aware of and I couldn't think of another solution without an ugly api change

flutter_typeahead not working in iOS flutter

I am getting compile error in flutter iOS application. In Android this package is working fine.
Below is error which I am getting when using this package.

compiler message: file:///Users/stral/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_typeahead-0.4.1/lib/flutter_typeahead.dart:1120:9: Error: Type 'TextCapitalization' not found.
compiler message: final TextCapitalization textCapitalization;
compiler message: ^
compiler message: file:///Users/stral/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_typeahead-0.4.1/lib/flutter_typeahead.dart:1179:7: Error: Type 'TextCapitalization' not found.
compiler message: TextCapitalization textCapitalization,
compiler message: ^
compiler message: file:///Users/stral/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_typeahead-0.4.1/lib/flutter_typeahead.dart:717:9: Error: No named parameter with the name 'onEditingComplete'.
compiler message: onEditingComplete: widget.textFieldConfiguration.onEditingComplete,
compiler message: ^^^^^^^^^^^^^^^^^
compiler message: file:///Users/stral/flutter/packages/flutter/lib/src/material/text_field.dart:99:9: Context: Found this candidate, but the arguments don't match.
compiler message: const TextField({
compiler message: ^
compiler message: file:///Users/stral/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_typeahead-0.4.1/lib/flutter_typeahead.dart:1120:9: Error: 'TextCapitalization' isn't a type.
compiler message: final TextCapitalization textCapitalization;
compiler message: ^^^^^^^^^^^^^^^^^^
compiler message: file:///Users/stral/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_typeahead-0.4.1/lib/flutter_typeahead.dart:1148:32: Error: Getter not found: 'TextCapitalization'.
compiler message: this.textCapitalization: TextCapitalization.none,
compiler message: ^^^^^^^^^^^^^^^^^^
compiler message: file:///Users/stral/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_typeahead-0.4.1/lib/flutter_typeahead.dart:1148:32: Error: The getter 'TextCapitalization' isn't defined for the class 'flutter_typeahead::TextFieldConfiguration<flutter_typeahead::TextFieldConfiguration::T>'.
compiler message: Try correcting the name to the name of an existing getter, or defining a getter or field named 'TextCapitalization'.
compiler message: this.textCapitalization: TextCapitalization.none,
compiler message: ^
compiler message: file:///Users/stral/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_typeahead-0.4.1/lib/flutter_typeahead.dart:1179:7: Error: 'TextCapitalization' isn't a type.
compiler message: TextCapitalization textCapitalization,
compiler message: ^^^^^^^^^^^^^^^^^^

Please provide any solution for this.

Serious issues with iOS keyboard ...

I am having some weird behavior with iOS and keyboard appearing / not appearing then getting totally futzed up ..

Initially we have no focus on the Widget.. this is good ..

However, when I click in the box .. to set focus .. the screen flashes and the suggestionsCallback fires .. but.. in the end .. the list goes away and we're back to the original screen .. but.. I think the Widget thinks the keyboard is still up and in focus?

One major difference I see is that on android when the keyboard goes up and down .. it's very clean ..


I/flutter (22356): FINE: 2019-03-11 15:52:10.446990: _CreateEventRecipientsScreenState - [suggestionsCallback()] - pattern of <>
I/flutter (22356): FINE: 2019-03-11 15:52:10.447610: _CreateEventRecipientsScreenState - [TypeAheadField() - suggestionsCallback] running search with pattern ''
I/flutter (22356): FINE: 2019-03-11 15:52:10.448855: _CreateEventRecipientsScreenState - [_getSuggestions] - query started - with pattern ''
I/flutter (22356): FINE: 2019-03-11 15:52:10.453695: _CreateEventRecipientsScreenState - [suggestionsCallback()] - returning Future of <Instance of 'Future<List<dynamic>>'>
I/flutter (22356): FINE: 2019-03-11 15:52:10.535237: MissionMode - [Router] - /home route invoked
I/flutter (22356): FINE: 2019-03-11 15:52:10.535702: _CreateEventFlowState - [cEventFlow - build()]
I/flutter (22356): FINE: 2019-03-11 15:52:10.791813: _CreateEventRecipientsScreenState - [_getSuggestions] - query completed!
I/flutter (22356): FINER: 2019-03-11 15:52:10.805159: _CreateEventRecipientsScreenState - [TypeAheadField() - itemBuilder] - Started with pattern <>

I/flutter (22356): FINE: 2019-03-11 15:52:46.121374: MissionMode - [Router] - /home route invoked
I/flutter (22356): FINE: 2019-03-11 15:52:46.122092: _CreateEventFlowState - [cEventFlow - build()]

However, on iOS everytime I show / hide the keyboard .. I see the build() method being called!!! This includes when focus is set by clicking originally.

flutter: FINE: 2019-03-11 15:41:42.227745: _CreateEventRecipientsScreenState - build()]
flutter: FINE: 2019-03-11 15:41:42.227979: _CreateEventRecipientsScreenState - [build() - FutureBuilder] - Fired! - Snapshot state is ConnectionState.done
flutter: FINE: 2019-03-11 15:41:42.228084: _CreateEventRecipientsScreenState - [_build()] - FutureBuilder - DATA RETURNED
flutter: FINE: 2019-03-11 15:41:42.228195: _CreateEventRecipientsScreenState - [_buildSearchField]
flutter: FINE: 2019-03-11 15:41:45.112227: _CreateEventRecipientsScreenState - build()]
flutter: FINE: 2019-03-11 15:41:45.112714: _CreateEventRecipientsScreenState - [build() - FutureBuilder] - Fired! - Snapshot state is ConnectionState.done
flutter: FINE: 2019-03-11 15:41:45.112875: _CreateEventRecipientsScreenState - [_build()] - FutureBuilder - DATA RETURNED
flutter: FINE: 2019-03-11 15:41:45.113023: _CreateEventRecipientsScreenState - [_buildSearchField]

-- Toggle keyboard --

flutter: FINE: 2019-03-11 15:41:59.104755: _CreateEventRecipientsScreenState - build()]
flutter: FINE: 2019-03-11 15:41:59.105041: _CreateEventRecipientsScreenState - [build() - FutureBuilder] - Fired! - Snapshot state is ConnectionState.done
flutter: FINE: 2019-03-11 15:41:59.105180: _CreateEventRecipientsScreenState - [_build()] - FutureBuilder - DATA RETURNED
flutter: FINE: 2019-03-11 15:41:59.105301: _CreateEventRecipientsScreenState - [_buildSearchField]

I think it calling the _buildSearchField in the build() maybe resetting or causing issues!?!?

Why is iOS behavior for this so much different? This is also true on a physical device too from what I can tell...

Our call for the TypeAhead is the following...

Widget _buildSearchField() {
    // final double boxSize =
    //     deviceHeight > 600 ? deviceHeight * 0.40 : deviceHeight * 0.25;

    logger.fine('[_buildSearchField]');
    return TypeAheadField<dynamic>(
      getImmediateSuggestions: true,
      debounceDuration: _debounce,
      textFieldConfiguration: TextFieldConfiguration<dynamic>(
        // focusNode: _myFocusNode,
        autofocus:
            false, // Dont ever set this to true until everything is fixed.. :)
        style: DefaultTextStyle.of(context)
            .style
            .copyWith(fontStyle: FontStyle.italic),
        decoration: const InputDecoration(
          border: OutlineInputBorder(),
          filled: true,
          hintText: 'Search for members and teams',
          // fillColor: Colors.white,
        ),
      ),
      suggestionsCallback: (String pattern) async {
        logger.fine('[suggestionsCallback()] - pattern of <$pattern>');

        // New search string..go get the results..
        _newPattern = pattern;
        _itemBuilder = true;
        if (_searchingForSuggestions) {
          // we are already searching - save the pattern and return what we have
          logger.fine(
              '[TypeAheadField() - suggestionsCallback] search is already running against \'$_currentSearch\'');
        } else {
          logger.fine(
              '[TypeAheadField() - suggestionsCallback] running search with pattern \'$pattern\'');
          _recipientsFuture = _getSuggestions(pattern);
        }

        // logger.finer(suggestions);
        logger.fine(
            '[suggestionsCallback()] - returning Future of <$_recipientsFuture>');
        return _recipientsFuture;
      },
      itemBuilder: (BuildContext context, dynamic suggestion) {
        final bool isTeam = suggestion['type'] == 'team' ? true : false;
        String displayName;

        if (_itemBuilder) {
          logger.finer(
              '[TypeAheadField() - itemBuilder] - Started with pattern <$_newPattern>');
        }

        _itemBuilder = false;

        if (isTeam) {
          displayName = suggestion['name'];
        } else {
          displayName = '${suggestion['name']} | ${suggestion['descr']}';
        }

        return ListTile(
          contentPadding: const EdgeInsets.all(5.0),
          leading: Icon(
            suggestion['type'] == 'team' ? Icons.people : Icons.person,
            size: 18.0,
          ),
          title: Text(
            displayName,
            style: const TextStyle(fontSize: 12.0),
          ),
          dense: true,
          // subtitle: Text(suggestion['descr']),
        );
      },
      // suggestionsBoxDecoration: SuggestionsBoxDecoration(
      //   constraints: BoxConstraints.expand(height: boxSize),
      // ),
      onSuggestionSelected: (dynamic suggestion) {
        if (suggestion['type'] == 'member') {
          if (_members.indexWhere((IRecipient m) {
                return m.id == suggestion['id'];
              }) ==
              -1) {
            // Make sure we're mounted since we may have closed before we got backk.
            if (mounted) {
              setState(() {
                _members.add(IRecipient(
                    id: suggestion['id'],
                    displayName:
                        '${suggestion['name']} | ${suggestion['descr']}'));
              });
            }
            widget.eventData.members = _members;
          }
        } else {
          if (_teams.indexWhere((IRecipient m) {
                return m.id == suggestion['id'];
              }) ==
              -1) {
            // Make sure we're mounted since we may have closed before we got backk.
            if (mounted) {
              setState(() {
                _teams.add(IRecipient(
                    id: suggestion['id'], displayName: suggestion['name']));
              });
            }
            widget.eventData.teams = _teams;
          }
        }
      },
    );
  }

Any ideas!?

Throttle suggestionsCallback future ..

This is more of a question -- although we are seeing bad behavior (keyboard not properly interacting in iOS Simulator) with our current (probably broken) behavior.

We have found ourselves in a situation where a user that keeps on type (slowly) is activating the getSuggestions callback multiple times BEFORE the previous one has completed. This is an expensive DB hit for us ..and eventually our DB goes to never never land .. so we want to make sure the caller only ever has ONE DB query active .. and when the previous one is done .. we take the LAST pattern given and do a new query on that ..

I was wondering if anyone had any ideas on an approach or maybe has done something similar? I don't see where this logic is built-in anyway to the core Typeahead logic... ? (looking at you @KaYBlitZ ! LOL)

Error: Type 'TextCapalization ' not found

Importing the library and setting up the given example in the docs throws out the below error

final TextCapitalization textCapitalization;
compiler message: ^
compiler message: file:///C:/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_typeahead-0.2.1/lib/flutter_typeahead.dart:1152:7: Error: Type 'TextCapitalization' not found.
compiler message: TextCapitalization textCapitalization,
compiler message: ^
compiler message: file:///C:/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_typeahead-0.2.1/lib/flutter_typeahead.dart:701:9: Error: No
named parameter with the name 'onEditingComplete'

Maybe a feature -- but how does someone force a new getSuggestions to fire even if same text?

Here is the use case:
We have a TypeAheadField .. and we have basically a "radio button set" that controls additional filters to be applied to the getSuggestions. The problem is that I can't think of any easy way to "fire" off the getSuggestions callback (and hence fire off the DB call and render a new suggestions box) from an external trigger like the user changing the radio button to use a different filter.

Nothing clever is jumping out at me looking at the code .. but .. I'm not that clever anyway. :)

Of course we are doing a setState() on change of buttons and I see it calling build (high level) and building the TypeAheadWidget .. which is probably calling ... build? But since the internal state within the TypeAheadWidget hasn't changed .. it's just being efficient and not doing anything. :)

@KaYBlitZ or @AbdulRahmanAlHamali -- or anyone -- any cool ideas on this one??

Type error

I'm not sure if it's the Typeahead bug or Dart bug.

Here's the repro case:

import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'flutter_typeahead demo',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 1,
      child: Scaffold(
          appBar: AppBar(
            title: TabBar(tabs: [
              Tab(
                text: 'Example 1: Navigation',
              ),
            ]),
          ),
          body: TabBarView(children: [NavigationExample()])),
    );
  }
}

enum Skill {
    Math,
    English,
    Physics,
    Sports,
}

class NavigationExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(32.0),
      child: Column(
        children: <Widget>[
          SizedBox(
            height: 10.0,
          ),
          TypeAheadField<Skill>(
            textFieldConfiguration: TextFieldConfiguration(
              autofocus: true,
              decoration: InputDecoration(
                  border: OutlineInputBorder(),
                  hintText: 'Got skillz?'),
            ),
            suggestionsCallback: (pattern) => Skill.values,
            itemBuilder: (context, suggestion) =>
              ListTile(title: Text(suggestion.toString())),
            onSuggestionSelected: (suggestion) {
                print("Selected: ${suggestion.toString()}");
            },
          ),
        ],
      ),
    );
  }
}

If you run it as is it fails with exception

I/flutter (10939): The following assertion was thrown building
I/flutter (10939): _OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#c54a2](dirty, state: _OverlayEntryState#02217):
I/flutter (10939): type '(BuildContext, Skill) => ListTile' is not a subtype of type '(BuildContext, dynamic) =>
I/flutter (10939): Widget'
I/flutter (10939): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter (10939): more information in this error message to help you determine and fix the underlying cause.
I/flutter (10939): In either case, please report this assertion by filing a bug on GitHub:
I/flutter (10939):   https://github.com/flutter/flutter/issues/new?template=BUG.md
I/flutter (10939): When the exception was thrown, this was the stack:
I/flutter (10939): #0      _TypeAheadFieldState._initOverlayEntry.<anonymous closure> (package:flutter_typeahead/flutter_typeahead.dart:697:33)
I/flutter (10939): #1      _OverlayEntryState.build (package:flutter/src/widgets/overlay.dart:170:25)

If you remove <Skill> from the call to TypeAheadField<Skill>(...) it works fine.

Flutter 1.1.9 • channel dev • https://github.com/flutter/flutter.git
Framework • revision 1407091bfb (5 days ago) • 2019-01-08 20:40:19 -0800
Engine • revision e5ec3cf3ea
Tools • Dart 2.1.1 (build 2.1.1-dev.0.1 2cb346bd0c)

Can't see items in dialog

Even though suggestions are being sent in itemBuilder, items can't be seen. Same code is working if I don't put it inside a dialog.

BoxConstraints not applying maxHeight on SuggestionsBoxDecoration

           TypeAheadField<String>(
              suggestionsBoxDecoration: SuggestionsBoxDecoration(
                constraints: BoxConstraints(
                  maxHeight: 100,
                ),
              ),
              textFieldConfiguration: TextFieldConfiguration(
                decoration: InputDecoration(hintText: 'SuperType'),
              ),
              itemBuilder: (BuildContext context, itemData) {
                return ListTile(
                  title: Text(itemData),
                );
              },

I'm trying to limit the size of the suggestions box using BoxConstraints. The typeahead field is being used in a Scrollable widget, applying custom constraints or leaving them as default doesn't seem to work, they take all height available.

Option to keep suggestion box "as is" until loading is done?

Maybe I'm doing something wrong, but when testing with suggestions that take only 100 ms to load, the box disappears and reappears, even with

animationStart: 1,
animationDuration: Duration(microseconds: 0),

IMHO it would look much nicer if the current suggestions would stay until new ones are loaded. Would it make sense to have an option (or set a duration) for not updating the suggestion box at all until new suggestions are loaded?

Return suggestions in "row" style versus "column" style option?

Currently, suggestions return as a list. Any plans to make it so that the suggestions can return as a "row" of suggestions, and wrap around as needed?

For example, instead of:

[Item]
[Item2]
[Item3
[Item]
[Item2]
[Item3

It is:

[Item] [Item2] [Item3] ...
...

On smaller devices -- keyboard obscures suggestions and doesn't scroll

This is a great widget. Our issue is that on smaller devices (specifically for us a user has an iPhone SE) and the initial suggestions comes up -- but when they tap in the box and the keyboard pops up -- the bottom of the list is obscured by the keyboard and scrolling doesn't "work". Meaning, it doesn't actually scroll it scrolls then pops back ... probably because it's confused that the text isn't visible by the keyboard?

Any workaround to this?

Also -- the "Done" button on iOS removes the keyboard, but also the scroll list and everything else -- so that didn't help :(

This is rather important for our users.. hoping for some ideas @AbdulRahmanAlHamali

Support for BLoC pattern when building suggestions

Currently, the way TypeAheadField et al works is by awaiting on the building of a list of items whenever there is typing interaction:

TypeAheadField(
  suggestionsCallback: fetchList,
  // ...
)

This is pretty simple and works well. However, it prevents someone from implementing a BLoC pattern for the building of a suggestion list. Instead of suggestionCallback, the constructor could also provide, for example, a suggestions field that accepts a Widget (such as BlocBuilder), so it'd take care to build a ListView or something scrollable of the suggestions. Or another solution.

I'd be happy to implement it.

Applying a FocusNode crashes the Typeahead widget

Hi everyone,

When I apply a FocusNode to this TypeAhead widget, after selecting my first suggestion, an exception is thrown:
Duplicate Global key being used.

Here is how I build the TypeAhead widget

Widget _buildExerciseTargetMuscleTFF() {
    return Container(
      margin: EdgeInsets.symmetric(horizontal: 16.0),
      child: TypeAheadFormField(
        textFieldConfiguration: TextFieldConfiguration(
          controller: _exerciseTargetMuscleTEC,
          focusNode: _initFNWithListener(),
          keyboardType: TextInputType.text,
          decoration: InputDecoration(
              labelText: "Target Muscle", labelStyle: _labelTextStyle),
          maxLength: 50,
        ),
        suggestionsCallback: (pattern) {
          return pattern != null && pattern.isNotEmpty
              ? muscles
                  .where((muscle) =>
                      muscle.toLowerCase().contains(pattern.toLowerCase()))
                  .toList()
              : [];
        },
        itemBuilder: (context, suggestion) {
          return ListTile(
            title: Text(suggestion),
          );
        },
        noItemsFoundBuilder: (context) {
          return Container();
        },
        transitionBuilder: (context, suggestionsBox, controller) {
          return suggestionsBox; // Removes the ugly default animation
        },
        onSuggestionSelected: (suggestion) {
          _exerciseTargetMuscleTEC.text = suggestion;
        },
        validator: (String value) {
          if (value == null || value != null && value.trim().isEmpty) {
            return "Target muscle is required.";
          }
          if (value.trim().length > 50) {
            return "Target muscle cannot exceed more than 50 charaters.";
          }
        },
        onSaved: (String targetMuscle) {
          if (_exercise != null) {
            _exercise.targetMuscle = targetMuscle;
          }
        },
      ),
    );
  }

FocusNode _initFNWithListener() {
    FocusNode focusNode = new FocusNode();
    focusNode.addListener(() {
      if (focusNode.hasFocus) {
        _startEdit();
      }
    });
    return focusNode;
  }

Any idea why this is happening? 

Scroll suggestions

Hi,

Should it be possible to scroll the suggestions?
If yes, it does not work for me :/
If no, this would be a really useful feature...

Thanks ;)

FocusNode exception

I'm on 1.2.0 and latest dev channel Flutter. My application has a TabBar with 3 tabs and when it starts it shows the first tab. TypeAhead is used only on the second tab, but if I switch from tab1 to tab3 I receive this:

flutter: ══╡ EXCEPTION CAUGHT BY SCHEDULER LIBRARY ╞═════════════════════════════════════════════════════════
flutter: The following assertion was thrown during a scheduler callback:
flutter: A FocusNode was used after being disposed.
flutter: Once you have called dispose() on a FocusNode, it can no longer be used.
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0      ChangeNotifier._debugAssertNotDisposed.<anonymous closure> (package:flutter/src/foundation/change_notifier.dart:105:9)
flutter: #1      ChangeNotifier._debugAssertNotDisposed (package:flutter/src/foundation/change_notifier.dart:111:6)
flutter: #2      ChangeNotifier.addListener (package:flutter/src/foundation/change_notifier.dart:141:12)
flutter: #3      _TypeAheadFieldState.initState.<anonymous closure> (package:flutter_typeahead/flutter_typeahead.dart:747:32)
flutter: #4      _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1008:15)
flutter: #5      _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:956:9)
flutter: #6      _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:860:5)
flutter: #10     _invoke (dart:ui/hooks.dart:219:10)
flutter: #11     _drawFrame (dart:ui/hooks.dart:178:3)
flutter: (elided 3 frames from package dart:async)
flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════

It doesn't happen if I switch to tab2 (where TypeAhead is used), only if I switch from tab1 to tab3 or from tab3 to tab1. I'm struggling to create a repro case though, but maybe someone has an idea what's going on?

Need a way to hide the suggestion box

When the suggestion box is showing, there seems to be no way to hide it except for tapping on one of the items. Since the suggestion box covers widgets that are placed underneath it, I need some way to close the box, either by tapping outside it or with a "X"-button inside the box itself. Is this possible to do somehow?

MR 45 Hide the suggestions box when keyboard is hidden

Hello,

I get a closing keyboard immediately after this change on a closed keyboard:
E/SpannableStringBuilder( 9947): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length

I tap on the entry field, keyboard opens and closes and I get an error. This issue appeared with this new change.

OS: Android 7.1.1
Flutter version 1.2.0

suggestionsCallback not being called iOS

Version flutter_typeahead: ^1.0.5 works perfectly on Android, however the suggestionsCallback is not being fired on iOS.

Currently running minimum iOS build 10.
Flutter (Channel beta, v1.2.1, on Mac OS X 10.14.3 18D10)
xCode version Version 10.1 (10B61)

I have upgraded flutter, reinstalled the pods. I have not attempted to debug the issue yet, except that the suggestionsCallback is not firing.

0.5 broke something pretty fundamental

On 0.4.X this work working just fine -- I upgraded to 0.5.0 and now for the same Widgets I am getting the below stack trace (and red screen of death on the phone).

Any ideas?

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following assertion was thrown building _SuggestionsList<dynamic>(dirty, state:
flutter: _SuggestionsListState<dynamic>#feb23(ticker inactive)):
flutter: BoxConstraints has non-normalized height constraints.
flutter: The offending constraints were:
flutter:   BoxConstraints(w=Infinity, 358.4<=h<=300.0; NOT NORMALIZED)
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0      BoxConstraints.debugAssertIsValid.<anonymous closure>.throwError (package:flutter/src/rendering/box.dart:504:9)
flutter: #1      BoxConstraints.debugAssertIsValid.<anonymous closure> (package:flutter/src/rendering/box.dart:540:19)
flutter: #2      BoxConstraints.debugAssertIsValid (package:flutter/src/rendering/box.dart:551:6)
flutter: #3      new ConstrainedBox (package:flutter/src/widgets/basic.dart:1884:27)
flutter: #4      _SuggestionsListState.build (package:flutter_typeahead/flutter_typeahead.dart:950:14)
flutter: #5      StatefulElement.build (package:flutter/src/widgets/framework.dart:3809:27)
flutter: #6      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3721:15)
flutter: #7      Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #8      ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3701:5)
flutter: #9      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3848:11)
flutter: #10     ComponentElement.mount (package:flutter/src/widgets/framework.dart:3696:5)
flutter: #11     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14)
flutter: #12     Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12)
flutter: #13     SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4860:14)
flutter: #14     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14)
flutter: #15     Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12)
flutter: #16     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
flutter: #17     Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #18     ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3701:5)
flutter: #19     ComponentElement.mount (package:flutter/src/widgets/framework.dart:3696:5)
flutter: #20     ParentDataElement.mount (package:flutter/src/widgets/framework.dart:4047:11)
flutter: #21     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14)
flutter: #22     Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12)
flutter: #23     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
flutter: #24     Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #25     ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3701:5)
flutter: #26     StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3848:11)
flutter: #27     ComponentElement.mount (package:flutter/src/widgets/framework.dart:3696:5)
flutter: #28     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14)
flutter: #29     Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12)
flutter: #30     RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:4643:32)

Keyboard closing itself when I click on textFormField to input

I'm using your plugin in a form which lies in between other TextFormFileds, but when I touch(click) on the this text field to input data the keyboard raises and closes itself with in a second even before entering any text.
This is my form for that particular filed

Form(
          key:  this._formCityKey,
            child: TypeAheadFormField(
              textFieldConfiguration: TextFieldConfiguration(
                decoration: InputDecoration(labelText: 'Enter city'),
                controller: this._cityTypeAheadController,
              ),
              suggestionsCallback: (pattern) {
                return CitiesService.getSuggestions(pattern, _selectedAdType);
              },
              itemBuilder: (context, suggestion) {
                return ListTile(
                  title: Text(suggestion),
                );
              },
              transitionBuilder: (context, suggestionsBox, controller) {
                return suggestionsBox;
              },
              onSuggestionSelected: (suggestion) {
                this._cityTypeAheadController.text = suggestion;
              },
              validator: (value) {
                if (value.isEmpty) {
                  return 'Please select a city';
                }
              },
              onSaved: (value) => _city = value.toLowerCase(),
            ))

Quick question is all

Using this package and it's awesome -- I have a quick question -- our users want the "search" to automatically load the first N items upon entry to the screen .. or if they click on the search field (if its empty) etc. How can we invoke the suggestionsCallback() and that logic immediately before they have to type anything -- or if they click on the field (I don't see it called on a touch) ??

Something in the order of the TextController ?? But I'm pretty new on that ..

Thanks!

Allow Stream type return instead of Future for suggestionsCallback?

In a different project we are using Firestore (ugh) -- which deals with Streams .. its pretty similar to Futures ..but .. not exactly the same LOL. Currently we allow a Future to be passed in to the suggestionsCallback ... I am wondering if we should also allow instead a Stream type thing in order for those sorts of data "streams" to be used.

I think, in the end, that the result of a Future being done and a Stream being "done" would yield the same data that could be fed into the Builder function ..

As a work around of course the programmer could encapsulate the Stream logic and just present (setState) to TypeAhead the completed list and not pass a Stream or Future .. but for completeness with Streams seemingly taking over the planet this maybe good. May also help in the BLoC stuff since that is all Stream based (well most implementations I've seen) although not exactly sure about the last.

Does not always show total list of possible outcomes if Future return in suggestionsCallback

screen shot 2019-01-18 at 7 36 43 am

screen shot 2019-01-17 at 4 11 54 pm

Please see the screenshot .. I changed the TypeAhead to use a Future in the suggestionsCallback .. however, as can be seen it doesn't always render the full list upon entry and it being invoked if 'getImmediateSuggestions' == true.

Also -- I can't help but notice that the suggestions box is overlaying on top of the Widgets I have .. which is ok .. just .. weird? Is this proper behavior? I basically have a simple layout like


  Widget _buildMainBody() {
    return Column(
      children: <Widget>[
        _buildSearchField(),
        _buildShowTemplate(),
        SizedBox(
          height: 20.0,
        ),
        _buildNavButtons(),
      ],
    );
  }

Where buildSearchField() is the TypeAhead .. and the showTemplate is a simple Text if there is one select and the _buildNavButtons is the Next button ... 

However, the main issue is the lack of proper rendering of the list upon entry .. not sure if I am doing something wrong?  

Oh I can also confirm the itemBuilder IS being called all 5 times (in this case) -- I have a print() in there .. so it's getting all the data.. <shrug> 

Cheers!

Suggestions overflow - ClipRect?

Good widget Abdul!
Question - do you think it's possible to make suggestions scrollable or ClipRect them?
Here is a yellow/black error I'm seeing:

I/flutter ( 4217): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 4217): The following message was thrown during layout:
I/flutter ( 4217): A RenderFlex overflowed by 100 pixels on the bottom.
I/flutter ( 4217): 
I/flutter ( 4217): The overflowing RenderFlex has an orientation of Axis.vertical.
I/flutter ( 4217): The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and
I/flutter ( 4217): black striped pattern. This is usually caused by the contents being too big for the RenderFlex.
I/flutter ( 4217): Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the
I/flutter ( 4217): RenderFlex to fit within the available space instead of being sized to their natural size.
I/flutter ( 4217): This is considered an error condition because it indicates that there is content that cannot be
I/flutter ( 4217): seen. If the content is legitimately bigger than the available space, consider clipping it with a
I/flutter ( 4217): ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex,
I/flutter ( 4217): like a ListView.
I/flutter ( 4217): The specific RenderFlex in question is:
I/flutter ( 4217):   RenderFlex#3e615 OVERFLOWING
I/flutter ( 4217):   creator: Column ← RepaintBoundary-[<3>] ← IndexedSemantics ←
I/flutter ( 4217):   NotificationListener<KeepAliveNotification> ← KeepAlive ← AutomaticKeepAlive ← SliverFillViewport
I/flutter ( 4217):   ← Viewport ← _ScrollableScope ← IgnorePointer-[GlobalKey#3b7f8] ← Semantics ← Listener ← ⋯
I/flutter ( 4217):   parentData: <none> (can use size)
I/flutter ( 4217):   constraints: BoxConstraints(w=379.4, h=297.4)
I/flutter ( 4217):   size: Size(379.4, 297.4)
I/flutter ( 4217):   direction: vertical
I/flutter ( 4217):   mainAxisAlignment: spaceBetween
I/flutter ( 4217):   mainAxisSize: min
I/flutter ( 4217):   crossAxisAlignment: center
I/flutter ( 4217):   verticalDirection: down
I/flutter ( 4217): ◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤
I/flutter ( 4217): ════════════════════════════════════════════════════════════════════════════════════════════════════

Identifying a Selection was Made

Hi,

Is there a way to identify a selection was made? I noticed if I enter random text and hit the submit button, I still get the random text using print(_typeAheadController.text);

I have:
onSuggestionSelected: (suggestion) { this._typeAheadController.text = suggestion; },

Did the this._typeAheadController.text gets updated even a selection wasn't made?

Thanks

Allow for "onFieldSubmitted" event.

In my case when using this widget the user might not want to use a given suggestion. In the case where they do not, I would like to take a different action than when using the "onSuggestionSelection" event and use something like TextFormField has which is a "onFieldSubmitted" event.

SuggestionList ListView.shrinkWrap configurable?

I'm new to flutter (this week), so I might be missing the obvious.

When there is a large number of suggestions that match the query, they do not all fit on the screen; and, when you collapse the keyboard to try to scroll down, the ListView does not scroll. I think this is because shrinkWrap: true; ... as in this:

    } else {
      child = ListView(
        padding: EdgeInsets.zero,
        primary: false,
        shrinkWrap: true,  // ** Can, or should, this be made configurable?
        children: this._suggestions.map((T suggestion) {
          return InkWell(
            child: widget.itemBuilder(context, suggestion),
            onTap: () {
              widget.onSuggestionSelected(suggestion);
            },
          );
        }).toList(),
      );

Various interaction issues with 1.0.5 and the keyboard ...

screen shot 2019-02-28 at 10 22 32 am

Our users are trying our app and we have some pretty critical UX issues that are appearing that we need some help with quickly .. (we hope to launch next week).

@KaYBlitZ -- any chance you can look at these? THey are all keyboard related.. and I think part of the solution IS going to use that 3rd party keyboard detection thing ..

Problem 1 -- on iOS when we enter a screen with a Typeahead the keyboard isn't appearing (see screen shot on an XR) and there is no way to make it appear since the focus is already in the TextField (that anyone can figure out). The keyboard DOES appear on Android .. %K on iOS causes the keyboard to appear but -- shouldn't it always appear on entry / focus ??

  1. On Android if I click on the TextField the keyboard reappears .. this does not happen on iOS

  2. If keyboard is open -- no way to scroll the list to select an entry hidden by keyboard ..

  3. If we implement the "close list on keyboard close" -- how would the user EVER scroll the list? I thought we recalculated the "display" size to accomodate the keyboard being open so the list could scroll?

  4. Assuming we fix 4, then we need to implement the "on keyboard close" dismiss the suggestions box option. We need this because there are some critical buttons being hidden by the suggestions box that allow the user to continue the process but they can't get access to them so we need a way to toggle showing the suggestions box or not .. and not many options on how to do it that I can see.

Phew.

/Steve

Has this become abandon ware?

There has been no activity on this project in months and nothing on the PRs ... I fear this is deadware ..

There is another project that is similar that appears to be alive (at least for now):

Flutter AutoComplete

Suggestion box height is incorrect when TypeAhead is in an scrollable

maxHeight calculation in the method resize() in the source code is not correct. Specifically the variable textBoxAbsY which is calculated as double textBoxAbsY = box.localToGlobal(Offset.zero).dy;

Creating a TypeAhead at the top of the scrollable works fine but once you scroll an take the focus of the textField, then the variable textBoxAbsY is not being calculated properly.

Maybe this can be fixed using the viewport and/or the ScrollPosition. I would PR, but I have never used these classes:

RenderAbstractViewport viewport = RenderAbstractViewport.of(box); // is not null when using a scroll
double offsetToRevealTop = viewport.getOffsetToReveal(box, 0.0).offset;

ScrollPosition scrollPosition = Scrollable.of(context).position;
double pixels = scrollPosition.pixels;

Hide suggestions box completely

Is there a way to hide the suggestions box completely if no suggestions have been found? When I use noItemsFoundBuilder: (context) => Container(), I still get the empty box.

Make SuggestionBox can be on top of TextField.

Is there any way to put the SuggestionBox above TextField? Because now my situation is that the input method will block the SuggestionBox, so I want to make the SuggestionBox above the TextField.

On focus is triggering another search

Every time I click on the TypeAheadField, even if I don't type anything, suggestionsCallback is being triggered. I looked into _SuggestionsListState but couldn't figure out why if (widget.controller.text == this._lastTextValue) return; this is not working.

Right now I have to create some kind of check inside suggestionsCallback to return an empty list instead of hitting the API.

Styling ListTile spacing between items

When the font for ListTile's title/subtitle is set to rather small (fontSize 6 or 8), the ListView showing a list of suggestions with huge padding around each ListItem. Can we change this? I've tried changing ListTile.contentPadding but that seems only affecting the Left/Right paddings, and leaving the vertical padding between each ListItem unaffected

img_20190225_234243
.

Text typed not reflecting in selections

Good widget visually, but not sure if the typeahead functionality is actually working - typeahead normally means when you type a letter, you should only see those entries which have that letter (or a combination), right?

It seems the formula is not providing that. So in your 2nd example, when you type B for Beirut, you are seeing Rome coming up the list, where B is not even present. Any way of correcting such behaviour?

Keyboard blocks overlay

For some screens with variable number of fields, the placement of an auto-complete field may not be known at design time. It would be great if the direction could adjust if there weren't enough room in the desired direction. In this screenshot you can see that the overlay of suggestions is completely obscured:

Simulator_Screen_Shot_-iPhone_X-_2019-03-22_at_16_10_10

Here the overlay looks ok because the screen is scrolled up:

Simulator_Screen_Shot_-iPhone_X-_2019-03-22_at_16_12_44

Multi-selection ?

We have a situation where, after we show a selection list .. we want to keep the list open so the user can click multiple items (and call the appropriate callback) after each one .. and of course refresh the selection list since we've removed the selected item .. :)

It would be slick to keep this going until the onSuggestionsSelected returns a bool "false" or something.. Just thinking out of the box right now.. of course closing the keyboard would close the suggestions box too .. (if option set) ..

Thoughts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.