раскрывающееся меню реагировать закрыть открытое меню - PullRequest
1 голос
/ 14 октября 2019

Я передаю данные с API на стол. Для каждой записи есть выпадающее меню на столе. Выпадающее меню. Но выпадающие меню не закрываются. Поэтому, когда я нажимаю на пустое место на столе, раскрывающееся меню не закрывается.

Я хочу закрыть раскрывающееся меню.

, то есть, как установить переключательстатус. Вы можете помочь с этим?

<buttondropdown
isOpen = {this.state.table_dropdownMap.get (item.id)}
toggle = {this.table_dropdownToggle}

enter image description here

import React, { Component } from "react";
import withAuth from "../../components/helpers/withAuth";
import {
  Card,
  CardBody,
  CardHeader,
  Col,
  Row,
  Table,
  DropdownItem,
  DropdownMenu,
  DropdownToggle,
} from "reactstrap";
import { connect } from "react-redux";
import ButtonDropdown from "reactstrap/es/ButtonDropdown";


class CustomerDebt extends Component {
  constructor(props) {
    super(props);

    this.domain = `http://127.0.0.1:8000`;

    this.state = {
      top_dropdownOpen: false,
      table_dropdownOpen: false,
      table_dropdownMap: new Map(),

      modal: false,
      isLoaded: true,

      items: [],
      selectedItem:{ }
    };

    this.top_dropdownToggle = this.top_dropdownToggle.bind(this);
    this.table_dropdownToggle = this.table_dropdownToggle.bind(this);

    this.debtModalForm = this.debtModalForm.bind(this);
    this.handleChange = this.handleChange.bind(this);

    this.handleSubmitUpdate = this.handleSubmitUpdate.bind(this);
    this.handleSubmitCreate = this.handleSubmitCreate.bind(this);
  }

  //Customer debts unmounts - refresh problem
  abortController = new AbortController();
  componentWillUnmount = () => {
    this.abortController.abort();
  };


  //Get customer debts
  async componentDidMount() {

    await fetch(
        `${this.domain}/api/debt/list?customer=` +
        this.props.customerInfo.customer.id,
        {
          headers: {
            Authorization: `Bearer ${localStorage.getItem("id_token")}`,
            "Content-Type": "application/json"
          }
        }
    )
        .then(res => {
          if (res.ok) {
            return res.json();
          } else {
            return res.json().then(err => Promise.reject(err));
          }
        })
        .then(json => {
          this.setState({
            items: json
          });
          this.abortController.abort();
          // console.log(json)
        })
        .catch(error => {
          //console.log('request failed:', error);
          return error;
        });
  }


  debtModalForm (value) {
    console.log( value);

    if (value === "newRecord") {
      this.setState( prevState =>({
        modal: !prevState.modal,
      }))
    } else {

      console.log(value);

      this.setState(prevState => ({
        modal: !prevState.modal,

        selectedItem: value,

        user: value.user,
        customer: value.customer,
        debtKey: value.debtKey,
        createduserKey: value.createduserKey,
        totalDebt: value.totalDebt,
        receivedAmount: value.receivedAmount,
        description: value.description,
        paymentDate: value.paymentDate
      }));
    }

  }


  //text handleChange
  handleChange(e) {
    this.setState({
      [e.target.name]: e.target.value
    });
  }


  //dropdown toggle menu
  top_dropdownToggle = () => {
    this.setState(prevState => ({
      top_dropdownOpen: !prevState.top_dropdownOpen,
    }));
  };

