корректные проверки селекта возраста
This commit is contained in:
parent
2540dd8079
commit
8255fe6908
@ -10,7 +10,8 @@ import {
|
||||
Grow,
|
||||
ClickAwayListener,
|
||||
MenuList,
|
||||
useTheme
|
||||
useTheme,
|
||||
FormHelperText
|
||||
} from '@mui/material';
|
||||
import ArrowDownIcon from "@/assets/icons/ArrowDownIcon";
|
||||
|
||||
@ -23,13 +24,47 @@ const AgeInputWithSelect = ({ value, onChange }: AgeInputWithSelectProps) => {
|
||||
const theme = useTheme();
|
||||
const [open, setOpen] = useState(false);
|
||||
const anchorRef = useRef<HTMLDivElement>(null);
|
||||
const [errorType, setErrorType] = useState<'format' | 'range' | false>(false);
|
||||
|
||||
// Валидация: только число или диапазон число-число, и диапазон 0-150
|
||||
const validate = (val: string) => {
|
||||
if (!val) return false;
|
||||
// Число (только положительное)
|
||||
if (/^\d+$/.test(val)) {
|
||||
const num = Number(val);
|
||||
if (num < 0 || num > 150) return 'range';
|
||||
return false;
|
||||
}
|
||||
// Диапазон (только положительные числа)
|
||||
const rangeMatch = val.match(/^(\d+)-(\d+)$/);
|
||||
if (rangeMatch) {
|
||||
const left = Number(rangeMatch[1]);
|
||||
const right = Number(rangeMatch[2]);
|
||||
if (left < 0 || left > 150 || right < 0 || right > 150 || left > right) return 'range';
|
||||
return false;
|
||||
}
|
||||
// Если есть минус не в начале диапазона — это ошибка диапазона
|
||||
if (/^-?\d+-\d+$/.test(val) || /^\d+-\d+-\d+$/.test(val)) {
|
||||
return 'range';
|
||||
}
|
||||
return 'format';
|
||||
};
|
||||
|
||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange(e.target.value);
|
||||
const filtered = e.target.value.replace(/[^\d-]/g, '');
|
||||
onChange(filtered);
|
||||
setErrorType(false);
|
||||
};
|
||||
|
||||
const handleInputBlur = (e: React.FocusEvent<HTMLInputElement>) => {
|
||||
const trimmed = e.target.value.replace(/\s+/g, '');
|
||||
onChange(trimmed);
|
||||
setErrorType(validate(trimmed));
|
||||
};
|
||||
|
||||
const handleSelectItemClick = (selectedValue: string) => {
|
||||
onChange(selectedValue);
|
||||
setErrorType(false);
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
@ -66,8 +101,10 @@ const AgeInputWithSelect = ({ value, onChange }: AgeInputWithSelectProps) => {
|
||||
<InputBase
|
||||
value={value}
|
||||
onChange={handleInputChange}
|
||||
onBlur={handleInputBlur}
|
||||
fullWidth
|
||||
placeholder="Введите возраст"
|
||||
inputProps={{ inputMode: 'numeric', pattern: '[0-9-]*' }}
|
||||
sx={{
|
||||
height: "100%",
|
||||
padding: "10px 20px",
|
||||
@ -77,6 +114,16 @@ const AgeInputWithSelect = ({ value, onChange }: AgeInputWithSelectProps) => {
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{errorType === 'format' && (
|
||||
<FormHelperText error sx={{ position: 'absolute', left: 0, top: '100%', mt: '2px', ml: '10px' }}>
|
||||
можно только число или диапазон
|
||||
</FormHelperText>
|
||||
)}
|
||||
{errorType === 'range' && (
|
||||
<FormHelperText error sx={{ position: 'absolute', left: 0, top: '100%', mt: '2px', ml: '10px' }}>
|
||||
таких возрастов нет
|
||||
</FormHelperText>
|
||||
)}
|
||||
<IconButton
|
||||
onClick={handleToggle}
|
||||
sx={{
|
||||
|
Loading…
Reference in New Issue
Block a user