Form with MUI and Table with AntD
Creating Form with MUI and Table with Ant Design
In the last doc, we learned how to create a form and a table with basic react tags. Now just to give you an idea of how many libraries there are that reduce the amount of time and code we need to write. In this I am using two very useful libraries: Material UI and Ant Design.
Material UI for creating form and Ant Design for creating table. I am using two different libraries just to give you an idea of how many libraries there are. You can use any library you want.
I will make changes to the previous code. So, I will not repeat the code from the previous blog. I will only change the code from the previous blog. If you did not read the previous blog, please read it first.
Creating a Form
I am using Material UI for creating a form. First I am importing the Material UI library.
import "antd/dist/antd.css";
import {
Typography,
AppBar,
Toolbar,
TextField,
Button,
} from "@material-ui/core";
I'll use the same onSubmit that I was in the previous blog.
Now I am creating a form. I am creating a form with the <form> tag. I am creating a form with the <form> tag. I will use @material-ui/core's TextField, Button that I imported earlier. TextField has a lot of properties that I can use. But for now, I will use only style, type, label, variant, name, and required
Let's do it.
<form onSubmit={onSubmit}>
<TextField
style={customStyle}
type="text"
label="Name"
variant="outlined"
name="name"
required
/>
<TextField
style={customStyle}
type="text"
label="Author"
variant="outlined"
name="author"
required
/>
<TextField
style={customStyle}
type="number"
inputProps={{ min: 0 }}
label="Price"
variant="outlined"
name="price"
required
/>
<TextField
style={customStyle}
type="number"
inputProps={{ min: 0 }}
label="Stock"
variant="outlined"
name="stock"
required
/>
<Button style={customStyle} variant="contained" color="primary" type="submit">
Save
</Button>
</form>
Now explain TextField's properties.
style
I am using the style property to set the style of the TextField like this style={customStyle}. I created a customStyle object with the style for the TextField. And assign it to the style property of all the TextFields, and Button, instead of applying the style to all the elements.
Here is the code for the customStyle object:
const customStyle = {
margin: "5px",
marginTop: "10px",
marginBottom: "10px",
width: "100%",
height: "50px",
borderRadius: "5px",
fontSize: "16px",
};
type
I am using the type property to set the type of the TextField. You see in type property of the first two TextField that I am using the type="text". Cause there data is text. And in the last two, I am using type="number". Cause there data is a number.
inputProps
You can use the inputProps property to set the properties of the input. For example, in the first TextField I am using inputProps={{ min: 0 }}. This means that the input will have a minimum value of 0.
label
I am using the label property to set the label of the TextField. I am using label="Name" for the first TextField and label="Author" for the second TextField.
variant
I am using the variant property to set the variant of the TextField. I am using variant="outlined".
name
I am using the name property to set the name of the TextField. Name is used to identify the TextField in the form. It helps to get the value of the TextField. I used it when I was submitting the form.
required
You see I used the required property to make the field required. It will display an error message if the field is empty while submitting the form
Creating a Table
I am using Ant Design to create a table. First I am importing the Ant Design library.
import { Table, Button } from "antd";
In the previous doc I created a table with the <table> tag, then I used <tr>, <th>, and <td> tags to create a table. But with Ant Design, I can create a table with the <Table> tag. It will take a few properties to create a table, but I will not explain all the properties, for now, I will only two properties: columns and dataSource.
First of all, I am creating a table with the <Table> tag.
<Table columns={columns} dataSource={books} />
columns
In Ant Design's table, there are property name columns. It's an array of objects. Each object is a column that has a property name title, dataIndex, key, and render.
These are the columns that I used in the blog.
const columns = [
{
title: "Name",
dataIndex: "name",
key: "name",
},
{
title: "Author",
dataIndex: "author",
key: "author",
},
{
title: "Price",
dataIndex: "price",
key: "price",
},
{
title: "Stock",
dataIndex: "stock",
key: "stock",
},
{
title: "Action",
key: "action",
render: (text, record) => (
<AntDButton color="primary" onClick={() => deleteBook(record._id)}>
Delete
</AntDButton>
),
},
];
The title means the name of the column. DataIndex means the name of the property in the object (Data Source). Key means the name of the column. Render means the function that I will use to create the column.
I used the render function to create a button that will delete the book. I used the onClick property to call the function deleteBook. Render is a function that takes two parameters: text and record. The text is the text in the cell. The record is the object that I am using in the table. I used the record._id to get the ID of the book.
The render function is used if we want to use tags in the table.
dataSource
In Ant Design's table, there's property name dataSource. It's an array of objects. Each object is a book. I created an array of books using React.useState in the previous blog. I simply assign the array of books to the dataSource property.
Final Code
Final code after I finished the blog.
import "./App.css";
import axios from "axios";
import React from "react";
import {
Typography,
AppBar,
Toolbar,
TextField,
Button as MuiButton,
} from "@material-ui/core";
import "antd/dist/antd.css";
import { Table, Button as AntDButton } from "antd";
function App() {
/*
useState is a hook that allows us to create a state variable in our component and also update it when we want to.
It takes a single argument, the initial value of the state variable. We can then use this state variable to update the component.
We can also use this state variable to get the current value of the state variable.
*/
const [books, setBooks] = React.useState([]);
// useEffect is a hook that runs after the component is rendered, but before the component is updated.
React.useEffect(() => {
// This is to get the list of books from the backend.
axios
.get("http://localhost:2022/book")
.then((response) => {
// Once we get the list of books, we need to set the state of the component with the list of books.
setBooks(response.data);
})
.catch((error) => {
// If the backend is not running, this will throw an error. So we need to handle it.
// I am adding book to the list, and it will be displayed in the UI.
const book = {
_id: (books.length + 1).toString(),
name: "Default Book",
author: "Default Author",
price: 0,
stock: 0,
};
// I am adding book to the list, and it will be displayed in the UI.
setBooks([book]);
});
});
const onSubmit = async (e) => {
// e.preventDefault prevents page from refreshing when form is submitted (default behavior)
e.preventDefault();
// This is body of the request, we can send it as a json object
const book = {
name: e.target.name.value,
author: e.target.author.value,
price: parseInt(e.target.price.value),
stock: parseInt(e.target.stock.value),
};
axios
.post("http://localhost:2022/book", book)
.then(async (res) => {
// Once the book is added, we need to get the list of books
const bookList = await axios.get("http://localhost:2022/book");
// And render the list of books in the UI. I am reassigning the state with the new list of books
setBooks(bookList.data);
})
.catch((err) => {
// If backend is not running, this will throw an error. So we need to handle it.
// I am adding book to the list, and it will be displayed in the UI.
book._id = (books.length + 1).toString();
const tempBooks = [...books, book];
setBooks(tempBooks);
})
.finally(() => {
// This is to clear the form after submitting.
e.target.name.value = "";
e.target.author.value = "";
e.target.price.value = "";
e.target.stock.value = "";
});
};
const deleteBook = async (id) => {
// This is to delete the book from the list.
axios
.delete(`http://localhost:2022/book/${id}`)
.then(async (res) => {
// Once the book is deleted, we need to get the list of books
const bookList = await axios.get("http://localhost:2022/book");
// And render the list of books in the UI. I am reassigning the state with the new list of books
setBooks(bookList.data);
})
.catch((err) => {
// If backend is not running, this will throw an error. So we need to handle it.
// I am deleting the book from the list, and it will be removed from the UI.
const tempBooks = books.filter((book) => book._id !== id);
setBooks(tempBooks);
});
};
const columns = [
{
title: "Name",
dataIndex: "name",
key: "name",
},
{
title: "Author",
dataIndex: "author",
key: "author",
},
{
title: "Price",
dataIndex: "price",
key: "price",
},
{
title: "Stock",
dataIndex: "stock",
key: "stock",
},
{
title: "Action",
key: "action",
render: (text, record) => (
<AntDButton color="primary" onClick={() => deleteBook(record._id)}>
Delete
</AntDButton>
),
},
];
const customStyle = {
margin: "5px",
marginTop: "10px",
marginBottom: "10px",
width: "100%",
height: "50px",
borderRadius: "5px",
fontSize: "16px",
};
return (
<div className="App">
<h1>Book Store</h1>
<AppBar>
<Toolbar>
<Typography variant="h6" color="inherit">
Book Store
</Typography>
</Toolbar>
</AppBar>
<div style={{ marginTop: "30px" }} />
<Typography variant="h5" color="primary">
Add Book
</Typography>
<form onSubmit={onSubmit}>
<TextField
style={customStyle}
type="text"
label="Name"
variant="outlined"
name="name"
required
/>
<TextField
style={customStyle}
type="text"
label="Author"
variant="outlined"
name="author"
required
/>
<TextField
style={customStyle}
type="number"
inputProps={{ min: 0 }}
label="Price"
variant="outlined"
name="price"
required
/>
<TextField
style={customStyle}
type="number"
inputProps={{ min: 0 }}
label="Stock"
variant="outlined"
name="stock"
required
/>
<MuiButton
style={customStyle}
variant="contained"
color="primary"
type="submit"
>
save
</MuiButton>
</form>
<Typography variant="h5" color="primary">
Books
</Typography>
<Table columns={columns} dataSource={books} />
</div>
);
}
export default App;
Code
You can get the complete code from here
Conclusion
In this article, we have learned how to use Material UI and Ant Design in React. We have also learned how to use Ant Design Table and Material UI Button in the same project. We have also learned how to use Material UI TextField and Ant Design Button in the same project. We have also learned how to use Ant Design Table and Material UI Button in the same project. We have also learned how to use Material UI TextField and Ant Design Button in the same project.