Coder Social home page Coder Social logo

thealphamerc / flutter_plugin_filter_list Goto Github PK

View Code? Open in Web Editor NEW
196.0 9.0 66.0 4.18 MB

filterList is a flutter package which provide utility to search/filter data from provided dynamic list.

Home Page: https://pub.dev/packages/filter_list

License: BSD 2-Clause "Simplified" License

Swift 0.35% Objective-C 0.02% Dart 72.87% HTML 2.46% Kotlin 0.08% CMake 9.88% C++ 13.10% C 0.89% Shell 0.35%

flutter_plugin_filter_list's Introduction

filter_list

pub package Likes Popularity Pub points Hits GitHub stars GitHub forks

FilterList is a flutter package which provide utility to search/filter on the basis of single/multiple selection from provided dynamic list.

Download Demo App GitHub All Releases

Getting Started

  1. Add library to your pubspec.yaml
dependencies:
  filter_list: ^<latest_version>
  1. Import library in dart file
import 'package:filter_list/filter_list.dart';
  1. Create a list of Strings / dynamic object
class User {
  final String? name;
  final String? avatar;
  User({this.name, this.avatar});
}

List<User> userList = [
 User(name: "Jon", avatar: ""),
  User(name: "Lindsey ", avatar: ""),
  User(name: "Valarie ", avatar: ""),
  User(name: "Elyse ", avatar: ""),
  User(name: "Ethel ", avatar: ""),
  User(name: "Emelyan ", avatar: ""),
  User(name: "Catherine ", avatar: ""),
  User(name: "Stepanida  ", avatar: ""),
  User(name: "Carolina ", avatar: ""),
  User(name: "Nail  ", avatar: ""),
  User(name: "Kamil ", avatar: ""),
  User(name: "Mariana ", avatar: ""),
  User(name: "Katerina ", avatar: ""),
];

Filter list offer 3 ways to filter data from list

  • FilterListDialog
  • FilterListWidget
  • FilterListDelegate

Below is a example of using filter list widgets with minimal code however there is a lot more inside the widget for you to fully customize the widget.

How to use FilterListDialog

1. Create a function and call FilterListDialog.display

  void openFilterDialog() async {
    await FilterListDialog.display<User>(
      context,
      listData: userList,
      selectedListData: selectedUserList,
      choiceChipLabel: (user) => user!.name,
      validateSelectedItem: (list, val) => list!.contains(val),
      onItemSearch: (user, query) {
        return user.name!.toLowerCase().contains(query.toLowerCase());
      },
      onApplyButtonClick: (list) {
        setState(() {
          selectedUserList = List.from(list!);
        });
        Navigator.pop(context);
      },
    );
  }

If Apply button is pressed without making any selection it will return empty list of items.

2. Call openFilterDialog function on button tap to display filter dialog

@override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: openFilterDialog,
        child: Icon(Icons.add),
      ),
      body: selectedUserList == null || selectedUserList!.length == 0
          ? Center(child: Text('No user selected'))
          : ListView.builder(
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(selectedUserList![index].name!),
                );
              },
              itemCount: selectedUserList!.length,
            ),
    );
  }

How to use FilterListWidget.

class FilterPage extends StatelessWidget {
  const FilterPage({Key? key, this.selectedUserList})
      : super(key: key);
  final List<User>? selectedUserList;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FilterListWidget<User>(
        listData: userList,
        selectedListData: selectedUserList,
        onApplyButtonClick: (list) {
          // do something with list ..
        },
        choiceChipLabel: (item) {
          /// Used to display text on chip
          return item!.name;
        },
        validateSelectedItem: (list, val) {
          ///  identify if item is selected or not
          return list!.contains(val);
        },
        onItemSearch: (user, query) {
          /// When search query change in search bar then this method will be called
          ///
          /// Check if items contains query
          return user.name!.toLowerCase().contains(query.toLowerCase());
        },
      ),
    );
  }
}

How to use FilterListDelegate.

