Code Monkey home page Code Monkey logo

react-native-modal-filter-picker's Introduction

react-native-modal-filter-picker

npm Join the chat at https://discord.gg/bYt4tWB Follow on Twitter

Demo

A cross-platform (iOS, Android) modal picker for React Native.

Features:

  • Cross-platform (iOS, Android)
  • Default styling works well
  • Extensively customisable styling and rendering
  • Built-in search filter for long lists
  • Uses React Native FlatList for lazy-loading and high performance
  • Compatible with React Native 0.40+
  • Successfully used in production apps

Installation

Use NPM/Yarn to install package: react-native-modal-filter-picker

Usage

A basic demo:

import { Component, View, Text, TouchableOpacity } from 'react-native'

import ModalFilterPicker from 'react-native-modal-filter-picker'


export default class App extends Component {
  constructor (props, ctx) {
    super(props, ctx);

    this.state = {
      visible: false,
      picked: null,
    };
  }

  render() {
    const { visible, picked } = this.state;

    const options = [
      {
        key: 'kenya',
        label: 'Kenya',
      },
      {
        key: 'uganda',
        label: 'Uganda',
      },
      {
        key: 'libya',
        label: 'Libya',
      },
      {
        key: 'morocco',
        label: 'Morocco',
      },
      {
        key: 'estonia',
        label: 'Estonia',
      },
    ];

    return (
      <View style={styles.container}>
        <TouchableOpacity style={styles.buttonContainer} onPress={this.onShow}>
          <Text>Select country</Text>
        </TouchableOpacity>      
        <Text style={appStyles.label}>Selected:</Text>
        <Text>{picked}</Text>
        <ModalFilterPicker
          visible={visible}
          onSelect={this.onSelect}
          onCancel={this.onCancel}
          options={options}
        />
      </View>
    );
  }

  onShow = () => {
    this.setState({ visible: true });
  }

  onSelect = (picked) => {
    this.setState({
      picked: picked,
      visible: false
    })
  }

  onCancel = () => {
    this.setState({
      visible: false
    });
  }
}

Options

The following functionality props can be passed to the component:

Prop name Type Default Description
options Array of { key, label } (required) The options to display in the list
onSelect function (key) {} (required) Callback for when an option is chosen
onCancel function () {} (required) Callback for when the cancel button is pressed
placeholderText String "Filter..." Placeholder text for filter input text field
placeholderTextColor String "#ccc" Color of placeholder text for filter input text field
androidUnderlineColor String "rgba(0,0,0,0)" Android text underline color of filter input text field
cancelButtonText String "Cancel" Cancel button text
title String null Title text which appears above options list
noResultsText String "No matches" Text to show when there are no results for filter
visible Boolean true Whether to show modal or not. This allows you to control when the picker is shown and/or hidden.
showFilter Boolean true Whether to show filter text field field or not
modal Object null Options to pass to native Modal component
selectedOption String null The currently selected option, to visually differentiate it from others
flatListProps Object null Properties to pass to the rendered FlatList
renderOption function (option, isSelected) {} null Custom option renderer
renderList function () {} null Custom option list renderer
renderCancelButton function () {} null Custom cancel button renderer
keyboardShouldPersistTaps never/always/handle never Determines when the keyboard should stay visible after a tap. If never, tapping outside of the focused text input when the keyboard is up dismisses the keyboard. When this happens, children won't receive the tap. If always, the keyboard will not dismiss automatically, and the scroll view will not catch taps, but children of the scroll view can catch taps. If handled, the keyboard will not dismiss automatically when the tap was handled by a children, (or captured by an ancestor).
autoFocus Boolean false If true, focuses the input on componentDidMount().

In addition, the following styling props (each of which must be an Object consisting of styles) can be passed in:

Prop name Description
overlayStyle Style for the background modal overlay
listContainerStyle Style for the View wrapping the options list
filterTextInputContainerStyle Style for the View wrapping the filter input text field
filterTextInputStyle Style for the filter input text field
cancelContainerStyle Style for the View wrapping the cancel button
cancelButtonStyle Style for the cancel button button face
cancelButtonTextStyle Style for the cancel button text
titleTextStyle Style for the title text
optionTextStyle Style for the option text

