最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is it possible to make fields required on material-table - Stack Overflow

programmeradmin9浏览0评论

I am working on a project, where I basically do crud using material-table interface. I am wondering is there a way if I can make fields required if I want too?

I tried researching but not much results. Please see the code below which is straight forward from / last example. Of course I have modified on my codebase for my personal use and everything works fine, but I am not sure how is it possible to make fields required if I want too? If yes, how would I do it? Would I pass something as a prop option on MaterialTable ?

Thank you for any suggestions.

import React from 'react';
import MaterialTable from 'material-table';

export default function MaterialTableDemo() {
  const [state, setState] = React.useState({
    columns: [
      { title: 'Name', field: 'name' },
      { title: 'Surname', field: 'surname' },
      { title: 'Birth Year', field: 'birthYear', type: 'numeric' },
      {
        title: 'Birth Place',
        field: 'birthCity',
        lookup: { 34: 'İstanbul', 63: 'Şanlıurfa' },
      },
    ],
    data: [
      { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
      {
        name: 'Zerya Betül',
        surname: 'Baran',
        birthYear: 2017,
        birthCity: 34,
      },
    ],
  });

  return (
    <MaterialTable
      title="Editable Example"
      columns={state.columns}
      data={state.data}
      editable={{
        onRowAdd: newData =>
          new Promise(resolve => {
            setTimeout(() => {
              resolve();
              const data = [...state.data];
              data.push(newData);
              setState({ ...state, data });
            }, 600);
          }),
        onRowUpdate: (newData, oldData) =>
          new Promise(resolve => {
            setTimeout(() => {
              resolve();
              const data = [...state.data];
              data[data.indexOf(oldData)] = newData;
              setState({ ...state, data });
            }, 600);
          }),
        onRowDelete: oldData =>
          new Promise(resolve => {
            setTimeout(() => {
              resolve();
              const data = [...state.data];
              data.splice(data.indexOf(oldData), 1);
              setState({ ...state, data });
            }, 600);
          }),
      }}
    />
  );
}

I am working on a project, where I basically do crud using material-table interface. I am wondering is there a way if I can make fields required if I want too?

I tried researching but not much results. Please see the code below which is straight forward from https://material-ui./ponents/tables/ last example. Of course I have modified on my codebase for my personal use and everything works fine, but I am not sure how is it possible to make fields required if I want too? If yes, how would I do it? Would I pass something as a prop option on MaterialTable ?

Thank you for any suggestions.

import React from 'react';
import MaterialTable from 'material-table';

export default function MaterialTableDemo() {
  const [state, setState] = React.useState({
    columns: [
      { title: 'Name', field: 'name' },
      { title: 'Surname', field: 'surname' },
      { title: 'Birth Year', field: 'birthYear', type: 'numeric' },
      {
        title: 'Birth Place',
        field: 'birthCity',
        lookup: { 34: 'İstanbul', 63: 'Şanlıurfa' },
      },
    ],
    data: [
      { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
      {
        name: 'Zerya Betül',
        surname: 'Baran',
        birthYear: 2017,
        birthCity: 34,
      },
    ],
  });

  return (
    <MaterialTable
      title="Editable Example"
      columns={state.columns}
      data={state.data}
      editable={{
        onRowAdd: newData =>
          new Promise(resolve => {
            setTimeout(() => {
              resolve();
              const data = [...state.data];
              data.push(newData);
              setState({ ...state, data });
            }, 600);
          }),
        onRowUpdate: (newData, oldData) =>
          new Promise(resolve => {
            setTimeout(() => {
              resolve();
              const data = [...state.data];
              data[data.indexOf(oldData)] = newData;
              setState({ ...state, data });
            }, 600);
          }),
        onRowDelete: oldData =>
          new Promise(resolve => {
            setTimeout(() => {
              resolve();
              const data = [...state.data];
              data.splice(data.indexOf(oldData), 1);
              setState({ ...state, data });
            }, 600);
          }),
      }}
    />
  );
}
Share Improve this question asked Sep 17, 2019 at 19:56 sci_dudesci_dude 2041 gold badge3 silver badges13 bronze badges 4
  • 2 The documentation has an example of a custom editable ponent, showing a simple input, to which you could add the required attribute. – Heretic Monkey Commented Sep 17, 2019 at 20:01
  • @HereticMonkey I looked before, and even now, I don't see the example for making inputs/fields required, only for readonly but not making editable, maybe I am missing something. Thank you. – sci_dude Commented Sep 17, 2019 at 20:13
  • 5 As I mentioned, use the one for a Custom Edit Component. The last one at the bottom of the screen. You see that? Look at the code. It has a property, editComponent that shows the use of an input element. it has type="text". To that, you can add required as an attribute (as the link I provided shows). The required attribute is not part of the example. I'm telling you to add it your self. This is what programming is all about. Taking examples and going further with them. – Heretic Monkey Commented Sep 18, 2019 at 0:19
  • @HereticMonkey I pletely agree about taking examples and going further with them. Thank you for being thorough. – sci_dude Commented Sep 18, 2019 at 13:06
Add a ment  | 

4 Answers 4

Reset to default 9

Material-table has native support for validation which can trivially be used to make a field required. All you have to do is specify the validation field in the columns specification as per docs here: https://material-table./#/docs/features/validation.

Here's what that would look like for your code, say if you wanted to make the "Surname" required:

...
  const [state, setState] = React.useState({
    columns: [
      { title: 'Name', field: 'name' },
      {
          title: 'Surname',
          field: 'surname',
          validate: rowData => Boolean(rowData.surname),
      },
      { title: 'Birth Year', field: 'birthYear', type: 'numeric' },
      {
        title: 'Birth Place',
        field: 'birthCity',
        lookup: { 34: 'İstanbul', 63: 'Şanlıurfa' },
      },
    ],
    data: [
      { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
      {
        name: 'Zerya Betül',
        surname: 'Baran',
        birthYear: 2017,
        birthCity: 34,
      },
    ],
  });
...

p.s. there's no need to put your columns data in the state here unless it's going to change, which seems unlikely in this case.

@HereticMonkey's ment essentially solves my question.

Making fields required is done through editable ponents as example shown by Heretic Monkey ^^.

Thank you

You need to use editComponent,TextField and validation handling on onRowAdd and onRowUpdate.

See below sample revise code.

import React from "react";
import MaterialTable from "material-table";
import TextField from "@material-ui/core/TextField";

export default function App() {

const [nameError, setNameError] = React.useState({
    error: false,
    label: "",
    helperText: "",
    validateInput: false,
});

const columnsHeader = [
    {
        title: "Name",
        field: "name",
        editComponent: (props) => (
            <TextField
                type="text"
                error={
                    !props.value &&
                    nameError.validateInput &&
                    props.rowData.submitted
                        ? nameError.error
                        : false
                }
                helperText={
                    !props.value &&
                    nameError.validateInput &&
                    props.rowData.submitted
                        ? nameError.helperText
                        : ""
                }
                value={props.value ? props.value : ""}
                onChange={(e) => {
                    if (nameError.validateInput) {
                        setNameError({
                            ...nameError,
                            validateInput: false,
                        });
                    }

                    props.onChange(e.target.value);
                }}
            />
        ),
    },
    { title: "Surname", field: "surname" },
    { title: "Birth Year", field: "birthYear", type: "numeric" },
    {
        title: "Birth Place",
        field: "birthCity",
        lookup: { 34: "İstanbul", 63: "Şanlıurfa" },
    },
    { title: "submitted", field: "submitted", hidden: true },
];

const [state, setState] = React.useState({
    data: [
        {
            name: "Mehmet",
            surname: "Baran",
            birthYear: 1987,
            birthCity: 63,
            submitted: false,
        },
        {
            name: "Zerya Betül",
            surname: "Baran",
            birthYear: 2017,
            birthCity: 34,
            submitted: false,
        },
    ],
});

return (
    <MaterialTable
        title="Editable Example"
        columns={columnsHeader}
        data={state.data}
        editable={{
            onRowAdd: (newData) =>
                new Promise((resolve, reject) => {
                    setTimeout(() => {
                        newData.submitted = true;
                        if (!newData.name) {
                            setNameError({
                                error: true,
                                label: "required",
                                helperText: "Name is required.",
                                validateInput: true,
                            });
                            reject();
                            return;
                        }
                        resolve();

                        const data = [...state.data];
                        data.push(newData);
                        setState({ ...state, data });
                    }, 600);
                }),
            onRowUpdate: (newData, oldData) =>
                new Promise((resolve, reject) => {
                    setTimeout(() => {
                        newData.submitted = true;
                        if (!newData.name) {
                            setNameError({
                                error: true,
                                label: "required",
                                helperText: "Name is required.",
                                validateInput: true,
                            });
                            reject();
                            return;
                        }
                        resolve();
                        const data = [...state.data];
                        data[data.indexOf(oldData)] = newData;
                        setState({ ...state, data });
                    }, 600);
                }),
            onRowDelete: (oldData) =>
                new Promise((resolve) => {
                    setTimeout(() => {
                        resolve();
                        const data = [...state.data];
                        data.splice(data.indexOf(oldData), 1);
                        setState({ ...state, data });
                    }, 600);
                }),
        }}
    />
);

}

just validate and use Reject() like this ( calling reject() keeps open row editable ):

 onRowAdd: (newData) =>
        new Promise((resolve) => {
          if(---!validate(newData)---) {
            // alert('required');
            reject();
          }else{ /*addRow*/ }
发布评论

评论列表(0)

  1. 暂无评论