Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Searchbar at the top of ListView #75

Closed
infacq opened this issue Oct 27, 2016 · 6 comments
Closed

Searchbar at the top of ListView #75

infacq opened this issue Oct 27, 2016 · 6 comments
Assignees

Comments

@infacq
Copy link

infacq commented Oct 27, 2016

How do I make a search bar when the page scroll to the top only. Thank you

@infacq
Copy link
Author

infacq commented Nov 4, 2016

actually I saw this behaviour on whatsapp app for ios. When user scroll down at the top of the page then the searchbar appear. How do I prepare such component

here is my ListView

class Products extends React.Component {
  constructor (props) {
    super(props)
    this._renderRow = this._renderRow.bind(this)
    this.state = {
      dataSource: [],
      search: null
    }
    this.api = API.create()
    (this: any).onSearchChange = this.onSearchChange.bind(this)
  }
  componentDidMount () {
    const { id } = this.props
    this.api.getList(id).then(result => {
       this.setState({
        dataSource: result.data.results
      })
    })
  }
  _renderRow (datas) {
    const cardViews =datas.map((rowData, i) => {
        return (
          <TouchableOpacity key={rowData.id+':'+i} onPress={() => { console.log('set') }}>
              <Image styleName="medium-wide" source={{ uri: rowData.image }}>
                <Tile>
                  <Subtitle styleName="md-gutter-bottom">{rowData.display_name}</Subtitle>
                </Tile>
              </Image>
          </TouchableOpacity>
        )
    })
    return (
      <GridRow columns={2}>
        {cardViews}
      </GridRow>
    )
  }
  onSearchChange (search) {
    this.setState({search})
  }
  _renderProducts(List) {
    const groupedList = GridRow.groupByRows(List, 2)
    return (
      <ListView data={ groupedList } stickyHeaderIndices={[0]} loading={true} renderRow={ this._renderRow } renderHeader={() => <ListViewSearchHeader onSearchChange={this.onSearchChange} search={this.state.search} />} />
    )
  }
  render () {
     return (
      <Screen style={{ marginTop: Metrics.navBarHeight }}>
        {this._renderProducts(this.state.dataSource)}
      </Screen>
    )
  }
}

and this is my searchbar

const SearchBar = ({search, onSearchChange}) => {
  const onChange = (text) => {
    onSearchChange(text)
  }
  return (
    <View style={styles.container}>
      <TextInput
        style={styles.input}
        placeholder="Search..."
        onChangeText={(text) => onChange(text)}
      />
    </View>
  )
}

now the searchbar will always appear and I still looking ways to filter data on the listview. Please help

@MrBr
Copy link
Contributor

MrBr commented Nov 4, 2016

ListView is always showing data you provide, so to show filtered results you have to provide filtered data.

In your case, when you enter search term you need to filter dataSource. You can filter data before grouping if you have search term (in _renderProducts).

  _renderProducts(List) {
    // You have to implement filterBySearchTerm
    const preparedList = this.state.search ? List.filter(filterBySearchTerm) : List;
    const groupedList = GridRow.groupByRows(preparedList, 2);
    return (
      <ListView data={ groupedList } stickyHeaderIndices={[0]} loading={true} renderRow={ this._renderRow } renderHeader={() => <ListViewSearchHeader onSearchChange={this.onSearchChange} search={this.state.search} />} />
    )
  }

Notes:

  • Think about debouncing onChangeText, you do not want to refresh state while still typing
  • Whenever you change ListView data reference ListView is going to rerender

@infacq
Copy link
Author

infacq commented Nov 5, 2016

thanks for the enlightment. but right now what I need is to hide the searchbar on initial appearance then only appear if user drag down the list. Here the similar issue facebook/react-native#1641

@ishsingh
Copy link

ishsingh commented Jan 4, 2017

@infacq Use autoHideHeader along with renderHeader method. This is how I am doing it:

<ListView autoHideHeader={true} data={this.state.data} loading={this.state.isLoading} onLoadMore={this.onEndReached} onRefresh={this.onSearchChanged} renderRow={this.renderRow} renderHeader={this.renderHeader} style={{backgroundColor: colors.black}} />
Then the renderHeader method looks like this.

renderHeader: function() { return ( <View> <SearchBar containerStyle={{backgroundColor : colors.black }} round onChangeText={(text) => this.setState({ search: text})} onSubmitEditing={this.onSearchChanged} placeholder='Type Here...'> </SearchBar> </View> ) }

@larafale
Copy link

larafale commented Jan 6, 2017

hello guys, i can't figure out how to clear the spinner when it's triggered by an onPress function (aka pull to refresh), any idea ?

@ishsingh
Copy link

ishsingh commented Jan 7, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants