Material-table example ReactJS

There are a lot of scenarios in Material-table that you might have difficulty in understanding from the documentation or may be scattered on different forums. I’ll try to cover up the scenarios which I faced while implementing a table in my Project with Actions like Add/Edit/Delete. Another scenario is to make it read-only i.e. remove all the Action buttons.

This is the sample courses React App over which I’ll develop further using Material-Table. You can get the code from the Github Project here. To get started, you’ll need the following packages:

npm i @material-ui/core
npm i @material-ui/icons
npm i @material-ui/lab
npm i material-table
npm i axios

The actions are managed through uncontrolled fields i.e. without managing through state directly. The API calls are as per my example and URL placeholder requires to be updated as per your API host name.

The columns and icons are set in the state. autoFocus property is set to the first TextField for edit mode.

The options prop which I’ve used has Paging, sorting and dragging of columns disabled. Sorting and draggable can simply be set to true and used.

To make the table read-only, the editable prop of Material Table can be set to null conditionally. I’ve used isReadOnly boolean to add the condition, you can have your own state here.

render() {
    const { classes } = this.props;
    return (
      <Fragment>
         <div
            id={this.props.id}
          >
            <MaterialTable
              components={{
                EditRow: (props) => {
                  return (
                    <MTableEditRow
                      {...props}
                      onEditingCanceled={(mode, rowData) => {
                        this.canceledClicked();
                        props.onEditingCanceled(mode);
                      }}
                    />
                  );
                },
              }}
              title=""
              columns={this.state.columns}
              data={this.state.StudentsEnrolled}
              icons={this.state.tableIcons}
              isLoading={this.state.showLoading}
              style={{
                border: "2px solid gray",
                maxWidth: "1450px",
                overflow: "scroll",
                marginTop: "10px",
                marginLeft: "20px",
              }}
              editable={
                isReadOnly
                ? null
                : 
                {
                onRowAdd: (newData) =>
                  new Promise((resolve, reject) => {
                    newData.studentName =
                      studentName_GRC === null ? "" : studentName_GRC;
                    
                    newData.grade = grade_GR === null ? "" : grade_GR;

                    newData.courseName = courseName_GR === null ? "" : courseName_GR;

                    newData.comments = comments_GR === null ? "" : comments_GR;

                    var errorMsg = " ";

                    if (newData.studentName === "") {
                      errorMsg = "Please insert Student Name.";
                    }
                    if (newData.grade === "") {
                      errorMsg = errorMsg + "\nPlease insert grade.";
                    }
                    if (newData.courseName === "") {
                      errorMsg = errorMsg + "\nPlease insert course Name.";
                    }

                    if (errorMsg !== " ") {
                      reject();
                      alert(errorMsg);
                    } else if (this.state.countGrid >= GridDataLimit) {
                      reject();
                      alert(
                        "You cannot add more than " +
                          GridDataLimit +
                          " Students to the list."
                      );
                    } else {
                      this.setState({ showLoading: true });
                      this.postStudentsEnrolledData(newData);
                      resolve();
                    }
                    // }, 600);
                  }),
                onRowUpdate: (newData, oldData) =>
                  new Promise((resolve, reject) => {
                    // setTimeout(() => {
                    //resolve();

                    if (oldData) {
                      newData.studentName =
                        studentName_GRC === null
                          ? oldData.studentName
                          : studentName_GRC === ""
                          ? ""
                          : studentName_GRC;

                      newData.grade =
                        grade_GR === null
                          ? oldData.grade
                          : grade_GR === ""
                          ? ""
                          : grade_GR;

                      newData.courseName =
                        courseName_GR === null
                          ? oldData.courseName
                          : courseName_GR === ""
                          ? ""
                          : courseName_GR;

                      newData.comments =
                        comments_GR === null
                          ? oldData.comments
                          : comments_GR === ""
                          ? ""
                          : comments_GR;

                      var errorMsg = " ";
                      if (newData.studentName === "") {
                        errorMsg = "Please insert Student Name.";
                      }
                      if (newData.grade === "") {
                        errorMsg = errorMsg + "\nPlease insert grade.";
                      }
                      if (newData.courseName === "") {
                        errorMsg = errorMsg + "\nPlease insert course Name.";
                      }
                      if (errorMsg !== " ") {
                        reject();
                        alert(errorMsg);
                      } else {
                        this.setState({ showLoading: true });
                        this.postStudentsEnrolledData(newData);
                        resolve();
                      }
                    }
                    // }, 600);
                  }),
                onRowDelete: (oldData) =>
                  new Promise((resolve) => {
                    // setTimeout(() => {
                    this.setState({ showLoading: true });
                    this.deleteStudentsEnrolledData(oldData);
                    resolve();
                    // }, 600);
                  }),
              }}
              options={{
                paging: false,
                sorting: false,
                draggable: false,
                addRowcourseName:"first",
                rowStyle: { backgroundColor: "#fff" },
              }}
            />
          </div>
      </Fragment>
    );
  }

The isLoading prop manages the hide/show of loader when an action is performed.

There is one more scenario where clicking outside the + icon, doesn’t trigger the onAddRowClick event. This is handled in componentDidMount method.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.