Create a function and call FilterListDelegate.open() on button tap.

 void openFilterDelegate() async {
   await FilterListDelegate.open<User>(
      context: context,
      list: userList,
      onItemSearch: (user, query) {
        return user.name!.toLowerCase().contains(query.toLowerCase());
      },
      tileLabel: (user) => user!.name,
      emptySearchChild: Center(child: Text('No user found')),
      searchFieldHint: 'Search Here..',
      onApplyButtonClick: (list) {
        // Do something with selected list
      },
    );
  }

Screenshots

Empty screen FilterListDialog Selected chip Result from dialog

Customized Dialog Header

Customized Choice chip

FilterListWidget

Default Customized customized

FilterListDelegate

Single selection Multiple selection Multiple selection
Search through list Customized Tile

Parameters

Parameter Type Description
height double Set height of filter dialog.
width double Set width of filter dialog.
hideCloseIcon bool Hide close Icon.
hideHeader bool Hide complete header section from filter dialog.
headerCloseIcon Widget Widget to close the dialog.
hideSelectedTextCount bool Hide selected text count.
enableOnlySingleSelection bool Enable only single selection
maximumSelectionLength int Set maximum selection length.
hideSearchField bool Hide search text field.
headlineText String Set header text of filter dialog.
backgroundColor Color Set background color of filter color
listData List<T>() Populate filter dialog with text list.
selectedListData List<T>() Marked selected text in filter dialog.
choiceChipLabel String Function(T item) Display text on choice chip.
validateSelectedItem bool Function(List<T>? list, T item) Identifies weather a item is selected or not
onItemSearch List<T> Function(List<T>? list, String text) Perform search operation and returns filtered list
choiceChipBuilder Widget Function(BuildContext context, T? item, bool? isSelected) The choiceChipBuilder is a builder to design custom choice chip.
onApplyButtonClick Function(List<T> list) Returns list of items when apply button is clicked
validateRemoveItem List<T> Function(List<T>? list, T item) Function Delegate responsible for delete item from list
resetButtonText String Reset button text to customize or translate
allButtonText String All button text to customize or translate
selectedItemsText String Selected items text to customize or translate
controlButtons List<ControlButtonType> configure which control button needs to be display on bottom of dialog along with 'Apply' button.
insetPadding EdgeInsets The amount of padding added to the outside of the dialog.
themeData FilterListThemeData Configure theme of filter dialog and widget.
choiceChipTheme ChoiceChipThemeData Configure theme of choice chip.
controlButtonBarTheme ControlButtonBarThemeData Configure theme of control button bar
controlButtonTheme ControlButtonThemeData Configure theme of control button.
headerTheme HeaderThemeData Configure theme of filter header.

T can be a String or any user defined Model

Other Flutter packages

Name Stars Pub
Empty widget GitHub stars pub package
Add Thumbnail GitHub stars pub package
Country Provider GitHub stars pub package

Pull Requests

I welcome and encourage all pull requests. It usually will take me within 24-48 hours to respond to any issue or request.

Created & Maintained By

Sonu Sharma (Twitter) (Youtube) (Insta) Twitter Follow

If you found this project helpful or you learned something from the source code and want to thank me, consider buying me a cup of ☕

Visitors Count

Loading

flutter_plugin_filter_list's People

Contributors

dannystrelok avatar itsoftware37 avatar sm-shifat avatar svegiary avatar thealphamerc 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

flutter_plugin_filter_list's Issues

Add paging or scroll controller

** Is your feature request related to a problem? Please describe.
Currently, the library lacks efficient support for handling large datasets or long lists, leading to potential performance issues and user frustration. Scrolling through extensive content or implementing pagination without a dedicated controller can result in suboptimal user experiences.

** Describe the solution you'd like
I propose the addition of a paging or scroll controller to the library. This controller would manage the loading and display of content in a more organized and performance-friendly manner. With this feature, users could smoothly navigate through large datasets or lengthy lists, enhancing the overall user experience.

** Describe alternatives you've considered

Manual Implementation: Users could manually implement their own pagination or scrolling logic, but this approach is prone to errors, increases development time, and may result in inconsistent experiences across different implementations.

