React-native-elements: Checkbox selected per checkbox

Created on 8 Aug 2017  路  26Comments  路  Source: react-native-elements/react-native-elements

I'm creating a number of checkbox via a for loop and wanted to know how I can set the selected stated per checkbox

Here is my code

render() {
        // Gets tags from props
        const tags = this.props.tags;

        // Creates tag
        const tagItems = tags.map((tag) => {
            return(
                <CheckBox
                    key={tag}
                    center
                    title={tag}
                    iconRight
                    iconType='material'
                    checkedIcon='clear'
                    uncheckedIcon='add'
                    checkedColor='red'
                    checked={false}
                    //onPress={this._toggle.bind(this)}
                    onPress={(event) => this._toggle(event, tag)}
                />
            )});

        return (
            <View>
                {tagItems}
            </View>
        )
    }
_toggle(event, buttonId) {

        //this.setState({checked: !this.state.checked});
        console.log(buttonId)
        //console.log(this)


    }

Most helpful comment

@AlmogRnD you will be happy to know that I already implemented a simple use case demonstrating the use of callback in reference to Tags & TagGroups. Here's is what it looks like:
screen shot 2017-08-08 at 1 52 37 am

You can find the entire source code for it on the /example app here

Also here is how to use callbacks

Hope this helps. 馃槂 Let me know if you have any other questions.

All 26 comments

@AlmogRnD that's a good question. The way I think about it is.. if a component needs its own state, then it makes sense to map over a custom implementation of the component which knows how to handle its own state. I implemented this in the example app here and have a working demo you can play.
Here is how I did it:

import { CheckBox } from 'react-native-elements';

class CustomCheckbox extends Component {
  constructor() {
    super();

    this.state = {
      checked: false
    };
  }

  render() {
    const { tag } = this.props;
    const { checked } = this.state;

    return (
      <CheckBox
        key={tag}
        center
        title={tag}
        iconRight
        iconType='material'
        checkedIcon='clear'
        uncheckedIcon='add'
        checkedColor='red'
        checked={checked}
        onPress={() => this.setState({checked: !checked})}
      />
    );
  }
}


// call this function in the render method of another Component
renderTags() {
    return ['One', 'Two', 'Three', 'Four'].map((tag, index) => {
      return <CustomCheckbox key={index} tag={tag} />;
    });
  }

Hope this helps. Let me know if you have trouble with this.

@Monte9 the issue is that while it does need its own state, the check boxes need to be together under one component so it's easy to know which ones were selected, think of it as tags and a user can select a couple different ones. Ideally, there would be a checkbook group this is how I would have done it in web

the check boxes need to be together under one component so it's easy to know which ones were selected

This sounds like a good use case for using func callbacks. Basically the idea would be that when a CustomCheckbox is selected, you would invoke the callback on the parent and that way be able to keep track of which checkbox is selected using the tag/index in the parent component

Let me know if this is too confusing or if you need an example on how to do this. Also maybe @xavier-villelegier has another approach to doing this?

@Monte9 could use a little help with this and how I would it
Right now I have the following structure

  • Component TagGroups

    • Component Tags

TagGroups

return (
            <View>
                {this.state.indeterminate &&
                <Progress.Circle
                    style={styles.progressContainer}
                    progress={this.state.progress}
                    indeterminate={this.state.indeterminate}
                />
                }

                {!isEmptyProjectTags &&
                <View>
                    {this._renderTagGroups()}
                </View>
                }

                {isEmptyProjectTags &&
                <View>
                    <Text>No tags</Text>
                </View>
                }
            </View>
        )

// Render tag groups
    _renderTagGroups() {

        // Gets the tags groups
        const tagGroups = store.getState().selectedProject.project.tagGroups;

        for (var i = 0, len = tagGroups.length; i < len; i++) {
            return(
                <View>
                    <View key={i}>
                        <Text>{tagGroups[i].name}</Text>
                        <Tag tags={tagGroups[i].tags}/>
                    </View>
                </View>
            );
        }
    }

Tags

render() {
        // Gets tags from props
        const tags = this.props.tags;

        const { checked } = this.state;

        // Creates tag
        const tagItems = tags.map((tag) => {
            return(
                <CheckBox
                    key={tag}
                    center
                    title={tag}
                    iconRight
                    iconType='material'
                    checkedIcon='clear'
                    uncheckedIcon='add'
                    checkedColor='red'
                    //checked={this.state.checked}
                    //onPress={this._toggle.bind(this)}
                    onPress={(event) => this._toggle(event, tag)} //!checked
                    //onChange={(checked) => this._checkStudent(student, !checked)}

                    //onChange={(checked) => this._checkStudent(student, !checked)}
                    //checked={student.checked}
                />
            )});

        return (
            <View>
                {tagItems}
            </View>
        )
    }