Advanced filtering

By default the filter input field allows you to filter by the option label that's displayed on the screen.

But you can also attach a searchKey attribute to each option for the filtering algorithm to use. For example, we can allow the user to filter by continent as well as country name, even though we don't display the continent name:

render() {
  const { visible } = this.state;

  const options = [
    {
      key: 'kenya',
      label: 'Kenya',
      searchKey: 'Africa',
    },
    {
      key: 'uganda',
      label: 'Uganda',
      searchKey: 'Africa',
    },
    {
      key: 'libya',
      label: 'Libya',
      searchKey: 'Africa',
    },
    {
      key: 'japan',
      label: 'Japan',
      searchKey: 'Asia',
    },
    {
      key: 'estonia',
      label: 'Estonia',
      searchKey: 'Europe',
    },
  ];

  return (
    <View style={styles.container}>
      <ModalFilterPicker
        onSelect={this.onSelect}
        onCancel={this.onCancel}
        options={options}
      />
    </View>
  );
}

If you run the above example, you will be able to type africa into the filter input field to see all the countries within Africa.

Note: Filtering is case-insensitive

License

MIT

react-native-modal-filter-picker's People

Contributors

alann-sapone avatar hiddentao avatar jash90 avatar kajeevan025 avatar markhco avatar ryanphung avatar vitalii-tab 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

react-native-modal-filter-picker's Issues

Add keyboardShouldPersistTaps="always" to ListView

When the Keyboard is shown and you click on an list item, you have to click twice (once for the keyboard to disappear, and then the actual item click).
Adding keyboardShouldPersistTaps="always" fixes this. Can you add it to the ListView or maybe as an optional prop to ModalFilterPicker ?
Thanks

Changelog for 2.0.0

Hi

Is there a changelog somewhere? I would like to know what's new in the latest version 2.0.0. I tried to upgrade from 1.3.4, but it seems that the functionality has changed since the value selection is broken.

EDIT: It seems that ListView is removed in RN 0.62 and the old version of this library does not work anymore with it. So that is at least one thing that has been updated.

EDIT 2: It seems that previously onSelect returned the selected object, now it returns a map, in which the object exists behind key key. Why was this breaking change made? I think it would be important to document changes like these.

EDIT 3: Some changes are documented in the commit message: 57f3607 This is good, but I believe it would be important to have a separate changelog.md, which is written for the users of the library.

EDIT 4: I was able to solve my problem by not using the onSelect argument directly as before, but reading the key value first.

Lazy-loading autocomplete, loading options remotely based on query in filter

I want the user to choose an option in a list of millions of records and I don't want to load the millions of records in memory for obvious reasons. It would be great if there was a way to show matches based on an (async) external function. Possible solutions:

  • I'll keep options empty. A onFilterTextChange must be added, allowing me to populate options with matched fetched from a query I got from onFilterTextChange. Error and loading is added to show "Loading" or an error in the modal.
<ModalFilterPicker loading={loading} error={error} onFilterTextChange={(query) => loadOptions(query)} options={options} />

...