** Additional context
To illustrate the need for this feature, consider scenarios where the library is used in applications dealing with extensive data, such as social media feeds, image galleries, or news articles. The addition of a paging or scroll controller would significantly improve the library's versatility and performance in handling such cases.

Selected chip color

selectedTextBackgroundColor Feature unavailable in 0.0.8 update
How can change the selected chips color ??

Filter By date

Add Filter By Date feature If Exist
In Between range of Start and End dates

Selected Text Count on bottom.

Is your feature request related to a problem? Please describe.
For me it is too much space, i would like the chips directly under the name and in the same time display how many are selected.

Make an option to display "selectedItemsCountOnBottom" boolean.

Screenshot 2022-12-05 at 10 19 18

How to Add subtitle

**as the library support single item in choiceChipLabel **
how to add subtitle in choiceChipLabel if data has subtitle [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Maximum selectable Chips

Hello,

it will be great to get control of a maximum amount of selectable Chips. Like the [maxLength] propertie in TextFields.

Null check operator used on a null value

Describe the bug
A clear and concise description of what the bug is.

    await FilterListDialog.display<T>(
      this,
      listData: data,
      choiceChipLabel: (T? data) => titleBuilder?.call(data),
      validateSelectedItem: selectedDataValidator,
      onItemSearch: (T data, String query) =>
          searchComparator?.call(data, query) ??
          titleBuilder
              ?.call(data)
              ?.toLowerCase()
              .contains(query.toLowerCase()) ??
          false,
      hideSelectedTextCount: true,
      hideSearchField: true,
      allButtonText: MaterialLocalizations.of(this).selectAllButtonLabel,
      resetButtonText: 'reset'.translateAction(),
      applyButtonText: MaterialLocalizations.of(this).saveButtonLabel,
      onApplyButtonClick: (List<T>? data) => _completer.complete(data),
    );


======== Exception caught by gesture ===============================================================
The following _CastError was thrown while handling a gesture:
Null check operator used on a null value

When the exception was thrown, this was the stack: 
#0      FilterState.addSelectedItem (package:filter_list/src/state/filter_state.dart:46:18)
#1      ChoiceList._buildChoiceList.<anonymous closure>.<anonymous closure> (package:filter_list/src/widget/choice_list.dart:52:25)
#2      _RawChipState._handleTap (package:flutter/src/material/chip.dart:1716:24)
#3      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:989:21)
#4      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:198:24)
#5      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:608:11)
#6      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:296:5)
#7      BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:267:7)
#8      GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:157:27)
#9      GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:443:20)
#10     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:419:22)
#11     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:322:11)
#12     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:374:7)
#13     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:338:5)
#14     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:296:7)
#15     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:279:7)
#19     _invoke1 (dart:ui/hooks.dart:170:10)
#20     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:331:7)
#21     _dispatchPointerDataPacket (dart:ui/hooks.dart:94:31)
(elided 3 frames from dart:async)
Handler: "onTap"
Recognizer: TapGestureRecognizer#f56cc
  debugOwner: GestureDetector
  state: ready
  won arena
  finalPosition: Offset(153.4, 286.0)
  finalLocalPosition: Offset(34.2, 16.0)
  button: 1
  sent tap down
====================================================================================================

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

 // Add item in to selected list
  void addSelectedItem(K item) {
    _selctedItems!.add(item); // _selctedItems wasn't initialized

    notifyListeners();
  }

  // Remove item from selected list
  void removeSelectedItem(K item) {
    _selctedItems!.remove(item);

    notifyListeners();
  }

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

Search filter doesn't work after empty list

Describe the bug
When you use the search textfield to filter the list, if you reach a dead end and your keyword doesn't correspond to items.
You then have to delete the whole keyword instead of just fixing your keyword typo in order to get the filter to work again.

for example:

List:

  • yorkshire
  • bulldog

if your keyword is "yorf": result is 0 items
then if you fix the keyword to "yor": result is still 0 items
until the you clear all the text and type "y": result 1 item

To Reproduce
Steps to reproduce the behavior:

Create a list and use search filters on it

Expected behavior
expected to have the keyword filter fire for each change in textfield

Customise close button on a dialog

Is your feature request related to a problem? Please describe.
It would be good to add option to customise close button appearance in order to make it consistent with the rest of application. There is already an option to customise close icon color, however it's not currently possible to change the icon itself.

Describe the solution you'd like
A builder for delivering the button would be perfect.

Remove bottom Bar Or just remove Apply button.

i just don't want the apply button but i cant get rid of it.

The most easy way is just inculde the apply button in the "controlButtons" list.

Or just remove the whole bar together because i dont want any buttons.

Screenshot 2022-12-05 at 10 19 18

How do I trigger the removeSelectedItem(item) method in a sibling of the FilterListWidget component on the same page and refresh the FilterListWidget

How do I trigger the removeSelectedItem(item) method in a sibling of the FilterListWidget component on the same page and refresh the FilterListWidget

image
  textfield_tags: ^2.0.2
  #filter_list: ^1.0.2
  filter_list:
    path: plugin/flutter_plugin_filter_list

page_view.dart

import 'package:filter_list/filter_list.dart';
import 'package:fluent_ui/fluent_ui.dart' as fl;
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:imboy/component/helper/list.dart';
import 'package:imboy/component/ui/common_bar.dart';
import 'package:imboy/component/ui/tag.dart';
import 'package:imboy/config/const.dart';
import 'package:niku/namespace.dart' as n;
import 'package:textfield_tags/textfield_tags.dart';

import 'tag_add_logic.dart';

// ignore: must_be_immutable
class TagAddPage extends StatelessWidget {
  final String peerId; // 用户ID

  String peerTag;
  final Color tagBackgroundColor;
  final Color tagSelectedBackgroundColor;

  TagAddPage({
    super.key,
    required this.peerId,
    required this.peerTag,
    this.tagBackgroundColor = const Color(0xfff8f8f8),
    this.tagSelectedBackgroundColor = const Color(0xFF649BEC),
  });

  @override
  Widget build(BuildContext context) {
    final logic = Get.put(TagAddLogic());
    final state = Get.find<TagAddLogic>().state;
    state.tagItems.value =
        peerTag.split(',').where((o) => o.trim().isNotEmpty).toList();
    for (var item in state.tagItems) {
      if (!state.recentTagItems.contains(item)) {
        state.recentTagItems.add(item);
      }
    }
    state.tagController.addListener(() {
      bool diff =
          listDiff(state.tagItems.toList(), state.tagController.getTags);
      state.tagItems.value = state.tagController.getTags!;
      // state.tagController.setError = '';
      // debugPrint(
      //     "tag_add_view_tagsController_addListener $diff tagItems ${state.tagItems.value.toList().toString()}");
      // debugPrint(
      //     "tag_add_view_tagsController_addListener $diff getTags ${state.tagController.getTags.toString()}");
      logic.valueOnChange(diff);
      if (diff) {
        state.tagController.setError = '需要确认提交,该操作才生效'.tr;
      }
    });
    return Scaffold(
      backgroundColor: AppColors.ChatBg,
      // backgroundColor: Colors.white,
      appBar: PageAppBar(
        titleWidget: n.Row(
          [
            Expanded(
              child: Text(
                '添加标签'.tr,
                textAlign: TextAlign.center,
                style: const TextStyle(
                  fontSize: 16.0,
                  fontWeight: FontWeight.bold,
                ),
              ),
              // 中间用Expanded控件
            ),
            ElevatedButton(
              onPressed: () async {
                //
              },
              // ignore: sort_child_properties_last
              child: Text(
                '新建'.tr,
                textAlign: TextAlign.center,
              ),
              style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all<Color>(
                  // AppColors.primaryElement,
                  tagSelectedBackgroundColor,
                ),
                foregroundColor: MaterialStateProperty.all<Color>(
                  Colors.white,
                ),
                minimumSize: MaterialStateProperty.all(const Size(60, 40)),
                visualDensity: VisualDensity.compact,
                padding: MaterialStateProperty.all(EdgeInsets.zero),
              ),
            ),
          ],
        ),
      ),
      body: fl.FluentTheme(
        data: fl.FluentThemeData(),
        child: n.Padding(
          left: 12,
          top: 12,
          right: 12,
          child: n.Column(
            [
              TextFieldTags(
                // key: Key('TextFieldTags'),
                // textEditingController: ,
                // focusNode: tfn,
                textfieldTagsController: state.tagController,
                initialTags: state.tagItems,
                textSeparators: const [' ', ','],
                // textSeparators: const [','],
                letterCase: LetterCase.normal,
                validator: (String tag) {
                  bool diff =
                      listDiff(state.tagItems, state.tagController.getTags);
                  debugPrint(
                      "tag_add_view_validator diff $diff, $tag, len:${tag.length}");
                  logic.valueOnChange(diff);
                  if (tag.length > 14) {
                    // 最最最最最最最最最最最最最最1
                    return '最多14个字'.tr;
                  }
                  if (state.tagController.getTags != null &&
                      state.tagController.getTags!.contains(tag)) {
                    // return 'you already entered that';
                    return '你已经输入过了'.tr;
                  }
                  return null;
                },

                inputfieldBuilder: (context, tecController, fn, error,
                    onChanged, onSubmitted) {
                  return ((context, scController, tags, onTagDelete) {
                    return Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 10.0),
                      child: TextField(
                        controller: tecController,
                        focusNode: fn,
                        decoration: InputDecoration(
                          border: UnderlineInputBorder(
                            borderSide: BorderSide(
                                color: tagSelectedBackgroundColor, width: 1.0),
                          ),
                          focusedBorder: UnderlineInputBorder(
                            borderSide: BorderSide(
                                color: tagSelectedBackgroundColor, width: 1.0),
                          ),
                          // helperText: '全部标签'.tr,
                          helperStyle: TextStyle(
                            color: tagSelectedBackgroundColor,
                          ),
                          hintText:
                              state.tagController.hasTags ? '' : '选择或输入标签'.tr,
                          errorText: error,
                          prefixIconConstraints: BoxConstraints(
                              maxWidth: state.distanceToField * 1.0),
                          prefixIcon: tags.isNotEmpty
                              ? SingleChildScrollView(
                                  controller: scController,
                                  scrollDirection: Axis.horizontal,
                                  child: n.Row(tags.map((String tag) {
                                    return TagItem(
                                      tag: tag,
                                      onTagDelete: (String tag) {
                                        debugPrint(
                                            "tag_add_page_onTagDelete $tag");
                                        onTagDelete(tag);
                                        // Get.find<FilterState>().removeSelectedItem(tag);
                                        // final state = StateProvider.of<FilterState<String>>(context);
                                        // state.removeSelectedItem(tag);
                                      },
                                      backgroundColor: tagBackgroundColor,
                                      selectedBackgroundColor:
                                          tagSelectedBackgroundColor,
                                    );
                                  }).toList()),
                                )
                              : null,
                        ),
                        onChanged: onChanged,
                        onSubmitted: onSubmitted,
                      ),
                    );
                  });
                },
              ),
              n.Padding(
                top: 10,
                child: fl.SizedBox(
                  height: Get.height - 160,
                  child: FilterListWidget<String>(
                    resetButtonText: '置空'.tr,
                    applyButtonText: '确认'.tr,
                    hideHeader: true,
                    enableOnlySingleSelection: false,
                    listData: state.recentTagItems,
                    selectedListData: state.tagItems,
                    controlButtons: const [ControlButtonType.Reset],
                    themeData: FilterListThemeData(
                      context,
                      backgroundColor: AppColors.ChatBg,
                      choiceChipTheme: ChoiceChipThemeData(
                        backgroundColor: tagBackgroundColor,
                        selectedBackgroundColor: tagSelectedBackgroundColor,
                      ),
                    ),
                    onApplyButtonClick: (list) async {
                      List<String>? tag =
                          state.tagController.getTags?.toSet().toList();
                      // state.tagController.getTags = tag?.toList();
                      debugPrint(
                          "submit_tag ${tag?.length} ${tag.toString()}, ");
                      bool res = await logic.add(peerId, tag ?? []);
                      if (res) {
                        // EasyLoading.showSuccess('操作成功'.tr);
                        Get.back(result: tag!.join(','));
                      }
                    },
                    choiceChipLabel: (item) {
                      /// Used to display text on chip

                      debugPrint(
                          "tag_add_page_choiceChipLabel $item, ${state.tagItems.contains(item)}");
                      return item;
                    },
                    validateSelectedItem: (list, val) {
                      ///  identify if item is selected or not
                      debugPrint(
                          "tag_add_page_validateSelectedItem $val, ${list!.contains(val)}, ${list.toString()}");
                      // if (list.contains(val)) {
                      //   state.tagController.addTag = val;
                      // }

                      return list.contains(val);
                    },
                    onReset: () {
                      state.tagController.clearTags();

                      state.tagController.setError = '需要确认提交,该操作才生效'.tr;
                      debugPrint(
                          "tag_add_page_onReset ${state.tagController.getTags?.length}");

                      /// When search query change in search bar then this method will be called
                      ///
                      // return true;
                    },
                    onSelected: (String item, bool selected) {
                      if (selected) {
                        state.tagController.addTag = item;
                      } else {
                        state.tagController.removeTag = item;
                        state.tagItems.value = state.tagController.getTags!;
                      }
                      // debugPrint("tag_add_page_onSelected $selected, $item, index $index");
                      state.tagController.notifyListeners();
                    },
                  ),
                ),
              ),
            ],
            // 内容文本左对齐
            crossAxisAlignment: CrossAxisAlignment.start,
          ),
        ),
      ),
    );
  }
}

