Powerful Complete and Beautiful Search Component for Flutter

Related tags

Widgets easy_search
Overview

logo

A highly customizable search component to accelerate your development.

Pub Package Buy Me A Coffee

Overview

There are many search or search components for Flutter, however this one comes to perform search in Offline List,

or HTTP Search and more, it already comes with nice default layout and many customizations,

and we can focus more on writing amazing applications.

Contributing

Getting Started

In pubspec.yaml:

dependencies:
  easy_search: any

Important configuration:

  • If you want to use the Offline List or Local list, do not implement the OnSearch method

  • If you want to fetch data from a web server or an API, do not implement the Offline List or Local List

  • If both OnSearch and the Offline List are implemented, the OnSearch method will prevail and the Offline List will be ignored

Offline list:

Default Layout:

Simple Offline List

import 'package:easy_search/easy_search.dart';

EasySearch(
  searchResultSettings: SearchResultSettings(
    padding: EdgeInsets.only(left: 8.0, top: 8.0, right: 8.0),
  ),
  controller: SearchItem(
    items: [
      Item(ModelExample(name: 'Tiago', age: 36), false),
      Item(ModelExample(name: 'Mel', age: 3), false),
      Item(ModelExample(name: 'Monique', age: 30), false),
    ],
  ),
),
Custom Layout:

Simple Offline List With Custom Layout

import 'package:easy_search/easy_search.dart';

EasySearch(
  searchResultSettings: SearchResultSettings(
    padding: EdgeInsets.only(left: 8.0, top: 8.0, right: 8.0),
  ),
  controller: SearchItem(
    items: [
      Item(ModelExample(name: 'Tiago', age: 36), false),
      Item(ModelExample(name: 'Mel', age: 3), false),
      Item(ModelExample(name: 'Monique', age: 30), false),
    ],
  ),
  customItemBuilder: (BuildContext context, ModelExample item, bool isSelected) {
    return Container(
      decoration: !isSelected
          ? null
          : BoxDecoration(
              border: Border.all(color: Theme.of(context).primaryColor),
              borderRadius: BorderRadius.circular(7),
              color: Colors.white,
            ),
      child: ListTile(
        selected: isSelected,
        title: Text(item.name),
        subtitle: Text(
          item.age.toString(),
        ),
        leading: Icon(Icons.people),
      ),
    );
  },
),
Multi Select Items:

Simple Offline List With Custom Layout And Multi Selection Items

import 'package:easy_search/easy_search.dart';

EasySearch(
  multipleSelect: true,
  searchResultSettings: SearchResultSettings(padding: EdgeInsets.only(left: 8.0, top: 8.0, right: 8.0)),
  controller: SearchItem(
    items: [
      Item(ModelExample(name: 'Tiago', age: 36), false),
      Item(ModelExample(name: 'Mel', age: 3), false),
      Item(ModelExample(name: 'Monique', age: 30), false),
    ],
  ),
  customItemBuilder: (BuildContext context, ModelExample item, bool isSelected) {
    return Container(
      decoration: !isSelected
          ? null
          : BoxDecoration(
              border: Border.all(color: Theme.of(context).primaryColor),
              borderRadius: BorderRadius.circular(7),
              color: Colors.white,
            ),
      child: ListTile(
        selected: isSelected,
        title: Text(item.name),
        subtitle: Text(item.age.toString()),
        leading: Icon(Icons.people),
      ),
    );
  },
),

HTTP Request:

Default Layout - Http:

From HTTP Request

import 'package:easy_search/easy_search.dart';

EasySearch(
  onSearch: (text) {
    print('Filter Query: $text');
    return getData(name: text);
  },
  searchResultSettings: SearchResultSettings(
    padding: EdgeInsets.only(left: 8.0, top: 8.0, right: 8.0),
  ),
),

.
.
.

//HTTP request Example
Future<List<ModelExample>> getData({name}) async {
  var response = await Dio().get(
    "https://5f24717b3b9d35001620456b.mockapi.io/user",
    queryParameters: {"name": name},
  );

  var result = ModelExample.fromJsonList(response.data);
  return result;
}
Custom Layout - Http:

From HTTP Request With Custom Layout

import 'package:easy_search/easy_search.dart';

EasySearch(
onSearch: (text) {
  print('Filter Query: $text');
  return getData(name: text);
},
searchResultSettings: SearchResultSettings(
  padding: EdgeInsets.only(left: 8.0, top: 8.0, right: 8.0),
),
customItemBuilder: (BuildContext context, ModelExample item, bool isSelected) {
  return Container(
    decoration: !isSelected
        ? null
        : BoxDecoration(
            border: Border.all(color: Theme.of(context).primaryColor),
            borderRadius: BorderRadius.circular(7),
            color: Colors.white,
          ),
    child: ListTile(
      selected: isSelected,
      title: Text(item.name),
      subtitle: Text(item.age.toString()),
      leading: Icon(Icons.people),
    ),
  );
},
),

.
.
.