Couple things:

  1. The code makes sense, although it's hard to tell what you are trying to achieve without some sort of UI representation. Can you add a screenshot so I get a better sense of how it's supposed to "behave"
  2. We are experimenting with "Paid Feature request" here at RNE. So basically a dev can implement the entire feature for you and share the completed code with you. If this sounds interesting, let me know. We can even do this one for free. 馃槈

@Monte9 I might be interested in that down the line, there is a lot of work that I need with components would need to understand how this would work.

Right now if you can help or point me in the right direction that would be great

Here is a screenshot of the design version
screen shot 2017-08-08 at 12 51 56 am

As you can see we have a group of tags that is the tag group component

and it renders the tags current version working

screen shot 2017-08-08 at 12 55 39 am

Ok, that's helpful. And so from what I understand you want to implement it in such a way that the TagGroups component is aware of all the tags that are selected within it's own group correct? And when a tag is selected, the UI for just that tag changes to indicate that it was select.

Feel free to correct me if you are trying to do something different. Seems like callbacks could work here as I talked about earlier.

Yea, that is the main concern I had with callbacks I was worried it would be nested too deep and create an issue.

A user uploads a photo and selects tags for that photo, the tag group component is inside the photo upload component

But worst case I can just updated the selected tags in my redux store

@AlmogRnD yeah that makes sense. Ok, so do you have a fair understanding of what you need to do and how you would do it using callbacks?

If not, I can implement something similar on the /example app by tomr if that helps you. let me know.

@Monte9 I have it working based on the first example code you sent me, I just need to understand the best way for the callbacks/props as you suggested

yes "how you would do it using callbacks?" what I'm not sure on

@AlmogRnD you will be happy to know that I already implemented a simple use case demonstrating the use of callback in reference to Tags & TagGroups. Here's is what it looks like:
screen shot 2017-08-08 at 1 52 37 am

You can find the entire source code for it on the /example app here

Also here is how to use callbacks

Hope this helps. 馃槂 Let me know if you have any other questions.

Ok can you send the code, thats just an image

Also how would I handle the onpress event with the state change

if do this
onPress={this._selectedTag()}

but then I can't handle the state change
onPress={() => this.setState({checked: !checked})}

Yes you can. Just put the this.setState({checked: !checked}) inside your _selectedTag() function.

Unless I'm doing it wrong but that crashes the app and I get the following error
screen shot 2017-08-08 at 2 06 53 am

@AlmogRnD please join our Slack channel and someone can help you resolve that.

https://reactnativetraining.herokuapp.com/

If I'm correct "put the this.setState({checked: !checked}) inside your _selectedTag() function."
It doesn't know which checkbox

I'm the only one on the slack channel.

I'm not sure it was correct to make the checkbox have it's own state / component if I can't change the state on press and handle that

@Monte9 ok I got got this is the use correct use case

onPress={() => {
this.setState({checked: !checked})
this._selectedTag()
}}

@Monte9 when you have a chance can you send me an email to [email protected] were looking at hiring a freelancer react native developer to develop a couple custom components for us. Thanks, Almog

Thanks for reaching out @AlmogRnD! I have sent you an email.

What a wonderful chat... I (junior) learn a lot of stuff from your healthy conversation thank you... :+1: :wave:

```
import { CheckBox } from 'react-native-elements'

            <View style={{ marginTop: 15 }}>

              <CheckBox
                key={tag}
                textStyle={{ flexWrap: 'wrap',fontFamily:'light', fontSize: Fonts.size.h4, color: 'rgba(255,255,255,0.7)', fontWeight: '400' }}
                containerStyle={{  backgroundColor:  'transparent', flexDirection: 'row', borderColor: 'transparent' }}
                title={tag}
                uncheckedColor='white'
                checkedColor='white'
                iconType='material-community'
                checkedIcon='checkbox-marked-outline'
                uncheckedIcon='checkbox-blank-outline'
                checked={this.state.checked}
                onPress={() => this.setState({checked: !this.state.checked})}
              />

            </View>``

It works fine but showing White background.
How can remove it ??
My background color is gradient so its look odd in app.

and above all chat is really helpful for me.

@Biplovkumar as you can see by this example https://snack.expo.io/@roach_iam/mature-truffles, there's no white background

@iRoachie Oops!
We couldn't find the Snack you're looking for. Go to the homepage.
this link is not valid.
really thanku so much for Quick reply.

I updated the link

Thanku sir

Was this page helpful?
0 / 5 - 0 ratings

Related issues

binzailani3136 picture binzailani3136  路  3Comments

xiaoneng picture xiaoneng  路  3Comments

mikebski picture mikebski  路  3Comments

motogod picture motogod  路  3Comments

jackcbrown89 picture jackcbrown89  路  3Comments