Support creation

Is your feature request related to a problem? Please describe.
When adding for example labels using this control, to be able to create item, not only select from existing.

Describe the solution you'd like
Type name of Chip item, and press Enter (or button) to create.

Describe alternatives you've considered
n/a

Additional context
n/a

Option to Remove The Shadow in FilterList Content Area

Is your feature request related to a problem? Please describe.
Currently Filterlist does have default shadow in Content Area That doesn't Go with My Apps Design Language, Please have an Option to Disable That

Describe the solution you'd like
Add Boolean to Turn that Default Shadow ON and OFF, for ex HideContentAreaShadow

Additional context

Here's Image that represent Default Shadow on Content Area

Inkedscreenshot_6

FilterListDelegateThemeData does not apply changed theme data

FilterListDelegate single selection text color cannot be changed from the default black.
I tried styling the text using FilterListDelegateThemeData but the theme changes aren't applied.
Am i supposed to style the list text in a different way??

[Question] Change title apply button & title search

is there anything to do to change the title on apply button FilterListDelegate.show...

image
based on that pict, it's only available to change applybuttonstyle, how to change applybuttontitle ?

also

image
how to rename label search as an example I want to change from Search here.. to Maghanap dito..
image

thanks,

Disabling "All" and "Reset" buttons

Is your feature request related to a problem? Please describe.
It would be very nice to be able to remove the "all" and "reset" buttons.