//HTTP request Example
Future<List<ModelExample>> getData({name}) async {
  var response = await Dio().get(
    "https://5f24717b3b9d35001620456b.mockapi.io/user",
    queryParameters: {"name": name},
  );

  var result = ModelExample.fromJsonList(response.data);
  return result;
}
Multi Select Items - Http:

From HTTP Request With Custom Layout And Multi Select Items

import 'package:easy_search/easy_search.dart';

EasySearch(
multipleSelect: true,
onSearch: (text) {
  print('Filter Query: $text');
  return getData(name: text);
},
searchResultSettings: SearchResultSettings(
  padding: EdgeInsets.only(left: 8.0, top: 8.0, right: 8.0),
),
customItemBuilder: (BuildContext context, ModelExample item, bool isSelected) {
  return Container(
    decoration: !isSelected
        ? null
        : BoxDecoration(
            border: Border.all(color: Theme.of(context).primaryColor),
            borderRadius: BorderRadius.circular(7),
            color: Colors.white,
          ),
    child: ListTile(
      selected: isSelected,
      title: Text(item.name),
      subtitle: Text(item.age.toString()),
      leading: Icon(Icons.people),
    ),
  );
},
),

.
.
.

//HTTP request Example
Future<List<ModelExample>> getData({name}) async {
  var response = await Dio().get(
    "https://5f24717b3b9d35001620456b.mockapi.io/user",
    queryParameters: {"name": name},
  );

  var result = ModelExample.fromJsonList(response.data);
  return result;
}
Programmatically changing the Item List:

Programmatically changing the Item List

import 'package:easy_search/easy_search.dart';

EasySearch(
  onSearch: (text) {
    print('Filter Query: $text');
    return getData(name: text);
  },
  startWithValue: true,
  searchResultSettings: SearchResultSettings(
    padding: EdgeInsets.only(left: 8.0, top: 8.0, right: 8.0),
    label: LabelSettings.searchLabel(value: 'People'),
  ),
  filterPageSettings: FilterPageSettings(
    searchOnShow: false,
  ),
  controller: controllerStartWithValue,
),
Center(
  child: RaisedButton(
    onPressed: () {
      //1ª Create the new listToFill
      List<Item<ModelExample>> listToFill = [
        Item(ModelExample(name: 'ABC 123', age: 3), true),
        Item(ModelExample(name: 'ACB 132', age: 13), false),
        Item(ModelExample(name: 'BAC 213', age: 23), false),
        Item(ModelExample(name: 'BCA 231', age: 33), false),
        Item(ModelExample(name: 'CAB 312', age: 43), false),
        Item(ModelExample(name: 'CBA 321', age: 53), false),
      ];

      //2ª Update controller with new listToFill
      controllerStartWithValue.updateValues(listToFill);
    },
    child: Text('Changing list'),
  ),
),

Important About Models

For the search to work in an offline list, we need to implement the following items in your model or in your object's data class:

toString, equals and also hashcode

Here's how to do it
fromJsonList(List list) { if (list == null) return null; return list.map((item) => ModelExample.fromJson(item)).toList(); } //In this case I customized it so that the search returns everything that contains part of the name or age @override operator ==(object) => this.name.toLowerCase().contains(object.toLowerCase()) || this.age.toString().contains(object); @override int get hashCode => name.hashCode ^ age.hashCode; } ">
class ModelExample {
  final String name;
  final int age;

  ModelExample({this.name, this.age});

  @override
  String toString() {
    return '$name $age';
  }

  factory ModelExample.fromJson(Map<String, dynamic> json) {
    if (json == null) return null;
    return ModelExample(
      name: json["name"],
      age: json["age"],
    );
  }

  static List<ModelExample> fromJsonList(List list) {
    if (list == null) return null;
    return list.map((item) => ModelExample.fromJson(item)).toList();
  }
  
  //In this case I customized it so that the search returns everything that contains part of the name or age
  @override
  operator ==(object) => this.name.toLowerCase().contains(object.toLowerCase()) || this.age.toString().contains(object);
  
  @override
  int get hashCode => name.hashCode ^ age.hashCode;
}

Roadmap

This is our current roadmap. Please, feel free to request additions/changes.

Feature Progress
Offline List
Http Request Support
Widget Consume for ChangeNotifier
Widget consume for NotifierValue
Just one selected item
Multiple item selection
Search after last input
Cancel to keep old items
Remove items by touch
Nice layout default
Custom layout support
Progress on search request
Custom selected animation
Custom animated action buttons
Custom message when no data found
Custom theme colors
Many other customizations
Documentation - in progress 💔

Features and bugs

Please send feature requests and bugs at the issue tracker.

You might also like...

Create beautiful Loading and Timer buttons in Flutter

Create beautiful Loading and Timer buttons in Flutter

Argon Buttons (Timer and Loading) Create beautiful Loading and Timer buttons using Argon Buttons. No need to worry about handling animations or timers

Dec 11, 2022

Create beautiful flutter tags quickly and easily