  //table dropdown menü
  table_dropdownToggle ()  {
    this.setState(prevState => ({
      table_dropdownOpenMap: !prevState.table_dropdownOpenMap,
    }));

    console.log(this.state.table_dropdownOpenMap)
  };



render() {
    const { isLoaded, items } = this.state;
    if (!isLoaded) {
      return <div>Loading...</div>;
    } else {
      return (
          <div className={"animated fadeIn container-fluid"}>
            <Row>
              <Col>
                <Card>
                  <CardHeader>
                    <i className="fa fa-align-justify" /> Customer Debt
                  </CardHeader>
                  <CardBody>
                    <Table hover bordered striped responsive size="sm">
                      <thead>
                      <tr>
                        <th width={"10"} />
                        <th width={"15"}>No</th>
                        <th style={{ display: "none" }}>User</th>
                        <th style={{ display: "none" }}>Key</th>
                        <th style={{ display: "none" }}>CreatedUserKey</th>
                        <th width={"40"}>Total Debt</th>
                        <th width={"40"}>Received Amount</th>
                        <th scope={"row"}>Description</th>
                        <th width={"20"}>Payment Date</th>
                      </tr>
                      </thead>
                      <tbody>

                      {items.map(item => {
                        return (
                            <tr key={item.id}>

                              <td >
                                <ButtonDropdown
                                    isOpen={  this.state.table_dropdownMap.get(item.id) }
                                    toggle={  this.table_dropdownToggle }

                                    onClick={ () => {
                                      let updatedMap = new Map(this.table_dropdownMap);
                                      updatedMap.set(item.id, !updatedMap.get(item.id));
                                      this.setState({ table_dropdownMap: updatedMap });

                                      console.log("clicked : "+ item.id)
                                    }}
                                >
                                  <DropdownToggle caret >
                                    Process
                                  </DropdownToggle>
                                  <DropdownMenu>
                                    <DropdownItem >New Record</DropdownItem>
                                    <DropdownItem >Print All</DropdownItem>
                                    <DropdownItem>Action 3</DropdownItem>
                                    <DropdownItem divider />
                                    <DropdownItem>Another Action</DropdownItem>
                                  </DropdownMenu>
                                </ButtonDropdown>
                              </td>
                              <td>{item.id}</td>
                              <td style={{ display: "none" }}>{item.user}</td>
                              <td style={{ display: "none" }}>{item.debtKey}</td>
                              <td style={{ display: "none" }}> {item.createduserKey} </td>
                              <td>{item.totalDebt}</td>
                              <td>{item.receivedAmount}</td>
                              <td>{item.description}</td>
                              <td>{new Date(item.paymentDate).toLocaleString()}</td>
                            </tr>
                        )
                      })}
                      </tbody>
                    </Table>
                  </CardBody>
                </Card>
              </Col>
            </Row>
          </div>
      );
    }
  }
}
const mapStateToProps = state => {
  return state;
};
export default connect(mapStateToProps)(withAuth(CustomerDebt));

1 Ответ

0 голосов
/ 14 октября 2019

Вместо того, чтобы пытаться создать объект, который хранит каждое отдельное состояние переключателя кнопок, вы должны создать компонент для кнопки, который имеет автономное состояние для свойства переключателя. Поэтому создайте компонент DropdownButton следующим образом:

import React from 'react';
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';

export default class DropdownButton extends React.Component {
  constructor(props) {
    super(props);

    this.toggle = this.toggle.bind(this);
    this.state = {
      dropdownOpen: false
  };
}

toggle() {
  this.setState(prevState => ({
    dropdownOpen: !prevState.dropdownOpen
  }));
}

render() {
 return (
  <Dropdown isOpen={this.state.dropdownOpen} toggle={this.toggle}>
    <DropdownToggle caret>
      Dropdown
    </DropdownToggle>
    <DropdownMenu>
       <DropdownItem >New Record</DropdownItem>
        <DropdownItem >Print All</DropdownItem>
        <DropdownItem>Action 3</DropdownItem>
        <DropdownItem divider />
        <DropdownItem>Another Action</DropdownItem>
       </DropdownMenu>
     </Dropdown>
   );
 }
} 

Тогда вы можете использовать DropdownButton в качестве дочернего компонента:

<DropdownButton />

И он будет иметь автономное состояние переключения.

...