Describe the solution you'd like
A parameter in the constructor to allow you to remove the "all" and "reset" buttons if desired. If removed, the "Accept" button should be the only one remaining and could be automatically centred to the bottom middle.

Describe alternatives you've considered
I have tried removing the text from the button (using "resetButtonText" and "allButtonText"), but it's still showing the buttons. Maybe giving an empty string ("") could disable it.

Additional context
I am using the widget as a tag selector while in the creation of elements for my app, and it makes no sense to have the "all" button, I wouldn't want the users to set all the tags to a new element, usually they should add only 2-3.

[Bug] FilterListDelegate bug when select item

Describe the bug
In FilterListDelegate mode, when I select the item, the item that is not visible is already selected (usually on the 2nd attempt). however when i click on the search box the item shows as selected.

To Reproduce
Steps to reproduce the behavior:

  1. Select item -> not show selected (usually on the 2nd attempt).
  2. Click on the search box -> show selected.

Expected behavior
Item show selected when select.

Screenshots
Bug

Smartphone

  • Device: [Samsung M51]
  • OS: [Android 12]

Multiple Chips with Same Value

Describe the bug
Using this plugin I am trying to group results based on locations, but for every repeated Location the plugin treats it as a different entity, hence shows a different chip for the same.

To Reproduce
Steps to reproduce the behavior:
A list with objects having fields : id (string: unique), name: (string: unique), location (string: repeated).
I want to use the filter on location.