loadOptions(query) {
  this.setState({options: [], loading: true, error: null})
  this.optionsService.find(query)
    .then(options => this.setState({options, loading: false}))
    .catch(error => this.setState({options: [], error, loading: false})
}
  • The component accepts a function for options, that has 2 arguments: the query/filter, and a callback. Every time the filter is changed, the function is invoked. The callback must be called with the filtered options.
<ModalFilterPicker options={queryOptions} />

...

queryOptions(query, cb) {
  // the component will invoke this function, showing a Loading message
  // as long as the callback isn't called. The callback is called with either
  // an error (which is shown in red or something) or a list of options.
  this.optionsService.find(query).then(options => cb(null, options)).catch(err => cb(err));
}

Thoughts? PRs welcome? Any pointers/hints/guides?

Move filtering out of component

Hey. I came across your component.

I want to have list of items rendered via API, based on text input. To do that, I need to know filter in text input.

Your component doesn't lift this data up.

I'm just wondering, wouldn't it better to let user decide if he wants filtering, and let him implement that? It shouldn't be component's responsibility in my opinion.

You could just remove filter option, and lift up filter input text change.

Basic filtering is really easy to implement (it is also really low code cost), yet you won't be limiting user of your component.

Add an icon/image to each dropdown

It's not a bug, just a feature suggestion. Is it possible to add an icon to each element in the dropdown? If it's already possible, can you guide me on where to look?

Can not pick key and label inside onSelect

Right now inside onSelect callback I'm picking a key from my list and sending it to the API.

I want to be able to pick two values inside onSelect, key and value so I can show value inside the component and send key to API.

keyboard touch on IOS

In the search field the keyboard touch is not appearing on iOS, only on Android.
What is the solution?

tks

How to add margin for the search text in search window

I need to add some margin-left value for the search text. I am using the modal filter picker. But if I set margin value means it moving entire search box.
![Screenshot 2019-08-20 at 2 31 12 PM](https://user-
images.githubusercontent.com/36992338/63333737-886e1e80-c357-11e9-93b0-cec424ce824e.png)

  filterInputText: {
    height:36,
    fontSize: 14,
    color: '#ffffff',
    backgroundColor:'#A0A0A0',
  }

Any way to get text while typing?

Hi, thank you for the library. It serves almost everything that I need. Apart from two purposes. I need to know what the user is typing. Is there a method for that? I looked at the source code but could not find anything. However, I added my own method but still wanted to know if there is any method to know what the user is typing.
Second is that kindly replace listview with flatview or something similar as listview is deprecated.
Thank you in advance.

picker requires double tap, to open and to select a picker value

Hi hiddentao, I am using this component in my android app on production, it works fine, great work :). The issue I am facing is that the picker always requires double tap. Whether you need to open the picker, or you need to select a value, from the dropdown, we always need to tap twice, which makes it non-intuitive. It should work on single tap. Please inform if there is a solution to this or a workaround.

Custom filtering function

Is there a way I can customize the filtering function? I needed to adjust search filter to strictly start whichever been type on the search text. For example if you filter out text 'A' it should only return results starts with 'A'

Thanks

Component makes the app lag

Could there be a possible reason for why the modal picker lags a lot in the app?

Here is a snippet of the code :

                          <ModalFilterPicker
                                visible={visible}
                                onSelect={this.onSelect}
                                onCancel={this.onCancel}
                                options={this.state.categoryOption}
                                autoFocus={false}
                                selectedOption="#FFCC00"
                                overlayStyle = {styles.overlayStyle}
                                listContainerStyle = {styles.listContainerStyle}
                                optionTextStyle = {styles.optionTextStyle}
                                titleTextStyle = {styles.titleTextStyle}
                                optionTextStyle = {styles.optionTextStyle}
                                filterTextInputContainerStyle = {styles.filterTextInputContainerStyle}
                                cancelContainerStyle = {styles.cancelContainerStyle}
                                cancelButtonStyle = {styles.cancelButtonStyle}
                                cancelButtonTextStyle = {styles.cancelButtonTextStyle}
                            />

Custom styles should be added to what's already there

Right now, if you declare a custom style, it uses the object instead of adding it to the style that's already there.

For example, if I declare listContainerStyle={{ borderRadius: 10 } as a prop, now the only style is the borderRadius. All other styles are no longer applied.

how to set overlayStyle

I am trying like overlayStyle={green} but i know it is not the exact way, can you put an example here how to set it

Props for onSelect include the selected option instead of the selected key

The onSelect -callback should receive key: string instead of option: {key: string, label: string} according to your documentation. However, it still receives the option instead of the key. This results to typescript issues when trying to refer to the key as key.key and the label as key.label. Likewise, if trying to fix the props type to be the type of option, it says the props should be string, even while it actually is not.

Still maintained?

Since I got a ListView deprecation warning. Might want to consider using FlatList.

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.