Create highly customizable, simple, and controllable autocomplete fields for Flutter.

Overview

Field Suggestion

codecov Package Version LICENSE


Installing

Depend on it

Add this to your package's pubspec.yaml file:

dependencies:
  field_suggestion: <latest_version>

Install it

You can install packages from the command line:

$ flutter pub get

Import it

Now in your Flutter code, you can use:

import 'package:field_suggestion/field_suggestion.dart';

Usage and overview

Require to create a TextEditingController and suggestions list, e.g:

final textEditingController = TextEditingController();
// And 
List<String> suggestionList = [
 '[email protected]',
 '[email protected]',
 '[email protected]',
];

Basic/Default usage.

FieldSuggestion(
  textController: textEditingController,
  suggestionList: suggestionList,
  hint: 'Email',
),

Custom usage.

FieldSuggestion(
  textController: textEditingController,
  suggestionList: suggestionList,
  fieldDecoration: InputDecoration(
    hintText: "Email",
    enabledBorder: const OutlineInputBorder(),
    focusedBorder: const OutlineInputBorder(),
  ),
  wDivider: true,
  divider: const SizedBox(height: 5),
  wSlideAnimation: true,
  slideAnimationStyle: SlideAnimationStyle.LTR,
  slideCurve: Curves.linearToEaseOut,
  animationDuration: const Duration(milliseconds: 300),
  suggestionItemStyle: SuggestionItemStyle.WhiteNeumorphismedStyle,
  suggestionBoxStyle: SuggestionBoxStyle(
    backgroundColor: Colors.white,
    borderRadius: BorderRadius.circular(15),
    boxShadow: [
      BoxShadow(
        color: Colors.blue.withOpacity(.2),
        spreadRadius: 5,
        blurRadius: 10,
        offset: const Offset(0, 5),
      ),
    ],
  ),
)

External control

Here we just wrapped our Scaffold with GestureDetector to handle gestures on the screen. And now we can close box when we tap on the screen. (You can do it everywhere, where you used FieldSuggestion with BoxController).

 class Example extends StatelessWidget {
   final _textController = TextEditingController();
   final _boxController = BoxController();
 
   @override
   Widget build(BuildContext context) {
     return GestureDetector(
       onTap: () => _boxController.close(),
       child: Scaffold(
         body: Center(
           child: FieldSuggestion(
             hint: 'test',
             suggestionList: [], // Your suggestions list here...
             boxController: _boxController,
             textController: _textController,
           ),
         ),
       ),
     );
   }
 }

Contributions

If you find a bug or want a feature, but don't know how to fix/implement it, please fill an issue.

If you fixed a bug or implemented a new feature, please send a pull request.

