Reputation: 1596
As said here <checkBox/>
is only possible for android but i want to implement single code for both android and iOS (without using any node packages). For this i'm proceeding with views as below
import React, { Component } from 'react';
import { Platform, View, TouchableOpacity } from 'react-native';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
checkSelected: 1
}
}
checkClick(id) {
this.setState({
checkSelected: id
})
}
render() {
const products = [{
id: 1
},
{
id: 2
},
{
id: 3
}];
return (
products.map((val) => {
return (
<TouchableOpacity key={val.id} onPress={this.checkClick.bind(this, val.id)}>
<View style={{
height: 24,
width: 24,
border: 12,
borderWidth: 2,
borderColor: '#000',
alignItems: 'center',
justifyContent: 'center',
}}>
{
val.id == this.state.checkSelected ?
<View style={{
height: 12,
width: 12,
border: 6,
backgroundColor: '#000',
}} />
: null
}
</View>
</TouchableOpacity>
)
})
);
}
}
This output will be like this
This approach is like RadioButton but i want to follow the <View/>
approach for CheckBox also. For this i've implemented like this
import React, { Component } from 'react';
import { View, TouchableOpacity } from 'react-native';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
checkSelected: []
}
}
checkClick(id) {
let todos = [...this.state.checkSelected]; //creating the copy
//adding new data
todos.push({
checkId: id
});
//updating the state value
this.setState({ checkSelected: todos }, () => {
alert('state: ' + JSON.stringify(this.state.checkSelected));
});
}
render() {
const products = [{
id: 1
},
{
id: 2
},
{
id: 3
}];
return (
products.map((val) => {
return (
<TouchableOpacity key={val.id} onPress={this.checkClick.bind(this, val.id)}>
<View style={{
height: 24,
width: 24,
border: 12,
borderWidth: 2,
borderColor: '#000',
alignItems: 'center',
justifyContent: 'center',
}}>
{
this.state.checkSelected.map((checkIds) => {
{
checkIds.checkId == val.id ?
<View style={{
height: 12,
width: 12,
border: 6,
backgroundColor: '#000',
}} />
: null
}
})
}
</View>
</TouchableOpacity>
)
})
);
}
}
In this approach i'm storing clicked id's in state and trying to select all checkboxes which id's are in state but i'm unable to do that. Can any one suggest me to select multiple check boxes.
Upvotes: 0
Views: 7644
Reputation: 4879
CheckBox
's clicked prop. import React, { Component } from 'react';
import { View, TouchableOpacity } from 'react-native';
class CheckBox extends Component {
constructor(props) {
super(props);
this.state = {isCheck: false};
}
checkClicked = async () => {
await this.setState(prevState => ({
isCheck: !prevState.isCheck,
})); // setState is async function.
// Call function type prop with return values.
this.props.clicked && this.props.clicked(this.props.value, this.state.isCheck);
}
render() {
return (
<TouchableOpacity onPress={this.checkClicked} style={this.props.style}>
<View style={{
height: 24,
width: 24,
borderWidth: 2,
borderColor: '#000',
alignItems: 'center',
justifyContent: 'center',
}}>
<View style={{
height: 12,
width: 12,
backgroundColor: this.state.isCheck ? '#000' : '#FFF',
}} />
</View>
</TouchableOpacity>
)
}
}
const products = [
{
id: 1
},
{
id: 2
},
{
id: 3
}
];
export default class CheckBoxScreen extends Component {
constructor(props) {
super(props);
this.state = {
checkSelected: [],
}
}
toggleCheckBox = (id, isCheck) => {
let { checkSelected } = this.state;
if (isCheck) {
checkSelected.push(id);
} else { // remove element
var index = checkSelected.indexOf(id);
if (index > -1) {
checkSelected.splice(index, 1);
}
}
this.setState({ checkSelected });
alert(this.state.checkSelected); // logging
}
render() {
const checkboxs = products.map(({id}) =>
<CheckBox style={{marginTop: 50,}}key={id} value={id} clicked={(id, isCheck) => this.toggleCheckBox(id, isCheck)}></CheckBox>
)
return (
<View style={{flex: 1, alignItems: 'center'}}>
{checkboxs}
</View>
);
}
}
It will work and you can use my example to other ways what you want.
Upvotes: 3
Reputation: 1661
In a different soluion, i would recommend to make a checkbox component , which will have properties id and onCheckBoxValueChange. Both will take initial values from parent component, and on every change, the state of local component will change, returning a callback with the id of the selected.
Child:
constructor(props) {
super(props);
this.state = {
value: this.props.value
};
}
onCheckBoxValueChange(id) {
this.setState({ value: !this.state.value });
this.props.onCheckBoxValueChange(id, !this.state.value);
}
render() {
return (
<ViewStyledAsCheckBox
style={styles.checkBox}
isChecked={this.state.value}
onPress={() => this.onCheckBoxValueChange(this.props.id)}
/>
Parent will call child component like this:
<CheckBoxComponent
id={1}
onCheckBoxValueChange={(id, value) =>
this.doSomethingWithChangedValueInThisSpecificChekbox(id, value)
}
/>
<CheckBoxComponent
id={2}
onCheckBoxValueChange={(id, value) =>
this.doSomethingWithChangedValueInThisSpecificChekbox(id, value)
}
/>
Let me know if this works for you or want more information as this is more of a template than real implementation
Upvotes: 0