FlatList component of react native as ListView is now deprecated
sudhirkumarojhaa opened this issue · 3 comments
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
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
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)}
<FlatList data={item[Object.keys(item)]}
numColumns={5}
keyExtractor={(index) => "D"+index.toString()}
extraData={this.state}
renderItem={({item, index}) => {
return(
<TouchableOpacity onPress={() => this._handleclick(index, item)} style={[
styles.Buttoncolor, this.state.selected == index+item.label
? styles.onfocusbutton
: null
]}>
<Text style={[styles.textcolor,this.state.selected == index+item.label?styles.white: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
v2 fixes flatlist