feat: enhance form validation logic to include table field checks and improve error handling
This commit is contained in:
parent
6b122bafd8
commit
6c311f4b2e
|
|
@ -57,29 +57,79 @@ export const Form: React.FC<any> = ({
|
|||
);
|
||||
try {
|
||||
const fieldDate: any = local?.fields;
|
||||
let isError = false;
|
||||
let error: Record<string, string> = {};
|
||||
try {
|
||||
const dateFields = Object.values(fieldDate).filter(
|
||||
(field: any) => get(field, "type") === "date"
|
||||
);
|
||||
if (Array.isArray(dateFields) && dateFields?.length) {
|
||||
dateFields.map((e: any) => {
|
||||
if (e?.name)
|
||||
local.data[e?.name] = normalDate(local.data[e?.name]);
|
||||
if (dateFields.length) {
|
||||
dateFields.forEach((e: any) => {
|
||||
if (e?.name) {
|
||||
local.data[e.name] = normalDate(local.data[e.name]);
|
||||
}
|
||||
});
|
||||
local.render();
|
||||
}
|
||||
} catch (ex) {}
|
||||
} catch (ex) {
|
||||
console.error("Error processing date fields:", ex);
|
||||
}
|
||||
|
||||
const fieldRequired = Object.values(fieldDate).filter(
|
||||
(field: any) => field?.required || field?.type === "table"
|
||||
);
|
||||
|
||||
if (fieldRequired.length) {
|
||||
fieldRequired.forEach((e: any) => {
|
||||
let keys = e?.name;
|
||||
const type = e?.type;
|
||||
|
||||
if (type === "table" && e?.fields?.length) {
|
||||
e.fields.forEach((item: any, index: number) => {
|
||||
let errorChilds: Record<string, string> = {};
|
||||
const fieldRequired = Object.values(item?.fields).filter(
|
||||
(field: any) => field?.required
|
||||
);
|
||||
let error = {} as any;
|
||||
if (Array.isArray(fieldRequired) && fieldRequired?.length) {
|
||||
fieldRequired.map((e: any) => {
|
||||
const type = e?.type;
|
||||
let keys = e?.name;
|
||||
console.log({ fieldRequired });
|
||||
fieldRequired.forEach((subField: any) => {
|
||||
let keySub = subField?.name;
|
||||
const typeSub = subField?.type;
|
||||
const val = get(local.data, `${keys}[${index}].${keySub}`);
|
||||
if (["dropdown-async", "multi-async"].includes(typeSub)) {
|
||||
keySub = subField?.target || subField?.name;
|
||||
}
|
||||
if (
|
||||
[
|
||||
"multi-dropdown",
|
||||
"checkbox",
|
||||
"multi-upload",
|
||||
"multi-async",
|
||||
].includes(typeSub)
|
||||
) {
|
||||
if (!Array.isArray(get(local.data, keys)) || !val?.length) {
|
||||
errorChilds[subField.name] =
|
||||
"This field requires at least one item.";
|
||||
isError = true;
|
||||
}
|
||||
} else if (!val) {
|
||||
errorChilds[subField.name] = "Please fill out this field.";
|
||||
isError = true;
|
||||
}
|
||||
|
||||
console.log({
|
||||
keySub,
|
||||
data: get(local.data, `${keys}[${index}]`),
|
||||
val,
|
||||
});
|
||||
});
|
||||
|
||||
item.error = errorChilds;
|
||||
});
|
||||
} else {
|
||||
if (["dropdown-async", "multi-async"].includes(type)) {
|
||||
keys = e?.target || e?.name;
|
||||
}
|
||||
const val = get(local.data, keys);
|
||||
if (
|
||||
[
|
||||
"multi-dropdown",
|
||||
|
|
@ -88,27 +138,26 @@ export const Form: React.FC<any> = ({
|
|||
"multi-async",
|
||||
].includes(type)
|
||||
) {
|
||||
if (
|
||||
!Array.isArray(get(local.data, keys)) ||
|
||||
!get(local.data, `${keys}.length`)
|
||||
) {
|
||||
error[e?.name] = `This field requires at least one item.`;
|
||||
if (!Array.isArray(val) || !val?.length) {
|
||||
error[e.name] = "This field requires at least one item.";
|
||||
isError = true;
|
||||
}
|
||||
} else {
|
||||
if (!get(local.data, keys)) {
|
||||
error[e?.name] = `Please fill out this field.`;
|
||||
} else if (!val) {
|
||||
error[e.name] = "Please fill out this field.";
|
||||
isError = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
local.error = error;
|
||||
local.render();
|
||||
console.log({ error });
|
||||
if (Object.keys(error).length) {
|
||||
throw new Error("please check your input field.");
|
||||
} else {
|
||||
await onSubmit(local);
|
||||
}
|
||||
console.log(isError);
|
||||
// if (isError) {
|
||||
// throw new Error("please check your input field.");
|
||||
// } else {
|
||||
// await onSubmit(local);
|
||||
// }
|
||||
setTimeout(() => {
|
||||
toast.success(
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -285,7 +285,7 @@ export const TypeAsyncDropdown: React.FC<any> = ({
|
|||
placeholder={disabled ? "" : placeholderField}
|
||||
isDisabled={disabled}
|
||||
className={cx(
|
||||
"rounded-md border-none text-sm",
|
||||
"rounded-md border-none text-sm w-full",
|
||||
css`
|
||||
[role="listbox"] {
|
||||
padding: 0px !important;
|
||||
|
|
|
|||
|
|
@ -230,6 +230,7 @@ export const TypeInput: React.FC<any> = ({
|
|||
asSingle={true}
|
||||
useRange={false}
|
||||
onChange={(value) => {
|
||||
console.log(value);
|
||||
fm.data[name] = value?.startDate
|
||||
? new Date(value?.startDate)
|
||||
: null;
|
||||
|
|
|
|||
|
|
@ -154,6 +154,12 @@ export const TableEditBetter: React.FC<any> = ({
|
|||
local.data = fm?.data[name] || [];
|
||||
local.render();
|
||||
console.log(columns);
|
||||
fm.fields[name] = {
|
||||
name: name,
|
||||
type: "table",
|
||||
fields: [],
|
||||
};
|
||||
fm.render();
|
||||
}, []);
|
||||
|
||||
const handleResize = (index: any, width: any) => {
|
||||
|
|
@ -168,9 +174,11 @@ export const TableEditBetter: React.FC<any> = ({
|
|||
<div className="tbl-wrapper flex flex-grow flex-col">
|
||||
{!disabledHeader ? (
|
||||
<div className="head-tbl-list block items-start justify-between bg-white px-0 py-4 sm:flex">
|
||||
<div className="flex flex-row items-end">
|
||||
<div className="sm:flex flex flex-col space-y-2">
|
||||
<div className="flex">{sideLeft ? sideLeft(local) : <></>}</div>
|
||||
<div className="flex flex-row h-full">
|
||||
<div className="sm:flex flex flex-col space-y-2 flex-grow">
|
||||
<div className="flex flex-grow flex-row">
|
||||
{sideLeft ? sideLeft(local) : <></>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="ml-auto flex items-center flex-row">
|
||||
|
|
@ -265,10 +273,21 @@ export const TableEditBetter: React.FC<any> = ({
|
|||
)}
|
||||
<tbody>
|
||||
{local.data.map((row: any, index: any) => {
|
||||
if (
|
||||
typeof fm.fields?.[name]?.fields?.[index]?.fields !==
|
||||
"object"
|
||||
) {
|
||||
fm.fields[name].fields[index] = {
|
||||
fields: {},
|
||||
};
|
||||
}
|
||||
const fm_row = {
|
||||
...fm,
|
||||
|
||||
name: name,
|
||||
type: "table",
|
||||
data: row,
|
||||
error: fm.fields?.[name]?.fields?.[index]?.error,
|
||||
fields: fm.fields?.[name]?.fields?.[index]?.fields,
|
||||
render: () => {
|
||||
local.render();
|
||||
fm.data[name] = local.data;
|
||||
|
|
@ -302,7 +321,9 @@ export const TableEditBetter: React.FC<any> = ({
|
|||
return (
|
||||
<td
|
||||
key={`row_${name}_${index}_${col?.accessorKey}_${idx}`}
|
||||
className={"table-header-tbl capitalize"}
|
||||
className={
|
||||
"table-header-tbl align-top capitalize"
|
||||
}
|
||||
>
|
||||
<div className="p-1">{renderData}</div>
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -74,9 +74,7 @@ const Input: React.FC<Props> = (e: Props) => {
|
|||
const handleInputChange = useCallback(
|
||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const inputValue = e.target.value;
|
||||
|
||||
const dates = [];
|
||||
|
||||
if (asSingle) {
|
||||
const date = parseFormattedDate(inputValue, displayFormat);
|
||||
if (dateIsValid(date.toDate())) {
|
||||
|
|
@ -121,6 +119,8 @@ const Input: React.FC<Props> = (e: Props) => {
|
|||
if (dates[1])
|
||||
changeDayHover(dayjs(dates[1]).add(-1, "day").format(DATE_FORMAT));
|
||||
else changeDayHover(dates[0]);
|
||||
} else {
|
||||
changeDatepickerValue(null, e.target);
|
||||
}
|
||||
|
||||
changeInputText(e.target.value);
|
||||
|
|
|
|||
Loading…
Reference in New Issue