tableflip / react-native-select-multiple

☑️ A customiseable FlatList that allows you to select multiple rows
ISC License
191 stars 62 forks source link

FlatList component of react native as ListView is now deprecated #24

Closed sudhirkumarojhaa closed 5 years ago

sudhirkumarojhaa commented 6 years ago

Also If there is any possibility to provide the search functionality so that it's easier for the user when the list is long.

Thanks

sudhirkumarojhaa commented 6 years ago

import React, { Component } from 'react' import PropTypes from 'prop-types'

import { View, FlatList, ListView, Text, TouchableWithoutFeedback, Image } from 'react-native'; import styles from './SelectMultiple.styles' import checkbox from '../images/icon-checkbox.png' import checkboxChecked from '../images/icon-checkbox-checked.png' import { mergeStyles } from './style'

const itemType = PropTypes.oneOfType([ PropTypes.string, PropTypes.shape({ label: PropTypes.any, value: PropTypes.any }) ])

const styleType = PropTypes.oneOfType([ PropTypes.object, PropTypes.number, PropTypes.array ])

const sourceType = PropTypes.oneOfType([PropTypes.object, PropTypes.number])

// A customiseable ListView that allows you to select multiple rows export default class SelectMultiple extends Component { static propTypes = { items: PropTypes.arrayOf(itemType).isRequired, selectedItems: PropTypes.arrayOf(itemType), onSelectionsChange: PropTypes.func.isRequired, checkboxSource: sourceType, selectedCheckboxSource: sourceType, renderLabel: PropTypes.func, listViewProps: PropTypes.any, style: styleType, rowStyle: styleType, checkboxStyle: styleType, labelStyle: styleType, selectedRowStyle: styleType, selectedCheckboxStyle: styleType, selectedLabelStyle: styleType }

static defaultProps = { selectedItems: [], style: {}, rowStyle: {}, checkboxStyle: {}, checkboxCheckedStyle: {}, labelStyle: {}, checkboxSource: checkbox, selectedCheckboxSource: checkboxChecked, renderLabel: null }

constructor (props) { super(props)

const rows = this.getRowData(props)

const dataSource = new ListView.DataSource({
  rowHasChanged: (r1, r2) => r1.value !== r2.value || r1.selected !== r2.selected
}).cloneWithRows(rows)

this.state = { dataSource: rows }

}

componentWillReceiveProps (nextProps) { const rows = this.getRowData(nextProps) this.setState({ dataSource: rows }); }

getRowData ({ items, selectedItems }) { items = items.map(this.toLabelValueObject) selectedItems = (selectedItems || []).map(this.toLabelValueObject)

items.forEach((item) => {
  item.selected = selectedItems.some((i) => i.value === item.value)
})

return items

}

onRowPress (row) { const { label, value } = row let { selectedItems } = this.props

selectedItems = (selectedItems || []).map(this.toLabelValueObject)

const index = selectedItems.findIndex((selectedItem) => selectedItem.value === value)

if (index > -1) {
  selectedItems = selectedItems.filter((selectedItem) => selectedItem.value !== value)

} else {
  selectedItems = selectedItems.concat({ label, value })
}
this.props.onSelectionsChange(selectedItems, { label, value })

}

toLabelValueObject (obj) { if (Object.prototype.toString.call(obj) === '[object String]') { return { label: obj, value: obj }

} else {
  return { label: obj.label, value: obj.value }
}

}

keyExtractor = (item, index) => index

render () { const { dataSource } = this.state const { style, listViewProps, items } = this.props return <FlatList style={style} keyExtractor={this.keyExtractor} data={dataSource} renderItem={this.renderItemRow} {...listViewProps} /> }

renderLabel = (label, style, selected) => { if (this.props.renderLabel) { return this.props.renderLabel(label, style, selected) } return (

{label}
)

}

renderItemRow = (row) => { let { checkboxSource, rowStyle, labelStyle, checkboxStyle } = this.props

const {
  selectedCheckboxSource,
  selectedRowStyle,
  selectedCheckboxStyle,
  selectedLabelStyle
} = this.props

 if (row.item.selected) {
  checkboxSource = selectedCheckboxSource
  rowStyle = mergeStyles(styles.row, rowStyle, selectedRowStyle)
  checkboxStyle = mergeStyles(styles.checkbox, checkboxStyle, selectedCheckboxStyle)
  labelStyle = mergeStyles(styles.label, labelStyle, selectedLabelStyle)
} else {
  rowStyle = mergeStyles(styles.row, rowStyle)
  checkboxStyle = mergeStyles(styles.checkbox, checkboxStyle)
  labelStyle = mergeStyles(styles.label, labelStyle)
}

return (
  <TouchableWithoutFeedback onPress={() => this.onRowPress(row.item)}>
    <View style={styles.rowStyle}>
     {this.renderLabel(row.item.label, labelStyle, row.item.selected)}
       <Image style={checkboxStyle} source={checkboxSource} />
    </View>
  </TouchableWithoutFeedback>
)

} }

Here is the working code for Flatlist component Please update it

tanveerbyn commented 5 years ago

I'm using react native's powerful flatlist this is my array which is like this:

data = [ {Color:[{'label':'BLUE','value':'10'}, {'label':'RED','value':'11'}]}, {Size:[{'label':'SMALL','value':'13'},{'label':'BIG','value':'12'}]} ] and here it Is my flatlist

<FlatList data={data} numColumns={1} keyExtractor={(item, index) => index.toString()} extraData={this.state} ItemSeparatorComponent={FlatListItemSeparator} renderItem={({item, index}) => { return(

{Object.keys(item)} "D"+index.toString()} extraData={this.state} renderItem={({item, index}) => { return( this._handleclick(index, item)} style={[ styles.Buttoncolor, this.state.selected == index+item.label ? styles.onfocusbutton : null ]}> {item.label} ) } }/> )}}/> this is the function where im matching the index of item.. _handleclick = (index, item) => { this.setState({selected: index+item.label, selectedColor: item.value}) } here it is what I tried :-> I call hand click function match its value with index+label name and it get change itself but when I click on BLUE it change its color but when I click on SMALL it can change itself but blue gets its previous condition now here's main what I want to do :-> I want to select only one item based on there array which is 'Color' I want that when I click on BLUE it can be change it color . and if I click also on SMALL it can also change color itself that two value need to be stored. I hope you could easily understand. thanks in advance
alanshaw commented 5 years ago

v2 fixes flatlist