Home > Mobile >  React: filter array list using Multiple CheckBoxes
React: filter array list using Multiple CheckBoxes

Time:12-18

I am trying to filter the list of array of objects from the Material UI Autocomplete, based on mutiple conditions. However the onchange method is only returning the first state. By that i mean;

-- const array = [1, 2, 2, 3, 4, 4]

-- filtrering 2 //return 2, 2

-- User change condition to filtrering 2 and 3 // null

//Array for checkbox
const races = [
  'Akita',
  'American Bulldog',
  'Barbet',
  'Beaglier',
  'Cavapoo',
  'Chihuahua',
  'Dachshund',
  'Goldador',
  'Virginia Andrews',
  'Golden Retriever',
];

const class = () => {
//Array for list data 
const [array, setArray] = useState([ // this only change in the first render
  { id: 1, title: 'Akita from place1', race: "Akita" },
  { id: 2, title: 'Akita from place2', race: "Akita" },
  { id: 3, title: 'Akita from place3', race: "Akita" },
  { id: 4, title: 'Chihuahua from place4', race: "Chihuahua" },
  { id: 5, title: 'Cockapoo from place5', race: "Cockapoo" },
  { id: 6, title: 'Dachshund from place6', race: "Dachshund" },
  { id: 7, title: 'Dutch Shepherd from place7', race: "Dutch Shepherd" },
  { id: 8, title: "Bulldog from place8", race: "Bulldog" },
  { id: 9, title: 'Goldador from place9', race: "Goldador" },
])

//Array for filter
const [filteredArray, setFilteredArray]= useState<any | null>(array || null) // use this to print 


//Onchange for material ui autocomplete checkbox
    const handleArrayChanges = (event, value) => {
      if (value) {  
        const data = array.filter(data => data.race.includes(value)).map(filteredName => {
          return filteredName
        })
        setFilteredArray(data);
      } else {
        const data2 = array.filter(data => data.race.includes(value)).map(filteredName => {
          return !filteredName;  
        })

        setFilteredArray(data2)
      }
      console.log(value)
      console.log(data)
   };

 return (
<Grid container xs={10} sm={10} md={10} lg={12} xl={8} spacing={3} style={{marginTop: 50}}>
 <Autocomplete
              multiple
              id="checkboxes-tags-demo"
              options={races}
              disableCloseOnSelect
              onChange={handleArrayChanges}
              getOptionLabel={(option) => option}
              renderTags={(value, getTagProps) => {
                const numTags = value.length;
                const limitTags = 1;
        
                return (
                  <>
                    {value.slice(0, limitTags).map((option, index) => (
                      <Chip
                        {...getTagProps({ index })}
                        key={index}
                        label={option}
                      />
                    ))}
        
                    {numTags > limitTags && `  ${numTags - limitTags}`}
                  </>
                );
              }}
              PaperComponent={({ children }) => (
                <Paper style={{ width: 1000 }}>{children}</Paper>
              )}
              renderOption={(props, option, { selected }) => (
                <li {...props}>
                  <Checkbox
                    icon={icon}
                    checkedIcon={checkedIcon}
                    checked={selected}
                  />
                  {option}

                </li>
              )}
              style={{ width: 300 }}
              renderInput={(params) => (
                <TextField {...params} label="Search for dog breeds"
                style={{backgroundColor: "#EEEEEE"}} variant="outlined" size="medium" 
                />
              )}      
            />
    {filteredArray?.map((data, _index) => (
        <Grid item xs={3}>
        <Card key={_index} sx={{ maxWidth: 300 }}>
      <CardMedia component="img" height="200" image={image} alt="green iguana" />
      <CardContent>
        <Typography gutterBottom variant="h5" component="div">
          {data.title}
        </Typography>
        <Typography variant="body2" color="text.secondary">
          {data.race}
        </Typography>
      </CardContent>
      <CardActions>
        <Button size="small">Share</Button>
        <Button size="small">Learn More</Button>
      </CardActions>
    </Card>
      </Grid>

 
    ))}
</Grid>

I know the usetate is pushing current value, which make the next condition return nothing, because there is no data. But i don't know how to solve this.

https://codesandbox.io/s/infallible-beaver-zdvn7?file=/src/App.js

CodePudding user response:

EDIT: Codesandbox with working example: https://codesandbox.io/s/delicate-grass-feqyn

You need to turn your filter statement around:

try replacing

 .filter((data) => data.race.includes(value))

with

.filter((data) => value.includes(data.race))
  • Related