2

I'm trying to create multiple checkbox for my app like in the image below. I created it, but a facing problem that it's alignment is not good.

Here is my code in which I'm trying to create it, I created Separate component for that so I can use it in multiple places. I use code just facebook which is looking bad. Is there any library for that or better way to do it? It not looking good compare to image.

//component code

function Choice({data, onValueChange, style}) {
  const [selectedIndex, setSelectedIndex] = useState(-1);

  const FilterButton = ({
    callback,
    text,
    id,
    selectedIndex,
    btnstyles,
    btnTxtStyles,
    btnstylesSelect,
    btnTxtStylesSelect,
    imageStyle,
  }) => {
    const clicked = selectedIndex === id;
    return (
      <View style={{flexDirection: 'row'}}>
        {!clicked ? (
          <>
            <TouchableOpacity
              style={[btnstyles]}
              onPress={() => {
                callback(id);
              }}></TouchableOpacity>
          </>
        ) : (
          <>
            <TouchableOpacity
              style={btnstylesSelect}
              onPress={() => {
                callback(id);
              }}>
              <Image source={imagePath.tick} style={{borderRadius: 5}} />
            </TouchableOpacity>
          </>
        )}
      </View>
    );
  };

  return (
    <View style={[style]}>
      {data.map((x, i) => (
        <FilterButton
          text={x.title}
          id={i}
          btnstyles={x.btnstyles}
          btnTxtStyles={x.btnTxtStyles}
          selectedIndex={selectedIndex}
          btnTxtStylesSelect={x.btnTxtStylesSelect}
          imageStyle={x.imageStyle}
          btnstylesSelect={x.btnstylesSelect}
          callback={(id) => {
            setSelectedIndex(id);
            if (onValueChange) {
              onValueChange(id);
            }
          }}
        />
      ))}
    </View>
  );
}

//Main code

 <View
              style={{
                flexDirection: 'row',
              }}>
              <Text style={{...styles.time1, ...commonStyles.fontSize14}}>
                1hr
              </Text>
              <Text style={{...styles.time2, ...commonStyles.fontSize14}}>
                2hr
              </Text>
              <Text style={{...styles.time2, ...commonStyles.fontSize14}}>
                3hr
              </Text>
              <Text style={{...styles.time2, ...commonStyles.fontSize14}}>
                4hr
              </Text>
            </View>
          

If anyone know how to do it better or any library for that please suggest.

enter image description here

2
  • Can you explain the problem that you have with the code? Commented Nov 21, 2020 at 5:59
  • Hey, well I want make checkbox like in image, facebook section has 4 check box I want that I able to make 1 box but don't know how to make 4 Commented Nov 21, 2020 at 6:15

2 Answers 2

4
+50

I changed name of your components for better understanding:

// ChoicesHeaders.js

import Checkbox from './CheckBox';

const ChoicesHeaders = ({
  headersName,
  choicesHeaderStyles,
  choicesHeaderItemStyles,
}) => {
  return (
    <View style={choicesHeaderStyles}>
      {headersName.map((header) => (
        <View style={choicesHeaderItemStyles}>
          <Text>{header}</Text>
        </View>
      ))}
    </View>
  );
};

export default ChoicesHeaders;
// Checkbox.js

const Checkbox = ({
  id,
  btnstyles,
  btnstylesSelect,
  checked,
  selectedIndex,
  onCheckboxChange,
}) => {
  return selectedIndex !== id ? (
    <TouchableOpacity
      style={btnstyles}
      onPress={() => {
        onCheckboxChange(id);
      }}></TouchableOpacity>
  ) : (
    <TouchableOpacity
      style={btnstylesSelect}
      onPress={() => {
        onCheckboxChange(id);
      }}></TouchableOpacity>
  );
};

export default Checkbox;
// Choice.js

import Checkbox from './CheckBox';