Expected behavior
The plugin should group all location objects together and show the result

Screenshots
image

Additional context
The example App provided does not have repeated values in the array, is this the default behavior of the plugin.
If there is anyway I can group similar objects together using this plugin then help me out.

[Question] FilterListDialog.display is missing i18n parameters for "searchFieldHintText"

I am using your package and it is awesome. Thank you a lot for it :)

Actually, in the Code documentation I can see that it should be possible to set a string for the searchFieldHintText:
grafik

But when I initialize the Dialog with FilterListDialog there is no possibility to set the string. Actually the search string is still showing up in english language.
grafik

Will be there a fix?

Boa noite!

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

Error: Type 'ListTileThemeData' not found - When compiling on Macos

Describe the bug
Failed to compile this library on macos (m1) Monterey 12.0.1
Here are the errors I get when I use this library, but when I comment out the usage its working just fine.

Launching lib/main.dart on Chrome in debug mode...
Waiting for connection from debug service on Chrome...
../../Downloads/flutter/.pub-cache/hosted/pub.dartlang.org/filter_list-1.0.1/lib/src/theme/filter_list_delegate_theme.dart:37:5: Error: Type 'ListTileThemeData' not found.
    ListTileThemeData? listTileTheme,
    ^^^^^^^^^^^^^^^^^