Comments
  • Feature: builder factory i.e `FieldSuggestion.builder()`

    Feature: builder factory i.e `FieldSuggestion.builder()`

    Hi, first I want to thank you for this library, it's the best of the kind that I found!

    I'm needing to show a tooltip when user hovers the item in the suggestion list. This would be possible If we had an option to pass a wrapper to the item.

    Right now I'm doing this passing to the FieldSuggestion this parameter: Widget Function(int, Widget)? itemWrapper;

    and changed the itemBuilder inside _buildSuggestionBox to:

    itemBuilder: (context, index) => widget.itemWrapper != null
                    ? widget.itemWrapper!(index, suggestionListItem(index))
                    : suggestionListItem(index),
    

    I don't know if there is a better way to do this. If this could be added inside this library it would be great.

    feature 
    opened by g-scosta 12
  • Feature/builder

    Feature/builder

    Resolves: #26

    Require to take suggestionList, textController, and itemBuilder.

    class BuilderExample extends StatelessWidget {
      final textEditingController = TextEditingController();
      List<String> suggestionsList = ['[email protected]', '[email protected]'];
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: FieldSuggestion.builder(
            hint: 'Email',
            textController: textEditingController,
            suggestionList: suggestionsList,
            itemBuilder: (BuildContext context, int index) {
              return GestureDetector(
                onTap: () => textEditingController.text = suggestionsList[index],
                child: Card(
                  child: ListTile(
                    title: Text(suggestionsList[index]),
                    leading: Container(
                      height: 30,
                      width: 30,
                      decoration: BoxDecoration(
                        color: Colors.blueGrey,
                        shape: BoxShape.circle,
                      ),
                      child: Center(
                        child: Text(suggestionsList[index][0].toUpperCase()),
                      ),
                    ),
                  ),
                ),
              );
            },
          ),
        );
      }
    }
    
    feature 
    opened by theiskaa 11
  • Add custom matcher option

    Add custom matcher option

    Is your feature request related to a problem? Please describe. In current version the field is always searched based in contains method. But sometimes I need a more advanced search. (In my case I need to remove diacritics (accented characters) and compare just the begining of the words, that means that if search oe in the name Jhon Doe 0 results will be found, but Doe will return the result).

    Describe the solution you'd like A general solution would be passing a custom query matcher so the developer can pass any function (regex, custom functions, etc) that returns a boolean value if the matchers is to be included

    Additional context I've created an aditional parameter in FieldSuggestion called customMatcher and passed the value when the matchers are evaluated inside _textListener.

    Ex:

    final bool Function(dynamic, String)? customMatcher;
    
    ...
    
    if (widget.customMatcher != null) {
            matchers = widget.suggestionList
                .where((item) => widget.customMatcher!(item, inputText))
                .toList();
          } else {
            matchers = widget.suggestionList.where((item) {
              // If we call toUperrCase on int or on double then we'll get error.
              // So that's why we check type of list and return suitable method.
              if (widget.suggestionList is List<int> ||
                  widget.suggestionList is List<double>) {
                return item.toString().contains(inputText.toString());
              }
              return item.toUpperCase().contains(inputText.toUpperCase());
            }).toList();
          }
    
    feature 
    opened by gcostaapps 5
  • Cannot refresh state

    Cannot refresh state

    Bug Description:

    When we try to remove an item from our suggestion list, then already opened suggestion box cannot understand that so it didn't update. However, FieldSuggestion's BoxController should have a refresh functionality to refresh widget after local changes.

    Reported by: @g-scota

    To Reproduce

    Steps to reproduce the behavior:

    1. Make a field suggestion widget (by builder).
    2. Add remove functionality to Suggestion Item. and try that functionality
    bug 
    opened by theiskaa 2
  • Generic type widget support

    Generic type widget support

    As tried to provide generic types for the main widget in PR(#48). We have to provide kinda functionality to the FieldSuggestion widget. Which would make user experience way way better.

    Example:

    FieldSuggestion<String>(
     ...
    )
    

    or

    FieldSuggestion<int>(
     ...
    )
    
    feature 
    opened by theiskaa 1
  • Error on using a custom class list

    Error on using a custom class list

    First, I want to say that I'm Brazilian, so sorry for my English.

    Describe the bug It's the first time I'm using this package and I really liked it when using common values, like strings and ints. But today I tried to do with a class, and it says that "type 'String' is not a subtype of type 'Map<String, dynamic>'" on the 39 line. But when I click on the item, it says that it's a class. I have the toJson function on my class.

    To Reproduce Steps to reproduce the behavior:

    1. Create a UserModel class with name and password.
    2. I did the same model of the example.
    3. I'm running on Windows 10.
    4. When I click on the field, it stops.
    opened by Noslin22 1
  • Feature/custom search

    Feature/custom search

    Resolves: #34

    Example:

    FieldSuggestion(
        customSearch: (_, __) => true, // Suggestion box won't close.
        // As default it is:
        // customSearch: (item, input) => item.contains(input)
    )
    
    opened by theiskaa 1
  • State refreshing

    State refreshing

    Resolves: #29

    New features:

    • Added refresh functionality to BoxController
    • Fixed closeBoxAfterCompleting problem
    • Added functionality, which automatically moves indicator to text's right position when suggestion item is selected

    Example of the main issue-resolving:

    Need a boxController first of all. Create it and give it to the suggestion field. Then just call boxController.refresh!() when you want to update your FieldSuggestion widget.

    official

    feature 
    opened by theiskaa 1
  • Feature/search by multiple properties

    Feature/search by multiple properties

    Resolves: #23

    Result:

    https://user-images.githubusercontent.com/59066341/124509691-6ebb1080-dde3-11eb-88e4-2d1f8a3a0ae8.mov

    FieldSuggestion(
      hint: 'Email',
      // If y're using list where are classes,
      // Don't forget adding search by property.
      searchBy: ['email', 'username'],
      itemTitleBy: 'username',
      // If you provide [itemSubtitleBy] then suggestion 
      // item's subtitle automaticallty will be enabled.
      itemSubtitleBy: 'email',
      boxController: thirdBoxController,
      textController: thirdTextController,
      suggestionList: userSuggestions,
      onItemSelected: (value) {
        // The field suggestion needs toJson mehtod inside your model right?
        // So that's mean it converts your model to json.
        // Then the output has to be JSON (Map). So now we can get our value's email.
        print(value['passoword']);
      },
    ),
    
    feature 
    opened by theiskaa 1
  • Feature/onItemSelected

    Feature/onItemSelected

    Resolves: #22

    Example:

     FieldSuggestion(
        hint: 'Email',
        // If y're using list where are classes,
        // Don't forget adding search by property.
        searchBy: 'email',
        boxController: thirdBoxController,
        textController: thirdTextController,
        suggestionList: userSuggestions,
        onItemSelected: (value) {
          // The field suggestion needs toJson mehtod inside your model right? 
          // So that's mean it converts your model to json.
          // Then the output has to be JSON (Map). So now we can get our value's email.
          print(value['email']);
        },
     ),
    
    bug feature 
    opened by theiskaa 1
  • Feature/UI-improvement

    Feature/UI-improvement

    Resolves: #20

    Now users can add leading to suggested item, disable suggested Item trailing or add a new one. etc. To learn more visit custom usage part of docs.

    documentation feature 
    opened by theiskaa 1
  • `page` widget variant to build up field with non-box widget

    `page` widget variant to build up field with non-box widget

    A factory builder to build page alike search field without any appearing box. So, instead of current suggestion box and item builder you will be required to build a page widget with suggestions.

    feature 
    opened by theiskaa 0
  • `network` widget variant to use package-widget for network base searching

    `network` widget variant to use package-widget for network base searching

    Current version of widget requires already providen suggestions. And which makes working with network so hard. So, we've to implement a factory builder to create network-usage appropriate widget which don't requires the suggestions (maybe gonna request something different).

    FieldSuggestion.network(
     boxBuilder: (context, index) {
       if(isLoading) return Center(child: LoadingWidget());
    
       return SingleChildScrollView(
         child: Column(
           children: [
              // ...
           ],
         ),
       );
     }
    )
    
    feature 
    opened by theiskaa 0
Releases(v0.2.4)
  • v0.2.4(Jun 16, 2022)

  • v0.2.3(Mar 15, 2022)

    Updates:

    Resolved: #33 and #44

    • Refactored and Redesigned whole widget structure, by that rendering speed was improved by almost 5x.
    • Made require the [search] field, to provide high customization and algorithm-agnostic usage. As default search could be normal -> item.toString().contains(input)
    • Rewritten the whole documentation of field suggestion.

    The new widget structure:

     ╭───────╮      ╭─────────────╮                                                  
     │ Input │╮    ╭│ Suggestions │                                                  
     ╰───────╯│    │╰─────────────╯                                                  
              │    │               Generated by                                      
              │  Element         search algorithm                                    
              │    │              ╭──────────╮                                       
              ▼    ▼          ╭──▶│ Matchers │─╮                                     
        ╭──────────────────╮  │   ╰──────────╯ │  ╭──────────────╮                   
        │ Search Algorithm │──╯                ╰─▶│ Item Builder │                   
        ╰──────────────────╯                      ╰──────────────╯                   
         Passes input and suggestion's             ... Passes context and            
         element to search function.               index of "matcher in suggestions".
         So, as a result matchers                  suggestion item widget.           
         fill be filled appropriate                                                  
         to algorithm                                                                
    
    Source code(tar.gz)
    Source code(zip)
  • v0.2.2(Oct 14, 2021)

  • v0.2.1(Oct 4, 2021)

  • v0.2.0(Aug 17, 2021)

  • v0.1.9(Jul 27, 2021)

    [v0.1.9] - 27/07/2021

    News:

    • Resolved: #29

    Features/Bug-fixes:

    • Added refresh functionality to BoxController
    • Fixed closeBoxAfterCompleting problem
    • Added functionality, which automatically moves indicator to text's right position when suggestion item is selected

    Example of the main issue-resolving: Need a boxController first of all. Create it and give it to the suggestion field. Then just call boxController.refresh!() when you want to update your FieldSuggestion widget.

    Overview:

    Source code(tar.gz)
    Source code(zip)
  • v0.1.8(Jul 26, 2021)

    [v0.1.8] - 21/07/21

    News:

    • Resolved: #26

    Features:

    • Added builder factory (i.e FielsSuggestion.builder) By using builder users can make custom suggestion items. So that improves the package's UI/UX. Now it has more ability to customize as we wish. So that means

    Overview:

    Source code(tar.gz)
    Source code(zip)
  • v0.1.7(Jul 5, 2021)

    [v0.1.7] - 5/07/21

    News:

    Features:

    • onItemSelected property added
    • subtitle added for suggestion item.
    • searchBy converted to list so that means users are able to give multiple properties to search. See more.
    Source code(tar.gz)
    Source code(zip)
  • v0.1.6(Jun 19, 2021)

  • v0.1.5(Jun 8, 2021)

    News:

    • FieldSuggestion logo is ready! 🎉

      Field Suggesion's Logo
    • Resolved: #19 New feature: A model class suggestions.

    UserModel class, we would use it into suggestionList. Note: You must have toJson method in your model class.

    class UserModel {
      final String? email;
      final String? password;
    
      const UserModel({this.email, this.password});
    
      // If we wanna use this model class into FieldSuggestion.
      // Then we must have toJson method, like this:
      Map<String, dynamic> toJson() => {
            'email': this.email,
            'password': this.password,
          };
    }
    

    If we gave a userSuggestions which is List<UserModel>. Then we must add the searchBy property. Our model has just email and password, right? So then we can implement it like: searchBy: 'email' or searchBy: 'password'.

    FieldSuggestion(
      hint: 'Email',
      textController: textEditingController,
      suggestionList: userSuggestions,
      searchBy: 'email' // Or 'password'
    ),
    
    Source code(tar.gz)
    Source code(zip)
  • v0.1.4(Jun 5, 2021)

  • v0.1.3(May 30, 2021)

  • v0.1.2(May 30, 2021)

    News:

    • Tests were improved. current coverage: codecov
    • And added new feature: External control. now users can control the suggestion boxes externally.

    Example of external control:

    Here we just wrapped our Scaffold with GestureDetector to handle gestures on the screen. And now we can close box when we tap on the screen. (You can do it everywhere, where you used FieldSuggestion with BoxController).

     class Example extends StatelessWidget {
       final _textController = TextEditingController();
       final _boxController = BoxController();
     
       @override
       Widget build(BuildContext context) {
         return GestureDetector(
           onTap: () => _boxController.close(),
           child: Scaffold(
             body: Center(
               child: FieldSuggestion(
                 hint: 'test',
                 suggestionList: [], // Your suggestions list here...
                 boxController: _boxController,
                 textController: _textController,
               ),
             ),
           ),
         );
       }
     }
    
    Source code(tar.gz)
    Source code(zip)
  • v.0.1+1(May 3, 2021)

    Basic/Default usage.

    FieldSuggestion(
      textController: emailEditingController,
      suggestionList: suggestionList,
      hint: 'Email',
    ),
    

    Parameters:

    | parameter | description | default | | -------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | onTap | It makes able to set custom onTap method. e.g you need open a page, when item selected. Then you should use [onTap] as Navigator. | Changes value of field with title of selected item | | onIconTap | It makes able to set custom method when we press on tralling of SuggestionItem. | Removes tapped item which are in [suggestionList] and private [matchers] list. | sizeByItem | Makes able to set size of SuggestionsBox by calculating count of SuggestionItem. | We do not use that property to set size of SuggestionBox. | | suggestionBoxStyle | Custom style option of [SuggestionBox], Makes able to customize SuggestionBox. | SuggestionBoxStyle.DefaultStyle | | wDivider | if it equeals true, you would see a simple line, every suggestionItem's front. | false, so it's diabled. | | divider | If wDivider is enabled, then user can use this property to show a widget every suggestionItem's front | Divider() widget. | | suggestionItemStyle | Custom style option for SuggestionItem. Makes able to customize Suggestion Item With following properties: backgroundColor, titleStyle, icon, iconSize, iconColor, border, borderRadius, gradient, boxShadow, margin.|It takes, [SuggestionItemStyle.DefaultStyle] as default.| | hint | Field hint property to set it without fieldDecoration property. | null | | fieldDecoration | Custom InputDecoration of Field | InputDecoration(hintText: hint, labelText: hint), | | fieldType | TextInputType of field. | null | | focusNode | FocusNode of field. | null | | onChanged | onChanged so Function(String) method of Field | null | | maxLines | maxLines of field | null | | disabledDefaultOnTap | To dissable default onTap method of SuggestionItem. | false, so it's diabled | | disabledDefaultOnIconTap | To dissable default onIconTap method of SuggestionItem. | false, so it's diabled | | closeBoxAfterSelect | If it's equals false (so disabled) then when you select item suggestion box won't close. | true, so it's enabled | | scrollController | The scroll controller for suggestionList. | null | | spacer | To set size between field and suggestionsBox. | 5.0 | | wOpacityAnimation | To disable or enable opacity animation. | false, so it's diabled | | animationDuration | Customize duration of suggestion Box animation. | Duration(milliseconds: 400) | | wSlideAnimation | To enable or disable slide animtaion of suggestions box. | false, so it's diabled | | slideAnimationStyle | Custom enum to set tween offset of slide animation, by: Rigth to left [RTL], Left to right [LTR], Bottom to up [BTU], Up to down [UTD].| SlideAnimationStyle.RTL | | slideCurve | To initilaze custom transition curve. | null | | slideTweenOffset | Offset with Tween for Slide animation. Note: when you use slideTweenOffset, otomaticly slideAnimationStyle would be disabled. | null

    Source code(tar.gz)
    Source code(zip)
Owner
Ismael Shakverdiev
Self-taught Developer | Design and Programming enthusiasts.
Ismael Shakverdiev
⚡️A highly customizable, powerful and easy-to-use alerting library for Flutter.

Flash ⚡️ A highly customizable, powerful and easy-to-use alerting library for Flutter. Website: https://sososdk.github.io/flash Specs This library all

null 368 Jan 5, 2023
A highly customizable Flutter widget to render and interact with JSON objects.

The spreadsheet with superpowers ✨ ! JSON Data Explorer A highly customizable widget to render and interact with JSON objects. Features Expand and col

rows 15 Dec 21, 2022
Powerful, helpfull, extensible and highly customizable API's that wrap http client to make communication easier with Axelor server with boilerplate code free.

flutter_axelor_sdk Powerful, helpful, extensible and highly customizable API's that wrap http client to make communication easier with Axelor server w

Abd al-Rahman al-Ktefane 5 Dec 25, 2022
A highly customizable Flutter color picker.

FlexColorPicker FlexColorPicker is a customizable color picker for Flutter. The ColorPicker can show six different types of color pickers, three of wh

Rydmike 132 Dec 14, 2022
A highly customizable Flutter color picker.

FlexColorPicker FlexColorPicker is a customizable color picker for Flutter. The ColorPicker can show six different types of color pickers, three of wh

Rydmike 132 Dec 14, 2022
Add beautiful animated effects & builders in Flutter, via an easy, highly customizable unified API.

Flutter Animate A performant library that makes it simple to add almost any kind of animated effect in Flutter. Pre-built effects, like fade, scale, s

Grant Skinner 352 Dec 25, 2022
A package that provides a highly customizable sheet widget that snaps to different vertical & horizontal positions

Snapping Sheet A package that provides a highly customizable sheet widget that snaps to different vertical & horizontal positions Can adapt to scrolla

Adam Jonsson 364 Dec 6, 2022
The flutter_calendar_widget is highly customizable calendar widget.

flutter_calendar_widget The flutter_calendar_widget is highly customizable calendar widget. Not only can you change the style, but you can also change

dooboolab 4 Jun 24, 2022
A TypeAhead (autocomplete) widget for Flutter, where you can show suggestions to users as they type

Starlight Type Ahead FLUTTER | ANDROID, IOS, LINUX, MACOS, WEB, WINDOWS A TypeAhead (autocomplete) widget for Flutter, where you can show suggestions

Ye Myo Aung 4 Dec 15, 2021
An address search field which helps to autocomplete an address by a reference

Address Search Field Widget builders to create 'address search widgets' which helps to autocomplete an address using a reference. They can be used to

Jose Luna 13 Aug 14, 2022
Flutter form fields designed to take much of the burden of form-related coding off the programmer's back — masks, validations, keyboard type, etc.

well_formed Contents Overview Getting Started Demo application References Overview Well-Formed Widget Fields - Well-Formed - is a collection of Flutte

Dartoos 7 Nov 2, 2022
Object-oriented package for validating Flutter form fields.

formdator Contents Overview Getting Started List of Validators Categories Demo Application References Overview Form Validator — Formdator is a fully o

Dartoos 10 Oct 26, 2022
Input fields for Flutter standalone or within a form

Flutter Input Widgets - Standalone or within a Form → flutter_input This package provides input widgets (fields) to manipulate data. The data to manip

null 7 Mar 14, 2021
First Open Source Flutter based Beautiful Material Design Text fields.

Pretty text field First Open Source Flutter based Beautiful Material Design Text fields.(More designed text fields coming soon.) Features [*] Compatib

Darshh 1 Aug 29, 2022
null 0 Feb 16, 2022
A highly customisable and simple widget for having iOS 13 style tab bars.

cupertino_tabbar A highly customisable and simple widget for having iOS 13 style tab bars. It is highly recommended to read the documentation and run

AliYigitBireroglu 98 Oct 31, 2022
A lightweight and customizable http client that allows you to create offline-first dart app easily.

Enjoyable & customizable offline-first REST API client Unruffled is lightweight and customizable http client that allows you to create offline-first e

T. Milian 3 May 20, 2022
The easiest way to create your animated splash screen in a fully customizable way.

Animated Splash Screen Check it out at Pub.Dev Do it your way Assets image Custom Widget Url image IconData Or just change PageTransition and/or Splas

Clean Code 104 Nov 10, 2022
Clock loader - Highly versatile Widget display the smooth and creative loader named as clock loader

Clock Loader Highly versatile Widget display the smooth and creative loader name

MindInventory 20 Dec 30, 2022