Show a pop-up window with information coming from an element and its totals, from one of the table in react.js

孤街浪徒 提交于 2020-12-23 12:52:51

问题


I'm developing an application in React.Js.

I have the array:

array = [
  {
    "id": 1,
    "date": {
      "id": 1,
      "name": "202001"
    },
    "item": {
      "id": 1,
      "name": "I1"
    },
    "price": 100
    },
    {
    "id": 2,
    "date": {
      "id": 2,
      "name": "202002"
    },
    "item": {
      "id": 1,
      "name": "I1"
    },
    "price": 200
  },
  {
    "id": 3,
    "date": {
      "id": 2,
      "name": "202002"
    },
    "item": {
      "id": 2,
      "name": "I2"
    },
    "price": 300
  },
]

And I show the data as shown in the table:

ITEM 202001 202002 TOTAL
I1 100 200 300
I2 - 300 300
TOTAL 100 500 600

And I did this to get those values:

items_dicc = array.reduce((acc, e) => {
    if (!acc[e["item"]["name"]]) {
      acc[e["item"]["name"]] = {
        [e["date"]["name"]]: e["price"]
      }
    } else {
      acc[e["item"]["name"]][e["date"]["name"]] = e["price"]
    }
    return acc
  }, {})

dates = [...new Set(Object.keys(items_dicc).map(i => Object.keys(items_dicc[i])).flat())]

totalSumPerDate = {};

dates.forEach(date => {
  const sumOnDate = Object.values(items_dicc).reduce((acc, curr) => {
    acc = acc + (curr[date]? curr[date] : 0);
    return acc;
  }, 0);
  totalSumPerDate[[date]] = sumOnDate;
});

totalSum = Object.values(totalSumPerDate).reduce((acc, curr) => acc+curr, 0);

sumPerItem = {};

Object.keys(items_dicc).forEach(key => {
   const sum = Object.values(items_dicc[key]).reduce((acc, curr) => acc + curr, 0);
   sumPerItem[[key]] = sum;
});


<table>
  <thead>
    <tr>
      <th>ITEM</th>
      {dates.map(date => <th>{date}</th>)}
      <th>TOTAL</th>
    </tr>
  </thead>
  <tbody>
  {
    Object.keys(items_dicc).map((item) => {
      return (
        <tr>
          <td>{item}</td>
          {dates.map((date) => <td>{items_dicc[item][date] || ''}</td>)}
          <td>{sumPerItem[item]}</td>
        </tr>
      )
    })
  }
    <tr>
      <td>TOTAL</td>
        {Object.values(totalSumPerDate).map(item => <td>{item}</td>)}
      <td>{totalSum}</td>
    </tr>
  </tbody>
</table>

I need to be able to show through a popup other data that the array may contain (for example the id).

I understand that to do this it is necessary to create a local state in the component to update the details when clicking on the selected record and pass the state to the modal.

It should also be able to bring in the totals info.

How can I do it, suggestions?


回答1:


You can pass the total data to the onClickEventHandler like this,

    <tr onClick={(event) => yourHandler(event, item, sumPerItem[item])}>
      <td>{item}</td>
      {dates.map((date) => <td>{items_dicc[item][date] || ''}</td>)}
      <td>{sumPerItem[item]}</td>
    </tr>

The event handler should be written like this,

yourHandler = (event, currentItem, totalForRow) => {
    // You update the state here 
}

This method is for whole row. If you want to show different data on each cell click you need to add the eventHandler on elements and update the method parameters according to your need.




回答2:


Try this approach,

You have to create a local state for the selected record of the table row and pass it to the modal component. Update the selected record on click of the table row.

import React, { useState } from "react";
import "./styles.css";
import "bootstrap/dist/css/bootstrap.min.css";

const array = [
  {
    id: 1,
    date: {
      id: 1,
      name: "202001"
    },
    item: {
      id: 1,
      name: "I1"
    },
    price: 100
  },
  {
    id: 2,
    date: {
      id: 2,
      name: "202002"
    },
    item: {
      id: 1,
      name: "I1"
    },
    price: 200
  },
  {
    id: 3,
    date: {
      id: 2,
      name: "202002"
    },
    item: {
      id: 2,
      name: "I2"
    },
    price: 300
  }
];

export default function App() {
  const [show, setShow] = useState(false);
  const [selectedData, setSelectedData] = useState({});
  const hanldeClick = (selectedId) => {
    const selectedRec = array.find((val) => val.item.name === selectedId);
    setSelectedData(selectedRec);
    setShow(true);
  };

  const hideModal = () => {
    setShow(false);
  };
  const items_dicc = array.reduce((acc, e) => {
    if (!acc[e["item"]["name"]]) {
      acc[e["item"]["name"]] = {
        [e["date"]["name"]]: e["price"]
      };
    } else {
      acc[e["item"]["name"]][e["date"]["name"]] = e["price"];
    }
    return acc;
  }, {});

  const dates = [
    ...new Set(
      Object.keys(items_dicc)
        .map((i) => Object.keys(items_dicc[i]))
        .flat()
    )
  ];

  const totalSumPerDate = {};

  dates.forEach((date) => {
    const sumOnDate = Object.values(items_dicc).reduce((acc, curr) => {
      acc = acc + (curr[date] ? curr[date] : 0);
      return acc;
    }, 0);
    totalSumPerDate[[date]] = sumOnDate;
  });

  const totalSum = Object.values(totalSumPerDate).reduce(
    (acc, curr) => acc + curr,
    0
  );

  const sumPerItem = {};

  Object.keys(items_dicc).forEach((key) => {
    const sum = Object.values(items_dicc[key]).reduce(
      (acc, curr) => acc + curr,
      0
    );
    sumPerItem[[key]] = sum;
  });

  return (
    <>
      <table>
        <thead>
          <tr>
            <th>ITEM</th>
            {dates.map((date) => (
              <th>{date}</th>
            ))}
            <th>TOTAL</th>
          </tr>
        </thead>
        <tbody>
          {Object.keys(items_dicc).map((item) => {
            return (
              <tr onClick={() => hanldeClick(item)}>
                <td>{item}</td>
                {dates.map((date) => (
                  <td>{items_dicc[item][date] || ""}</td>
                ))}
                <td>{sumPerItem[item]}</td>
              </tr>
            );
          })}
          <tr>
            <td>TOTAL</td>
            {Object.values(totalSumPerDate).map((item) => (
              <td>{item}</td>
            ))}
            <td>{totalSum}</td>
          </tr>
        </tbody>
      </table>
      {show && <Modal details={selectedData} handleClose={hideModal} />}
    </>
  );
}

const Modal = ({ handleClose, details }) => {
  console.log(details);
  return (
    <div className="modal display-block">
      <section className="modal-main">
        <div className="App">
          <table class="table">
            <thead>
              <tr>
                <th scope="col">ITEM</th>
                <th scope="col">ID</th>
                <th scope="col">DATE</th>
                <th scope="col">PRICE</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>{details?.item?.name}</td>
                <td>{details?.item?.id}</td>
                <td>{details?.date?.name}</td>
                <td>{details?.price}</td>
              </tr>
            </tbody>
          </table>
        </div>
        <button onClick={handleClose}>close</button>
      </section>
    </div>
  );
};

Working code - https://codesandbox.io/s/adoring-moore-rsn97?file=/src/App.js:0-3665



来源:https://stackoverflow.com/questions/65390482/show-a-pop-up-window-with-information-coming-from-an-element-and-its-totals-fro

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!