How to update data for table column in react?

微笑、不失礼 提交于 2020-04-18 05:35:16

问题


Hi i have problem with my table in bootstrap. I am getting data from server about timetable. This data i am saving in state. Next i am creating table. (Two ways of creating mobile and pc, just changing position of days and hours). Every column contains component SubjectColumn (there will be more data in one column like class and subject name). So when I click on this subject column i need to open modal with clicked subject data and after choosing of list of subjects in modal, I have to change subject for new one. I get subject data in my modal but i don't know how to change them for new one. Any idea please?


export class Schedule extends Component {
    static contextType = LoggedInuserContext;

    constructor(props) {
        super(props);
        this.state = {
            editMode: false,
            openModal: false,
            schedule: null,
            modalShow: false,
            mySubjects: null,
            selectedSubject:null
        };

        this.resize = () => this.forceUpdate();
    }

    changeModalState() {
        this.setState({modalShow: !this.state.modalShow})
    }


    selectSubject(subject){
        this.setState({selectedSubject:subject},this.changeModalState);
    }


    componentDidMount() {
        window.addEventListener('resize', this.resize)
        this.getTimeTable().then(r =>
            this.setState({isScheduleLoaded: true})
        );
        this.getMySubjects();
    }

    componentWillUnmount() {
        window.removeEventListener('resize', this.resize)
    }

    async getTimeTable() {
        if (this.context == null) return;
        const response = await fetch('UserController/GetTimeTable/' + this.context.user.id + '/' + this.context.company + '/' + this.context.role.id);
        this.setState({schedule: await response.json()});
    }

    async getMySubjects() {
        if (this.context == null) return;
        const response = await fetch('SubjectTreeController/GetUserSubjectsList/' + this.context.user.id + '/' + this.context.company + '/' + this.context.role.id);
        this.setState({mySubjects: await response.json()});
    }

    createContent() {
        if (!this.state.isScheduleLoaded === true) return;

        let header_data = [];
        let body_data = [];

        //For mobile else pc
        if (window.innerWidth < 768) {
            //Header of table
            this.state.schedule.days.forEach(day => {
                header_data.push(day.name.substring(0, 2))
            });

            //Body of table
            for (let i = 0; i < this.state.schedule.days[0].slots.length; i++) {
                let row = {
                    firstColumn: i,
                    other: []
                };
                this.state.schedule.days.forEach((day, key) => {
                    row.other.push(day.slots[i]);
                });

                body_data.push(row);
            }
        } else {
            //Header of table
            this.state.schedule.days[0].slots.forEach(slot => {
                header_data.push(slot.order)
            });

            //Body of table
            this.state.schedule.days.forEach(day => {
                let row = {
                    firstColumn: [],
                    other: []
                };
                row.firstColumn.push(day.name);
                day.slots.map(slot => row.other.push(slot));
                body_data.push(row);
            });
        }

        let head = this.createTableHead(header_data);
        let body = this.createRows(body_data);

        return (
            <>
                <thead>
                {head}
                </thead>
                <tbody>
                {body}
                </tbody>
            </>
        );
    }

    createTableHead(data) {
        return (
            <tr>
                <td></td>
                {data.map((d, k) => {
                    return (<th key={k} className={"text-center"}> {d} </th>)
                })}
            </tr>
        );
    }

    createRows(data) {
        const items = [];
        for (let i = 0; i < data.length; i++) {
            const row = [];

            for (let j = 0; j < data[i].other.length; j++) {
                if (data[i].other[j].subject !== null) {
                    row.push(<td key={j} className={"text-center "}><SubjectColumn editMode={this.state.editMode}
                                                                                   subject={data[i].other[j].subject}
                                                                                    selectSubject={this.selectSubject.bind(this)}>
                    </SubjectColumn>
                    </td>);
                } else {
                    row.push(<td key={j} className={"text-center "}><SubjectColumn editMode={this.state.editMode}
                                                                                   subject={null}
                                                                                   selectSubject={this.selectSubject.bind(this)}
                                                                                   >
                                                                                   </SubjectColumn>
                    </td>);
                }
            }

            items.push(
                <tr key={i}>
                    <td>{data[i].firstColumn}</td>
                    {row}
                </tr>
            );
        }
        return items;

    }

    loading() {
        if (this.state.schedule === null)
            return (
                <div className={"d-flex flex-column justify-content-center text-center"}>
                    <div>
                        <Spinner animation="grow" variant="success"/>
                        <Spinner animation="grow" variant="danger"/>
                        <Spinner animation="grow" variant="warning"/>
                    </div>
                    <span>Načítam rozvrh</span>
                </div>
            );
    }

    showActionButtons() {
        const items = [];

        if (this.state.editMode) {
            items.push(<Button key={"save"} className={"px-4 mx-1"} variant={"success"}
                               onClick={this.startEditing.bind(this)}>Uložiť</Button>)
        }
        items.push(
            <Dropdown key={"settings"} alignRight>
                <Dropdown.Toggle variant="dark" id="dropdown-basic">
                    <FontAwesomeIcon icon={faCog} size={"lg"}/>
                </Dropdown.Toggle>

                <Dropdown.Menu>
                    <Dropdown.Item onClick={this.startEditing.bind(this)}>Edituj rozvrh</Dropdown.Item>
                </Dropdown.Menu>
            </Dropdown>
        );
        return items;
    }

