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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.