const Choice = ({
  callback,
  text,
  btnstyles,
  btnTxtStyles,
  btnstylesSelect,
  btnTxtStylesSelect,
  onValueChange,
  choicesCount
}) => {
  const [selectedIndex, setSelectedIndex] = React.useState(-1);
  const handleCheckboxChange = (id) => {
    setSelectedIndex(id)
    if (onValueChange) {
      onValueChange(text, id);
    }
  };

  return (
    <View style={{ flexDirection: 'row', alignItems: 'center' }}>
      <View style={btnTxtStyles}>
        <Text>{text}</Text>
      </View>
      {Array.from({length: choicesCount}).map((item, index) => (
      <Checkbox
        id={index}
        btnstyles={btnstyles}
        btnstylesSelect={btnstylesSelect}
        selectedIndex={selectedIndex}
        onCheckboxChange={handleCheckboxChange}
      />
      ))}
    </View>
  );
};

export default Choice;

// App.js

import Choice from './components/Choice';
import ChoicesHeader from './components/ChoicesHeader';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';


const data = [
  { title: 'Instagram', /* extra properties(e.g. keys to save in db) */},
  { title: 'Facebook',  },
  { title: 'Twitter',   },
  { title: 'Linkdin',   },
];

const choicesHeaders=['1 hr', '2 hr', '3 hr', '4 hr'];

export default function App() {
  const handleValueChange = (socialMediaName, checkboxId) => {
    // do what ever you want with this two
  };

  return (
    <View style={styles.container}>
      <ChoicesHeader
        headersName={choicesHeaders}
        choicesHeaderStyles={styles.choicesHeader}
        choicesHeaderItemStyles={styles.choicesHeaderItem}
      />
      {data.map((x) => (
        <Choice
          text={x.title}
          btnTxtStyles={styles.btnTxtStyles}
          btnstyles={styles.btnstyles}
          btnstylesSelect={styles.btnstylesSelect}
          onValueChange={handleValueChange}
          choicesCount={choicesHeaders.length}
        />
      ))}
    </View>
  );
}

const checkBoxBaseStyles = {
    height: 40,
    width: 40,
    margin: 10,
};

const labelDimentions = {
  width: 100
};

const styles = StyleSheet.create({
  btnstyles: {
    ...checkBoxBaseStyles,
    borderWidth: 1,
    borderColor: 'orange',
  },
  btnstylesSelect: {
    ...checkBoxBaseStyles,
    backgroundColor: 'orange',
  },
  btnTxtStyles: {
    ...labelDimentions,
  },
  choicesHeader: {
    flexDirection: 'row',
    alignItems: 'center',
    marginLeft: labelDimentions.width
  },
  choicesHeaderItem: {
    ...checkBoxBaseStyles,
    textAlign: 'center'
  },
});

expo snack link

Sign up to request clarification or add additional context in comments.

6 Comments

what about text (1hr, 2hr)? your code is working properly but how I set upper text?
Can you tell me where exactly you want to put upper text? and what challenges do you have? @DarkPrince
Ya sure, just like in the image(in question) you can see 1 hr 2hr 3 hr 4hr upside 1st line of box, I want upper text like that
I changed the code inside answer. I changed some part of code to reuse styles. you can see changes in expo link. @DarkPrince
I should say it could be better if we change name of components again: whole app ---> SocialMediaActivityQuestion, ChoiceHeaders ---> Header, Choice ---> SocialMediaItem
|
1

Its definitely not perfect but here is at least a working example of the text above the checkboxes. Rather than having the labels linked with the checkboxes I have merely 'placed' them above the checkboxes.

in App.js - change your App return to:

 return (
    <View>
      <View style={{ flexDirection: 'row', alignItems: 'center', marginLeft:100}}>
          <Text style={styles.labelStyles}>1hr</Text>
          <Text style={styles.labelStyles}>2hr</Text>
          <Text style={styles.labelStyles}>3hr</Text>
          <Text style={styles.labelStyles}>4hr</Text>
      </View>
      <Choice data={data} onValueChange={handleValueChange} />
    </View>
  );

Then just add some styles in your const styles, something like this:

labelStyles: {
    margin:10,
    fontSize:13,
    color:'#afafb2'
  },

For a playground view: https://snack.expo.io/RGzGbUadq

Hope this helps give you an idea, if anything! :)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.