    startEditing() {
        this.setState({editMode: !this.state.editMode});
    }


    openScheduleSetting() {
        console.log("open");
//        this.setState({openModal: true});
    }

    closeScheduleSetting() {
        console.log("close");

        //      this.setState({openModal: false});
    }

    render() {
        return (
            <div className={"w-100"} id="schedule">
                <div className={"d-flex justify-content-center my-2"}>
                    <h3 className={"my-1 text-left flex-grow-1  pl-2"}>Rozvrh hodín</h3>
                    {this.showActionButtons()}
                </div>
                <Table striped bordered hover>
                    {this.createContent()}
                </Table>
                {this.loading()}
                <ScheduleSelectModal subject={this.state.selectedSubject} subjectslist={this.state.mySubjects} show={this.state.modalShow} onHide={this.changeModalState.bind(this)}>
                </ScheduleSelectModal>
            </div>
        );
    }
}

SubjectColumn

export class SubjectColumn extends Component {

    showModalInParrent(){
        console.log(this.props);
        this.props.selectSubject(this.props.subject);
    }

    createCell() {
        let items = null;
        if (this.props.editMode) {
            if(this.props.subject === null){
                return (  <Button className={"w-100 h-100"} onClick={this.showModalInParrent.bind(this)}>  </Button>)
            }

            items = (
                <Fragment>
                    <Button className={"w-100 h-100"} onClick={this.showModalInParrent.bind(this)}> {this.props.subject.acronym } </Button>
                </Fragment>
            );
            return items;
        } else {
            if(this.props.subject === null){
            return;
            }

            return (this.props.subject.acronym  );
        }
    }

    render() {
        return (
            <div className="w-100 h-100">
                {this.createCell()}
            </div>
        );
    }
}

Modal:

import React, {Component, Fragment} from "react";
import Modal from "react-bootstrap/Modal";
import ButtonGroup from "react-bootstrap/ButtonGroup";
import Button from "react-bootstrap/Button";

export class ScheduleSelectModal extends Component {

   componentDidUpdate(prevProps, prevState, snapshot) {
       console.log("modal props:");
       console.log(this.props.subject);
   }

    createList() {
        let items = [];
        if (this.props.subjectslist !== null)
            this.props.subjectslist.map(subject =>
                items.push(<Button key={subject.id} block className={"my-1"}>{subject.name} </Button>)
            );

        return items;
    }

    renderHeader(){
       if(this.props.subject === null){
           return(
               <p>
                   Vyberťe subjekt ktorý chcete nahradiť
               </p>
           )
       }
       else{
          return(   <p>
              {this.props.subject.name }
          </p>);
        }
    }

    render() {
        return (
            <Modal
                {...this.props}
                size="lg"
                aria-labelledby="contained-modal-title-vcenter"
                centered
            >
                <Modal.Header closeButton>
                    <Modal.Title id="contained-modal-title-vcenter">
                        {this.renderHeader()}
                    </Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    <ButtonGroup vertical className={"w-100"}>
                        {this.createList()}
                    </ButtonGroup>
                </Modal.Body>
            </Modal>
        );
    }
}

This loos like my shedule object

Object
id: 1
dateUpdated: "2020-03-24T17:36:48.66"
days: Array(5)
0: {slots: Array(8), id: 1, order: 1, name: "Pondelok", acronym: "PO", …}
1:
slots: Array(8)
0: {order: 0, subject: null, studentGroup: null}
1: {order: 1, subject: null, studentGroup: null}
2: {order: 2, subject: {…}, studentGroup: null}
3:
order: 3
subject:
note: ""
id: 5
name: "Biológia"
acronym: "B"
__proto__: Object
studentGroup: null
__proto__: Object
4: {order: 4, subject: {…}, studentGroup: null}
5: {order: 5, subject: null, studentGroup: null}
6: {order: 6, subject: null, studentGroup: null}
7: {order: 7, subject: null, studentGroup: null}
length: 8
__proto__: Array(0)
id: 2
order: 2
name: "Utorok"
acronym: "UT"
isWeekend: 0
__proto__: Object
2: {slots: Array(8), id: 3, order: 3, name: "Streda", acronym: "ST", …}
3: {slots: Array(8), id: 4, order: 4, name: "Štvrtok", acronym: "ŠT", …}
4: {slots: Array(8), id: 5, order: 5, name: "Piatok", acronym: "PIA", …}
length: 5
__proto__: Array(0)
__proto__: Object

回答1:


If I've undeerstood your q, this might work for you:

  1. In the modal where you show selectedSubject, replace each value (text) you want to edit with input element.
  2. changing value in input should update state.selectedSubject in Schedule component or you might have state in modal to capture edited selectedSubject, but why duplicating data if you don't have to. I would go with updating parent component state.
  3. Schedule component should have method which will make put (or patch) request with edited data.
  4. Pass this method to the modal.
  5. Add "Save" button to the modal. When you finish editing, clicking on "Save" button should fire passed method.
  6. Optional: you can have success message in your modal (success or error)


来源:https://stackoverflow.com/questions/60979021/how-to-update-data-for-table-column-in-react

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