rows expanding issue with rusite infinite loader

22 views Asked by At

Issue: on scrolling on the table and calling the loadMore function to get more data, the rows height is automatically expanding(on scrolling). I have used rusite table and column to fill up the data. Reference link to rusite Infinite Loader table

As mentioned in the example code in the link, onScroll() function calls handleScroll() function and check for the tableheight and contextHeight and based of the if condition calls loadmore() function.

import { FaLockOpen, FaLock } from "react-icons/fa";
import { Table, Checkbox, Loader } from "rsuite";
import { useSelector, useDispatch } from "react-redux";
import {
  setCheckedUsers,
  setPagination,
  getUserList,
  setLoader,
} from "users.actions";

const { Column, HeaderCell, Cell } = Table;
const FixedLoader = () => (
  <Loader
    content="Loading..."
    style={{
      display: "flex",
      justifyContent: "center",
      position: "absolute",
      bottom: "0",
      background: "#f5f5f5",
      width: "100%",
      padding: "4px 0",
    }}
  />
);
const CheckCell = ({ rowData, onChange, checkedKeys, dataKey, ...props }) => (
  <Cell
    {...props}
    style={checkedKeys.includes(rowData["id"]) ? checkStyles : { padding: 0 }}
  >
    <div style={{ lineHeight: "46px" }}>
      <Checkbox
        value={rowData[dataKey]}
        inline
        onChange={onChange}
        checked={checkedKeys.some((item) => item === rowData[dataKey])}
      />
    </div>
  </Cell>
);
const IconCell = ({ rowData, checkedKeys, dataKey, ...props }) => (
  <Cell
    {...props}
    style={checkedKeys.includes(rowData["id"]) ? lockStyles : { padding: 10 }}
  >
    {rowData[dataKey] ? (
      <FaLockOpen className="icon" style={{ fontSize: 24 }} />
    ) : (
      <FaLock className="icon" style={{ fontSize: 24 }} />
    )}
  </Cell>
);
const DataCell = ({ rowData, checkedKeys, dataKey, ...props }) => (
  <Cell {...props} style={checkedKeys.includes(rowData["id"]) ? styles : null}>
    {rowData[dataKey]}
  </Cell>
);

const styles = {
  backgroundColor: "#15c1b1",
  color: "black",
};
const checkStyles = {
  backgroundColor: "#15c1b1",
  color: "black",
  padding: 0,
};
const lockStyles = {
  backgroundColor: "#15c1b1",
  color: "black",
  padding: 10,
};

const tableHeight = 650;
export default function TableComponent({ filterValue, advanceFilterValue }) {
  const userData = useSelector((state) => state.users.users);
  const loader = useSelector((state) => state.users.loader);
  let data = userData;
  const dispatch = useDispatch();
  const [loading, setLoading] = React.useState(false);
  const [oldY, setY] = React.useState(0);
  let checked = false;
  let indeterminate = false;

  if (checkedKeys.length === data.length) {
    checked = true;
  } else if (checkedKeys.length === 0) {
    checked = false;
  } else if (checkedKeys.length > 0 && checkedKeys.length < data.length) {
    indeterminate = true;
  }

  useEffect(() => {
    setFilter(filterValue);
    setY(0);
  }, [filterValue, userData]);

  useEffect(() => {
    dispatch(getUserList());
  }, []);

  const loadMore = () => {
    // dispatch(setLoader(true))
    setLoading(true);
    setTimeout(() => {
      dispatch(getUserList());
      setLoading(false);
    }, 1000);
  };

  const handleScroll = (x, y) => {
    let contextHeight = userData.length * 46;
    const top = Math.abs(y);
    const sol = contextHeight - top - tableHeight;
    if (sol < 300 && oldY < y) {
      setY(y);
      dispatch(setPagination(userData.length, 10));
      loadMore();
    }
  };

  return (
    <div id="table-container" style={{ position: "relative" }}>
      <Table
        virtualized
        wordWrap="break-word"
        bordered
        shouldUpdateScroll={false}
        height={tableHeight}
        data={getData(filter)}
        sortColumn={sortColumn}
        sortType={sortType}
        onSortColumn={handleSortColumn}
        onScroll={handleScroll}
      >
        <Column flexGrow={1} fixed align="center">
          <HeaderCell style={{ padding: 0 }}>
            <div style={{ lineHeight: "40px" }}>
              <Checkbox
                inline
                checked={checked}
                indeterminate={indeterminate}
              />
            </div>
          </HeaderCell>
          <CheckCell dataKey="id" checkedKeys={checkedKeys} />
        </Column>

        <Column flexGrow={1} fixed sortable>
          <HeaderCell style={{ color: "black", fontSize: 15 }}>
            Status
          </HeaderCell>
          <IconCell dataKey="locked" checkedKeys={checkedKeys} />
        </Column>
        <Column flexGrow={2} fixed sortable>
          <HeaderCell style={{ color: "black", fontSize: 15 }}>ID</HeaderCell>
          <DataCell dataKey="id" checkedKeys={checkedKeys} />
        </Column>

        <Column flexGrow={2} sortable>
          <HeaderCell style={{ color: "black", fontSize: 15 }}>name</HeaderCell>
          <DataCell dataKey="name" checkedKeys={checkedKeys} />
        </Column>

        <Column flexGrow={2} sortable>
          <HeaderCell style={{ color: "black", fontSize: 15 }}>
            lastname
          </HeaderCell>
          <DataCell dataKey="lastname" checkedKeys={checkedKeys} />
        </Column>
        <Column flexGrow={2} sortable>
          <HeaderCell style={{ color: "black", fontSize: 15 }}>
            E-Mail
          </HeaderCell>
          <DataCell dataKey="email" checkedKeys={checkedKeys} />
        </Column>
        <Column flexGrow={2} sortable>
          <HeaderCell style={{ color: "black", fontSize: 15 }}>
            checked-in
          </HeaderCell>
          <DataCell dataKey="checked-in" checkedKeys={checkedKeys} />
        </Column>
      </Table>
      {loading && <FixedLoader />}
    </div>
  );
}

Please bare with me that i have added more than sample code. One more thing to mention is the getUserList() which is getting called in loadmore() the api call is replaced with the sample data and 10 data is populated in the table at the start then as scrolled down the next 10 data is being called and populated and so on.

export const getUserList =
  (search = "") =>
  async (dispatch, select) => {
    const state = select((state) => state);
    const pagination = state.users.pagination;
    const { first = 0, max = 10 } = pagination;
    let query = `first=${first}&max=${max}`;
    if (search) {
      query += `&search=${search}`;
    }
    try {
      // const res = await instance.get(`/list-users?${query}`);
      const res = state.users.apiUsers;
      const data = res.map((user) => {
        return {
          id: user.id,
          email: user.email,
          kostenstelle: user.attributes?.kostenstelle,
          nachname: user.lastName,
          vorname: user.firstName,
          groups: user.groups,
          attributes: user.attributes,
          locked: user.enabled,
        };
      });
      const fetchData = (offset, limit) => {
        const length = data.length;
        const start = Math.min(length - 1, offset);
        const end = Math.min(length, offset + limit);
        return res.slice(start, end);
      };
      dispatch({
        type: GET_USER_LIST,
        payload: fetchData(first, max),
      });
      dispatch({
        type: SET_LOADER,
        payload: false,
      });
    } catch (err) {
      return err;
    }
  };

What wrong with this code? How to stop rows height expanding when scrolled?
Any guidance would help. Also attaching a image of before and after the scrolling. enter image description here enter image description here

0

There are 0 answers