Home > Net >  react native (type script) : Selecting the father sons check box in flatlist
react native (type script) : Selecting the father sons check box in flatlist

Time:11-21

My goal is that when user select a checkbox of one of the fathers ('Non Veg Biryanis','Pizzas','Drinks','Deserts') in the flatlist, then those sons who belong to him are also selected. When the check box is removed from all the children belonging to the same father, then the check box is also removed for the father as well.

this is my example (but its not works as can see, the father 'Pizzas' not checked but his sons checked) enter image description here

The data is:

[
    {
      title: 'Non Veg Biryanis',
      checked: false,
      data: [
        { key: 'chicken', value: false, checked: false },
        { key: 'meat', value: false, checked: false },
        { key: 'veg', value: false, checked: false },
      ],
    },

    {
      title: 'Pizzas',
      checked: false,
      data: [
        { key: 'olives', value: false, checked: false },
        { key: 'green cheese', value: false, checked: false },
        { key: 'paprika', value: false, checked: false },
      ],
    },
    {
      title: 'Drinks',
      checked: false,
      data: [
        { key: 'cola', value: false, checked: false },
        { key: 'sprite', value: false, checked: false },
        { key: 'orange', value: false, checked: false },
      ],
    },
    {
      title: 'Deserts',
      checked: false,
      data: [
        { key: 'cake', value: false, checked: false },
        { key: 'ice-cream', value: false, checked: false },
        { key: 'pie', value: false, checked: false },
      ],
    },
  ]

The Accordian:

import React, { useState } from 'react';
import { View, TouchableOpacity, Text, FlatList, LayoutAnimation, Platform, UIManager } from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';
import styles from './AccordianStyle';

const Accordian = props => {
  const [data, setData] = useState(props.item);
  const [expanded, setExpanded] = useState(false);

  if (Platform.OS === 'android') {
    UIManager.setLayoutAnimationEnabledExperimental(true);
  }

  const onClick = (index: number) => {
    console.log(data);
    const temp = { ...data };
    temp.data[index].checked = !temp.data[index].checked;
    setData(temp);
  };
  const onClickFather = () => {
    const temp = { ...data };
    temp.checked = !temp.checked;
    if (temp.checked) {
      temp.data = temp.data.map((item: { checked: boolean }) => {
        item.checked = true;
      });
    }
    console.log(temp);
    setData(temp);
  };
  const toggleExpand = () => {
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
    setExpanded(!expanded);
  };
  return (
    <View>
      <View style={styles.row}>
        <TouchableOpacity onPress={() => onClickFather()}>
          <Icon name={'check-circle'} size={24} color={data.checked ? 'green' : '#d3d7de'} />
        </TouchableOpacity>
        <Text style={[styles.title]}>{data.title}</Text>
        <TouchableOpacity style={styles.row} onPress={() => toggleExpand()}>
          <Icon name={expanded ? 'keyboard-arrow-up' : 'keyboard-arrow-down'} size={30} color={'grey'} />
        </TouchableOpacity>
      </View>
      <View style={styles.parentHr} />
      {expanded && (
        <View style={{}}>
          <FlatList
            data={data.data}
            numColumns={1}
            scrollEnabled={false}
            renderItem={({ item, index }) => (
              <View>
                <TouchableOpacity
                  style={[styles.childRow, styles.button, item.checked ? styles.btnActive : styles.btnInActive]}
                  onPress={() => onClick(index)}
                >
                  <Text style={[styles.itemInActive]}>{item.key}</Text>
                  <Icon name={'check-circle'} size={24} color={item.checked ? 'green' : '#d3d7de'} />
                </TouchableOpacity>
                <View style={styles.childHr} />
              </View>
            )}
          />
        </View>
      )}
    </View>
  );
};

export default Accordian;

CodePudding user response:

Modify your onClick function so that it loops through each entry in the data array with the some() method and check if any of the children (sons) are clicked.

If one of them is, then update set the checked property accordingly.

const onClick = (index: number) => {
  setData(prevState => {
    const newData = prevState.data.map((entry, entryIndex) =>
      index === entryIndex ?
        ({ ...entry, checked: !entry.checked }) : 
        entry
    );

    const isAnyChildChecked = newData.some(({ checked }) => 
      checked === true
    );

    return ({
      ...prevState,
      checked: isAnyChildChecked,
      data: newData
    })
  });
};

If the parent is clicked, then check or uncheck all the children as well.

const onClickFather = () => {
  setData(prevState => {
    const isParentChecked = !prevState.checked;
        
    return ({
      ...prevState,
      checked: isParentChecked,
      data: prevState.data.map(item => ({ ...item, checked: isParentChecked }))
    });
  });
};
  • Related