../../Downloads/flutter/.pub-cache/hosted/pub.dartlang.org/filter_list-1.0.1/lib/src/theme/filter_list_delegate_theme.dart:84:9: Error: Type 'ListTileThemeData' not found.
  final ListTileThemeData listTileTheme;
        ^^^^^^^^^^^^^^^^^
../../Downloads/flutter/.pub-cache/hosted/pub.dartlang.org/filter_list-1.0.1/lib/src/filter_list_delegate.dart:252:27: Error: No named parameter with the name 'data'.
                          data: theme.listTileTheme,
                          ^^^^
../../Downloads/flutter/packages/flutter/lib/src/material/list_tile.dart:44:9: Context: Found this candidate, but the arguments don't match.
  const ListTileTheme({
        ^^^^^^^^^^^^^
../../Downloads/flutter/.pub-cache/hosted/pub.dartlang.org/filter_list-1.0.1/lib/src/filter_list_delegate.dart:260:27: Error: No named parameter with the name 'data'.
                          data: theme.listTileTheme,
                          ^^^^
../../Downloads/flutter/packages/flutter/lib/src/material/list_tile.dart:44:9: Context: Found this candidate, but the arguments don't match.
  const ListTileTheme({
        ^^^^^^^^^^^^^
../../Downloads/flutter/.pub-cache/hosted/pub.dartlang.org/filter_list-1.0.1/lib/src/theme/filter_list_delegate_theme.dart:37:5: Error: 'ListTileThemeData' isn't a type.
    ListTileThemeData? listTileTheme,
    ^^^^^^^^^^^^^^^^^
../../Downloads/flutter/.pub-cache/hosted/pub.dartlang.org/filter_list-1.0.1/lib/src/theme/filter_list_delegate_theme.dart:51:23: Error: Method not found: 'ListTileThemeData'.
    listTileTheme ??= ListTileThemeData();
                      ^^^^^^^^^^^^^^^^^
../../Downloads/flutter/.pub-cache/hosted/pub.dartlang.org/filter_list-1.0.1/lib/src/theme/filter_list_delegate_theme.dart:84:9: Error: 'ListTileThemeData' isn't a type.
  final ListTileThemeData listTileTheme;
        ^^^^^^^^^^^^^^^^^
../../Downloads/flutter/.pub-cache/hosted/pub.dartlang.org/filter_list-1.0.1/lib/src/theme/filter_list_delegate_theme.dart:97:33: Error: 'ListTileThemeData' isn't a type.
      ..add(DiagnosticsProperty<ListTileThemeData>(
                                ^^^^^^^^^^^^^^^^^
../../Downloads/flutter/.pub-cache/hosted/pub.dartlang.org/filter_list-1.0.1/lib/src/theme/filter_list_delegate_theme.dart:102:33: Error: 'ListTileThemeData' isn't a type.
      ..add(DiagnosticsProperty<ListTileThemeData>(
                                ^^^^^^^^^^^^^^^^^

To Reproduce
Steps to reproduce the behavior:

  1. Here is my only usage of it in my app
await FilterListDialog.display<RequestDBModel>(
      context,
      listData: distinctRequests,
      selectedListData: selectedRequests,
      choiceChipLabel: getFilteredFieldAsString,
      validateSelectedItem: (list, val) => list!.contains(val),
      onItemSearch: (request, query) {
        return getFilteredFieldAsString(request)
            .toLowerCase()
            .contains(query.toLowerCase());
      },
      selectedItemsText:
          AppDynamicLocalizations.of(context)?.translate("selecteditems") ??
              'selected items',
      allButtonText:
          AppDynamicLocalizations.of(context)?.translate("all") ?? 'All',
      applyButtonText:
          AppDynamicLocalizations.of(context)?.translate("apply") ?? 'Apply',
      resetButtonText:
          AppDynamicLocalizations.of(context)?.translate("reset") ?? 'Reset',
      onApplyButtonClick: (list) {
        setState(() {
          filtersByColumn[columnIndex] = [];
          if (list?.length != distinctRequests.length) {
            // If actually choose all(no need to filter it at all)
            list?.forEach((request) {
              filtersByColumn[columnIndex]
                  .add(getFilteredFieldAsString(request));
            });
          }
        });
        Navigator.pop(context);
      },
    );

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: macos (m1) Monterey 12.0.1 (On windows it works great)
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: Compiled to web
  • Browser chrome

Merging Duplicate Items in Choice Chip into 1

Is your feature request related to a problem? Please describe.

currently, If we have duplicates in the choice chip, filter list still shows the duplicate.

Describe the solution you'd like

it would be great if we have option to merge duplicate items into 1.

[Question] initial selected

at initstate I've done to add selectedlistdate

but when i clicked the filter list, the filterlistdelegate not giving the checklist.

image

am i wrong to write below code ?
image

btw ive logs the list that i input into the selectedlist.
it show, but only at the filterlistdelegate that not giving the checklist

Flutter upgrade to 3.22 and Getting Error for TextTheme Caption.

/C:/Users/xxx/AppData/Local/Pub/Cache/hosted/pub.dev/filter_list-1.0.2/lib/src/filter_list_widget.dart:193:58: Error: The getter 'caption' isn't defined for the class 'TextTheme'.

  • 'TextTheme' is from 'package:flutter/src/material/text_theme.dart' ('/D:/flutter/packages/flutter/lib/src/material/text_theme.dart').
    Try correcting the name to the name of an existing getter, or defining a getter or field named 'caption'.
    style: Theme.of(context).textTheme.caption,
    ^^^^^^^
    Target kernel_snapshot failed: Exception

After upgrading to Flutter 3.22.
Getting textTheme.caption error when compiling.

Apply button overflow on the right

Hey mate,

Thanks for this lib, made my life super easy as I'm just mocking up something which needs a filter.
I am getting some overflow reporting on the apply button.
"A RenderFlex overflowed by 234 pixels on the right."

I am on an Android Moto g6,
I can fix it for my case by setting the width, but I'm hesitant to use that to resolve it for a real multi platform / device experience.

Maybe id like to do something like setting the margin myself, or enabling the text to auto scale to the device I am on?

image

Thanks again!

Select only one option [feature]

hey there ,
the package is all good , thanks for that,
i was hoping if you can add one more feature that would be great help
--------------The Feature----------------
the user can select the multiple options right
can you add something like the user can select only one option
when he tries to select other option then other option should be automatically deselected
---basically user can select only one option-------

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.