Create beautiful flutter tags quickly and easily

flutter_tags Create beautiful tags quickly and easily. Installing Add this to your package's pubspec.yaml file: Null-safety version (Beta) MORE INFO d

Mar 4, 2022

A sliding up panel widget which can be used to show or hide content, beautiful and simple.

A sliding up panel widget which can be used to show or hide content, beautiful and simple.

flutter_sliding_up_panel A sliding up panel widget which can be used to show or hide content, beautiful and simple. demo Getting Started dependencies:

Dec 12, 2022

A beautiful circle color picker for flutter.

A beautiful circle color picker for flutter.

A beautiful circle color picker for flutter.

Dec 29, 2022

A Flutter package to show beautiful animated snackbars directly using overlay

A Flutter package to show beautiful animated snackbars directly using overlay

Easily show beautiful snack bars directly using overlays. Create custom snack bars and show them with awesome animations.

Dec 27, 2022

Sliding card is a highly customizable flutter package that will help you create beautiful Cards with a sliding animation effect.

Sliding Card Introduction Sliding card is a highly customizable flutter package that will help you create beautiful Cards with a sliding animation eff

Nov 4, 2022

Custom Flutter widgets that makes Checkbox and Radio Buttons much cleaner and easier.

Custom Flutter widgets that makes Checkbox and Radio Buttons much cleaner and easier.

custom_radio_grouped_button Custom Radio Buttons and Grouped Check Box Button Custom Flutter widgets that makes Checkbox and Radio Buttons much cleane

Sep 23, 2022

Custom widgets and utils using Flutter framework widgets and Dart language

reuse_widgets_and_utils The custom widgets and utils using Flutter framework widgets and Dart programming language. Getting Started This project is a

Oct 29, 2021

The SpannableGrid is a Flutter widget that allows its cells to span columns and rows and supports moving cells inside the grid.

The SpannableGrid is a Flutter widget that allows its cells to span columns and rows and supports moving cells inside the grid.

Spannable Grid The SpannableGrid is a Flutter widget that allows its cells to span columns and rows and supports moving cells inside the grid. Feature

Nov 7, 2022
Owner
Tiagosito
Mobile Software Engineer at IATec | Co-organizer at Flutterando https://flutterando.com.br/
Tiagosito
📓 Storyboard your components with Flutterbook. Develop, document, & test any kind of Flutter component.

Flutterbook A storyboarding tool to accelerate the development of Flutter widgets. Inspired by Storybook.js. The package is built to support Windows a

Philip Vu 25 Oct 7, 2022
React hooks for Flutter. Hooks are a new kind of object that manages a Widget life-cycles. They are used to increase code sharing between widgets and as a complete replacement for StatefulWidget.

English | Português Flutter Hooks A Flutter implementation of React hooks: https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889 Ho

Remi Rousselet 2.6k Dec 29, 2022
RoundedLoadingButton is a Flutter package with a simple implementation of an animated loading button, complete with success and error animations.

rounded_loading_button RoundedLoadingButton is a Flutter package with a simple implementation of an animated loading button, complete with success and

Chris Edgington 223 Jan 4, 2023
Flutter package: Easy and powerful internationalization using Dart extensions.

i18n_extension Non-boilerplate Translation and Internationalization (i18n) for Flutter Start with a widget with some text in it: Text("Hello, how are

Marcelo Glasberg 262 Dec 29, 2022
SKAlertDialog - A highly customizable, powerful and easy-to-use alert dialog for Flutter.

SKAlertDialog A highly customizable, powerful and easy-to-use alert dialog for Flutter. GIF Screenshots SKAlertDialog Basic Alert Alert with buttons A

Senthil_Kumar 7 May 18, 2022
PowerFileView - A powerful file view widget, support a variety of file types, such as Doc Eexcl PPT TXT PDF and so on, Android is implemented by Tencent X5, iOS is implemented by WKWebView.

PowerFileView - A powerful file view widget, support a variety of file types, such as Doc Eexcl PPT TXT PDF and so on, Android is implemented by Tencent X5, iOS is implemented by WKWebView.

Yao 8 Oct 22, 2022
The complete solution for Dart command-line interfaces

The complete solution for Dart command-line interfaces, inspired by node commander.js which created by tj.

Axetroy 6 Feb 21, 2020
Unofficial search provider for Medium for dart/flutter apps.

medium_search Unofficial search provider for Medium that can be used in dart or flutter apps. This library provides you an easy way to get search resu

Clone Conflict 1 Jan 10, 2022
Widget to let the user search through a keyword string typed on a customizable keyboard in a single or multiple choices list presented as a dropdown in a dialog box or a menu.

searchable_dropdown Widget to let the user search through a keyword string typed on a customizable keyboard in a single or multiple choices list prese

Bobby Stenly Irawan 108 Sep 11, 2022
A highly customizable multiple selection widget with search functionality.

A highly customizable multiple selection widget with search functionality.

null 5 Dec 19, 2022