zlobul
zlobul

Reputation: 375

How to handle arrays in a Grommet DataTable?

I'm trying to use arrays in Grommet DataTable. My data looks like this :

{
    customer: [
        'BANANA',
        'Banana',
        'banana',
        'republic of banana'
    ],
    somethingelse: ['ABC','123','DEF']
}

In a regular Grommet Table , I'm able to use every cell by defining the first value from the array as title - for example customer[0] - and create an expandable arrow to show the rest of the data in 'customer' :

Regular Grommet Table

But I don't get how to do this on a cell basis for a Grommet DataTable ?

Here is the way I'm using it in the regular Grommet Table :

<TableCell scope="row" pad={{ left: '2px', righ: '3px' }}>
                <TextInput name="tags" size="xsmall" />
              </TableCell>
            </TableRow>
            {searchResults.length > 0 &&
              searchResults.map((searchResult, index) => (
                <TableRow key={index}>
                  <TableCell>
                    <Box direction="row">
                      <Text size="xsmall">{searchResult.customer[0]}</Text>
                      {searchResult.customer.length > 1 && (
                        <Button
                          plain
                          hoverIndicator={false}
                          icon={
                            isExpanded[index] ? (
                              <FormDown size="18px" />
                            ) : (
                              <FormNext size="18px" />
                            )
                          }
                          onClick={() => toggleOpen(index)}
                        />
                      )}
                    </Box>
                    <Box>
                      {isExpanded[index] && listElements(searchResult.customer)}
                    </Box>
                  </TableCell>

Here is my Form , using DataTable :

 return (
    <Form value={formData} onSubmit={onSubmit} onChange={onChange}>
      ...
        <DataTable
          fill
          border={{ body: 'bottom' }}
          paginate
          columns={columns}
          data={searchResults}
          select={select}
          onClickRow={(e) => console.log(e.datum)}
          onSelect={() => {}}
          step={8}
          rowDetails={(row) => {             // I'm able to use rowDetails to expand and display some data , but how can I use this to 1. Use the [0] element of the array as title and 2. apply to all cells in the row/table. 
            for (const cell in row) {
              // if (cell.length > 1) {
              //   return listElements(cell);
              // }
              console.log(cell);
            }
          }}
          ...
         />
         ...
    </Form>
  );

Upvotes: 0

Views: 258

Answers (1)

zlobul
zlobul

Reputation: 375

I was able to achieve that by using the render function and passing a CellElement to it, in which I have created my rules :

const columns = [
    {
      property: 'customer',
      header: <FormField label="Customer" name="customer" size="xsmall" />,
      render: (datum) => <CellElement val={datum.customer} />,
    },

CellElement.js

import { Box, Text, Button } from 'grommet';
import { FormNext, FormDown } from 'grommet-icons';
import React, { useState } from 'react';

const CellElement = ({ val }) => {
  const title = Array.isArray(val) ? val[0] : val;
  const [isExpanded, setIsExpanded] = useState({});
  const toggleOpen = (category) => {
    setIsExpanded({
      ...isExpanded,
      [category]: !isExpanded[category],
    });
  };
  const listElements = (arr) => {
    return arr.slice(1).map((el, index) => (
      <Text key={index} size="xsmall">
        {el}
      </Text>
    ));
  };
  return (
    <Box>
      <Box direction="row">
        <Text size="xsmall">{title}</Text>
        {Array.isArray(val) && val.length > 1 && (
          <Button
            plain
            hoverIndicator={false}
            icon={
              isExpanded[title] ? (
                <FormDown size="18px" />
              ) : (
                <FormNext size="18px" />
              )
            }
            onClick={() => toggleOpen(title)}
          />
        )}
      </Box>
      <Box>{isExpanded[title] && listElements(val)}</Box>
    </Box>
  );
};

export default CellElement;

Upvotes: 0

Related Questions