Reputation: 784
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(
<View >
<Text >{Object.keys(item)}</Text>
<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}</Text>
</TouchableOpacity>
)
}
}/>
</View>)}}/>
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
UPDATE 1
STATUS :SOLVED
Changes
_handleclick = (index, item,objectname) => {
const {selected,result} = this.state
let selectedIndex = this.state.selected.indexOf(item.value);
if(selectedIndex == -1){
let my = this.state.result.filter((e)=>{return e[objectname]})
selected.forEach((items) => {
let arrayofattribute = result.filter((e)=>{return e[objectname]})
arrayofattribute.forEach((value,index)=>{
newval = value[objectname].map((val,i)=>{
if(items == val.label)
{
selected.splice(selected.indexOf(val.label),1)
}
})
})
})
this.setState({selected:[item.label,...this.state.selected]})
}
}
in Flatlist render
<TouchableOpacity
onPress={() => this._handleCategoryColor(index, item,objectname)}
style={[
styles.Buttoncolor,
this.state.selected.indexOf(item.label) != -1
? styles.onfocusbutton
: null,
]}>
<Text
style={[
styles.textcolor,
this.state.selected.indexOf(item.label) != -1
? styles.white
: null,
]}>
{item.label}
</Text>
</TouchableOpacity>
Upvotes: 1
Views: 4089
Reputation: 1672
If I correcty understood you need to select just one option for each property (colors and sizes). So you need to have a field in your state for each element you want to be saved.
Your _handleClick
function could be something like this:
_handleclick = (index, item) => {
const { Color } = this.state.data[0];
const { Size } = this.state.data[1];
this.setState(state => ({
selectedColor: Color.find(color => color.label === item.label)
? index + item.label
: state.selectedColor,
selectedSize: Size.find(size => size.label === item.label)
? index + item.label
: state.selectedSize,
}));
};
Every time you click on an element you need to know if it's a color or a size and then correctly update the right field. Maybe this is not the most performant way, but it works.
Then, in your render method, in order to assign style you could check both conditions:
<TouchableOpacity
onPress={() => this._handleclick(index, item)}
style={[
styles.Buttoncolor,
this.state.selectedSize == index + item.label ||
this.state.selectedColor == index + item.label
? styles.onfocusbutton
: null,
]}>
<Text
style={[
styles.textcolor,
this.state.selectedSize == index + item.label ||
this.state.selectedColor == index + item.label
? styles.white
: null,
]}>
{item.label}
</Text>
</TouchableOpacity>
I tried to reproduce your question in this snack, you can take a look.
Upvotes: 1
Reputation: 3856
Probably the issue is with the function arguments assignments. If you see both renderItem
methods in Flatlist
uses renderItem={({item, index})
so the last renderItem
can access the above item, index
. There's an confusion when onPress
called, which item or index to put in the callback.
Please try to add the arg different names. Like
<FlatList data={data}
numColumns={1}
keyExtractor={(item, index) => index.toString()}
extraData={this.state}
ItemSeparatorComponent={FlatListItemSeparator}
renderItem={({item, index}) => {
return(
<View >
<Text >{Object.keys(item)}</Text>
<FlatList data={item[Object.keys(item)]}
numColumns={5}
keyExtractor={(index) => "D"+index.toString()}
extraData={this.state}
renderItem={({set, key}) => {
return(
<TouchableOpacity onPress={() => this._handleclick(key, set)} 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}</Text>
</TouchableOpacity>
)
}
}/>
</View>)}}/>
Let me know if this fixes your issue. Happy coding. :)
Upvotes: 1
Reputation: 4961
you can try array instead of storing single selected item,
make selected state as empty array when you are declaring.
...
<TouchableOpacity onPress={() => this._handleclick(index, item)} style={[
styles.Buttoncolor, this.state.selected.indexOf(index+item.label) != -1
? styles.onfocusbutton
: null
]}>
<Text style={[styles.textcolor, this.state.selected.indexOf(index+item.label) != -1?styles.white:null]}>{item.label}</Text>
</TouchableOpacity>
here is you handle method, push new selected item to selected array
_handleclick = (index, item) => {
let selectedIndex = this.state.selected.indexOf(index+item.label);
if(selectedIndex== -1){
this.setState({selected: [...this.state.selected,index+item.label], selectedColor: item.value})
}
}
Upvotes: 1