我想要这个来自 Macial UI Text Field 的 TextField 组件
<TextField
value={value}
label='Ana iş Adımı'
multiline
onChange={onChange}
placeholder=' '
error={Boolean(errors.definition)}
aria-describedby='validation-basic-definition'
sx={{ mb: 2, backgroundColor: isUpdateMode && '#EBF3F7', rounded: 4 }}
/>
最大长度为 255 个字符。如果超过 255 个字符的限制,我希望在下面显示一条红色警告消息,如下图所示:pic,但我不想只包含
<TextField
...
inputProps={{ maxLength: 255 }}
/>
到文本字段,因为它不显示红色警告消息。它仅强制执行字符限制。我的整个页面是:
import React, {useEffect, useState} from "react";
import Grid from "@mui/material/Grid";
import Typography from "@mui/material/Typography";
import Box from "@mui/material/Box";
import Tooltip from "@mui/material/Tooltip";
import IconButton from "@mui/material/IconButton";
import Icon from "../../../@core/components/icon";
import {Controller, useForm} from "react-hook-form";
import restClient from "../../../rest/client";
import mappings from "../../../mappings/mapping";
import toast from "react-hot-toast";
import Card from "@mui/material/Card";
import CardHeader from "@mui/material/CardHeader";
import CardContent from "@mui/material/CardContent";
import FormControl from "@mui/material/FormControl";
import TextField from "@mui/material/TextField";
import FormHelperText from "@mui/material/FormHelperText";
import InputLabel from "@mui/material/InputLabel";
import Select from "@mui/material/Select";
import MenuItem from "@mui/material/MenuItem";
import Button from "@mui/material/Button";
import {
DataGrid, gridPageCountSelector, GridPagination,
GridToolbarContainer,
GridToolbarExport,
GridToolbarFilterButton, GridToolbarQuickFilter,
useGridApiContext, useGridSelector
} from "@mui/x-data-grid";
import DeleteDialog from "../../../views/components/company/DeleteDialog";
import MuiPagination from "@mui/material/Pagination";
import secureLocalStorage from "react-secure-storage";
const defaultValues = {
id: '',
definition: '',
orderNo: '',
companyRequest: null,
};
function CustomToolbar() {
return (
<GridToolbarContainer>
<GridToolbarQuickFilter/>
</GridToolbarContainer>
);
}
function Pagination({page, onPageChange, className}) {
const apiRef = useGridApiContext();
const pageCount = useGridSelector(apiRef, gridPageCountSelector);
return (
<MuiPagination
color="warning"
className={className}
count={pageCount}
page={page + 1}
onChange={(event, newPage) => {
onPageChange(event, newPage - 1);
}}
/>
);
}
function CustomPagination(props) {
return <GridPagination ActionsComponent={Pagination} {...props} />;
}
const CompanyJobDescription = () => {
const [companyJobDescriptionLList, setCompanyJobDescriptionList] = useState([]);
const [selectedId, setSelectedId] = useState();
const [openDelete, setOpenDelete] = useState(false);
const [isUpdateMode, setIsUpdateMode] = useState(false);
const {
control,
handleSubmit,
formState: { errors },
reset,
setValue,
watch: valueWatch
} = useForm({
defaultValues,
});
const columns = [
{
flex: 0.01,
minWidth: 100,
headerName: 'S.N',
field: 'orderNo',
renderCell: (params) => (
<Typography variant="body2" sx={{ color: 'text.primary' }}>
{params.row.orderNo}
</Typography>
)
},
{
flex: 1,
minWidth: 200,
field: 'definition',
headerName: 'Ana İş Adımı',
renderCell: (params) => (
<Typography
variant="body2"
sx={{ color: 'text.primary', whiteSpace: 'pre-wrap', overflow: 'auto', maxHeight: '50px', pt: 1 }}
>
{params.row.definition}
</Typography>
)
},
{
flex: 0.05,
minWidth: 140,
field: 'actions',
headerName: 'İşlemler',
renderCell: (params) => {
const id = valueWatch("id");
return (
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Tooltip title="Düzenle">
<IconButton
size="small"
color="warning"
sx={{ mr: 0.5 }}
onClick={() => updateJobDescription(params)}
>
<Icon icon="mi:edit" />
</IconButton>
</Tooltip>
<Tooltip title="Sil">
<IconButton
size="small"
color="error"
onClick={() => showDeleteModal(params)}
>
<Icon icon="mdi:delete-outline" />
</IconButton>
</Tooltip>
{id === params.row.id && (
<Tooltip title='Güncellemeyi İptal Et'>
<IconButton size='small' color="error" onClick={resetForm}>
<Icon icon='material-symbols:cancel-outline' />
</IconButton>
</Tooltip>
)}
</Box>
);
}
}
];
const handleConfirmDelete = () => {
deleteCompanyJobDescription(selectedId);
setOpenDelete(false);
};
const updateJobDescription = params => {
const { id, definition, orderNo } = params.row;
setValue('id', id);
setValue('orderNo', orderNo);
setValue('definition', definition);
setIsUpdateMode(true); // Güncelleme modunu etkinleştir
};
const showDeleteModal = (params) => {
setSelectedId(params.row.id);
setOpenDelete(true);
};
const deleteCompanyJobDescription = (selectedId) => {
restClient.delete(mappings.companyJobDescription.deleteCompanyJob(selectedId)).then(() => {
getCompanyJobDescription();
setOpenDelete(false);
toast.success("Görev Tanımı başarıyla silindi.");
}).catch(() => {
toast.error("Görev Tanımı silinirken hata oluştu.");
});
};
const getCompanyJobDescription = () => {
const company = JSON.parse(secureLocalStorage.getItem("companyInfo"));
restClient.get(mappings.companyJobDescription.getCompanyJobDescriptionByCompanyId(company?.id)).then(res => {
setCompanyJobDescriptionList(res.data.data);
});
};
useEffect(getCompanyJobDescription, []);
const onSubmit = (companyJobDescription) => {
companyJobDescription.companyRequest = JSON.parse(secureLocalStorage.getItem("companyInfo"));
const isOrderNoUnique = !companyJobDescriptionLList.some(
(item) => item.orderNo === parseInt(companyJobDescription.orderNo) && item.id !== companyJobDescription.id
);
if (!isOrderNoUnique) {
toast.error("Bu sıra numarası zaten mevcut. Lütfen farklı bir sıra numarası girin.");
return;
}
restClient.post(mappings.companyJobDescription.addCompanyJobDescription(), companyJobDescription)
.then(() => {
toast.success("Görev Tanımı başarıyla kaydedildi.");
getCompanyJobDescription();
resetForm();
}).catch((error) => {
console.error("Görev Tanımı oluşturulurken bir hata oluştu: ", error);
toast.error("Görev Tanımı oluşturulurken hata oluştu.");
});
};
const resetForm = () => {
reset();
setIsUpdateMode(false); // Güncelleme modunu kapat
};
return (
<>
<Card sx={{ mb: 2 }}>
<CardHeader
sx={{ mb: 0 }}
title="Görev Tanımı Jenerik Maddeleri Ekle"
avatar={
<IconButton>
<Icon icon={isUpdateMode ? 'mi:edit' : 'mdi:plus'} />
</IconButton>
}
/>
<CardContent>
<Grid sx={{ pb: 5 }}>
<form onSubmit={handleSubmit(onSubmit)}>
<Grid container spacing={5}>
<Grid item xs={12} sm={12}>
<FormControl fullWidth>
<Controller
name='orderNo'
control={control}
rules={{ required: true }}
render={({ field: { value, onChange } }) => (
<TextField
value={value}
label='Sıra Numarası'
onChange={onChange}
placeholder=' '
error={Boolean(errors.orderNo)}
aria-describedby='validation-basic-orderNo'
sx={{ mb: 2, backgroundColor: isUpdateMode && '#EBF3F7', rounded: 4 }}
/>
)}
/>
{errors.orderNo && (
<FormHelperText sx={{ color: 'error.main' }} id='validation-basic-orderNo'>
Bu alan zorunlu.
</FormHelperText>
)}
</FormControl>
</Grid>
<Grid item xs={12} sm={12}>
<FormControl fullWidth>
<Controller
name='definition'
control={control}
rules={{ required: true }}
render={({ field: { value, onChange } }) => (
<TextField
value={value}
label='Ana iş Adımı'
multiline
onChange={onChange}
placeholder=' '
error={Boolean(errors.definition)}
aria-describedby='validation-basic-definition'
sx={{ mb: 2, backgroundColor: isUpdateMode && '#EBF3F7', rounded: 4 }}
/>
)}
/>
{errors.definition && (
<FormHelperText sx={{ color: 'error.main' }} id='validation-basic-definition'>
Bu alan zorunlu.
</FormHelperText>
)}
</FormControl>
</Grid>
<Grid item xs={12} sm={12} sx={{ display: 'flex' }}>
<Button fullWidth size='large' type='submit' variant='contained'>
{isUpdateMode ? "Güncelle" : "Kaydet"}
</Button>
</Grid>
</Grid>
</form>
</Grid>
<Box sx={{ height: 700 }}>
<DataGrid
columns={columns}
rowsPerPageOptions={[7, 10, 25, 50]}
rows={companyJobDescriptionLList}
sortModel={[
{
field: 'orderNo',
sort: 'asc',
},
]}
slots={{
toolbar: CustomToolbar,
pagination: CustomPagination,
}}
pagination
getRowHeight={() => "auto"}
/>
</Box>
</CardContent>
</Card>
<DeleteDialog onConfirm={handleConfirmDelete} open={openDelete} setOpen={setOpenDelete} />
</>
);
}
export default CompanyJobDescription;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js"></script>
我是 stackoverflow 的新用户。如果我在提问时犯了错误,我深表歉意。
你可以做类似的事情
...
const [text, setText] = useState("");
const [error, setError] = useState(false);
const handleChange = (event) => {
const value = event.target.value;
if (value.length <= 255) {
setText(value);
setError(false);
} else {
setError(true);
}
};
...
return (
...
<TextField
...
value={value}
onChange={handleChange}
error={error}
/>
{error && (
<Typography variant="caption" color="error">
Maximum character limit is 255
</Typography>
)}