diff --git a/src/qqq/components/forms/DynamicFormField.tsx b/src/qqq/components/forms/DynamicFormField.tsx
index e2fb6f8..4a80caa 100644
--- a/src/qqq/components/forms/DynamicFormField.tsx
+++ b/src/qqq/components/forms/DynamicFormField.tsx
@@ -135,7 +135,7 @@ function QDynamicFormField({
/>
- {!isDisabled &&
}
+ {!isDisabled && {msg}} />
}
>
diff --git a/src/qqq/components/forms/DynamicFormUtils.ts b/src/qqq/components/forms/DynamicFormUtils.ts
index 02f3d85..59c060e 100644
--- a/src/qqq/components/forms/DynamicFormUtils.ts
+++ b/src/qqq/components/forms/DynamicFormUtils.ts
@@ -104,7 +104,18 @@ class DynamicFormUtils
{
if (field.isRequired)
{
- return (Yup.string().required(`${field.label} is required.`));
+ if(field.possibleValueSourceName)
+ {
+ ////////////////////////////////////////////////////////////////////////////////////////////
+ // the "nullable(true)" here doesn't mean that you're allowed to set the field to null... //
+ // rather, it's more like "null is how empty will be treated" or some-such... //
+ ////////////////////////////////////////////////////////////////////////////////////////////
+ return (Yup.string().required(`${field.label} is required.`).nullable(true));
+ }
+ else
+ {
+ return (Yup.string().required(`${field.label} is required.`));
+ }
}
return (null);
}
diff --git a/src/qqq/components/forms/DynamicSelect.tsx b/src/qqq/components/forms/DynamicSelect.tsx
index ac558c8..a11a2b3 100644
--- a/src/qqq/components/forms/DynamicSelect.tsx
+++ b/src/qqq/components/forms/DynamicSelect.tsx
@@ -27,8 +27,9 @@ import Autocomplete from "@mui/material/Autocomplete";
import Box from "@mui/material/Box";
import Switch from "@mui/material/Switch";
import TextField from "@mui/material/TextField";
-import {useFormikContext} from "formik";
+import {ErrorMessage, useFormikContext} from "formik";
import React, {useEffect, useState} from "react";
+import MDTypography from "qqq/components/legacy/MDTypography";
import Client from "qqq/utils/qqq/Client";
interface Props
@@ -246,78 +247,85 @@ function DynamicSelect({tableName, processName, fieldName, overrideId, fieldLabe
// console.log(`default value: ${JSON.stringify(defaultValue)}`);
const autocomplete = (
-
- {
- setOpen(true);
- // console.log("setting open...");
- if(options.length == 0)
+
+
{
- // console.log("no options yet, so setting search term to ''...");
- setSearchTerm("");
- }
- }}
- onClose={() =>
- {
- setOpen(false);
- }}
- isOptionEqualToValue={(option, value) => option.id === value.id}
- getOptionLabel={(option) =>
- {
- // @ts-ignore
- if(option && option.length)
+ setOpen(true);
+ // console.log("setting open...");
+ if(options.length == 0)
+ {
+ // console.log("no options yet, so setting search term to ''...");
+ setSearchTerm("");
+ }
+ }}
+ onClose={() =>
+ {
+ setOpen(false);
+ }}
+ isOptionEqualToValue={(option, value) => option.id === value.id}
+ getOptionLabel={(option) =>
{
// @ts-ignore
- option = option[0];
- }
+ if(option && option.length)
+ {
+ // @ts-ignore
+ option = option[0];
+ }
+ // @ts-ignore
+ return option.label
+ }}
+ options={options}
+ loading={loading}
+ onInputChange={inputChanged}
+ onBlur={handleBlur}
+ defaultValue={defaultValue}
// @ts-ignore
- return option.label
- }}
- options={options}
- loading={loading}
- onInputChange={inputChanged}
- onBlur={handleBlur}
- defaultValue={defaultValue}
- // @ts-ignore
- onChange={handleChanged}
- noOptionsText={"No matches found"}
- onKeyPress={e =>
- {
- if (e.key === "Enter")
+ onChange={handleChanged}
+ noOptionsText={"No matches found"}
+ onKeyPress={e =>
{
- e.preventDefault();
- }
- }}
- renderOption={renderOption}
- filterOptions={filterOptions}
- disabled={isDisabled}
- multiple={isMultiple}
- disableCloseOnSelect={isMultiple}
- limitTags={5}
- slotProps={{popper: {className: "DynamicSelectPopper"}}}
- renderInput={(params) => (
-
- {loading ? : null}
- {params.InputProps.endAdornment}
-
- ),
- }}
- />
- )}
- />
+ if (e.key === "Enter")
+ {
+ e.preventDefault();
+ }
+ }}
+ renderOption={renderOption}
+ filterOptions={filterOptions}
+ disabled={isDisabled}
+ multiple={isMultiple}
+ disableCloseOnSelect={isMultiple}
+ limitTags={5}
+ slotProps={{popper: {className: "DynamicSelectPopper"}}}
+ renderInput={(params) => (
+
+ {loading ? : null}
+ {params.InputProps.endAdornment}
+
+ ),
+ }}
+ />
+ )}
+ />
+
+
+ {!isDisabled && {msg}} />
}
+
+
+
);
diff --git a/src/qqq/components/forms/EntityForm.tsx b/src/qqq/components/forms/EntityForm.tsx
index 1d3c2ef..9d1761a 100644
--- a/src/qqq/components/forms/EntityForm.tsx
+++ b/src/qqq/components/forms/EntityForm.tsx
@@ -32,8 +32,8 @@ import Box from "@mui/material/Box";
import Card from "@mui/material/Card";
import Grid from "@mui/material/Grid";
import Icon from "@mui/material/Icon";
-import {Form, Formik} from "formik";
-import React, {useContext, useReducer, useState} from "react";
+import {Form, Formik, useFormikContext} from "formik";
+import React, {useContext, useEffect, useReducer, useState} from "react";
import {useLocation, useNavigate, useParams} from "react-router-dom";
import * as Yup from "yup";
import QContext from "QContext";
@@ -77,7 +77,7 @@ function EntityForm(props: Props): JSX.Element
const [formTitle, setFormTitle] = useState("");
const [validations, setValidations] = useState({});
- const [initialValues, setInitialValues] = useState({} as { [key: string]: string });
+ const [initialValues, setInitialValues] = useState({} as { [key: string]: any });
const [formFields, setFormFields] = useState(null as Map);
const [t1sectionName, setT1SectionName] = useState(null as string);
const [nonT1Sections, setNonT1Sections] = useState([] as QTableSection[]);
@@ -233,27 +233,26 @@ function EntityForm(props: Props): JSX.Element
////////////////////////////////////////////////////////////////////////////////////////////////
// if default values were supplied for a new record, then populate initialValues, for formik. //
////////////////////////////////////////////////////////////////////////////////////////////////
- if(defaultValues)
+ for (let i = 0; i < fieldArray.length; i++)
{
- for (let i = 0; i < fieldArray.length; i++)
+ const fieldMetaData = fieldArray[i];
+ const fieldName = fieldMetaData.name;
+ const defaultValue = (defaultValues && defaultValues[fieldName]) ? defaultValues[fieldName] : fieldMetaData.defaultValue;
+ if (defaultValue)
{
- const fieldMetaData = fieldArray[i];
- const fieldName = fieldMetaData.name;
- if (defaultValues[fieldName])
- {
- initialValues[fieldName] = defaultValues[fieldName];
+ initialValues[fieldName] = defaultValue;
- ///////////////////////////////////////////////////////////////////////////////////////////
- // we need to set the initialDisplayValue for possible value fields with a default value //
- // so, look them up here now if needed //
- ///////////////////////////////////////////////////////////////////////////////////////////
- if (fieldMetaData.possibleValueSourceName)
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // we need to set the initialDisplayValue for possible value fields with a default value //
+ // so, look them up here now if needed //
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ if (fieldMetaData.possibleValueSourceName)
+ {
+ const results: QPossibleValue[] = await qController.possibleValues(tableName, null, fieldName, null, [initialValues[fieldName]]);
+ if (results && results.length > 0)
{
- const results: QPossibleValue[] = await qController.possibleValues(tableName, null, fieldName, null, [initialValues[fieldName]]);
- if (results && results.length > 0)
- {
- defaultDisplayValues.set(fieldName, results[0].label);
- }
+ defaultDisplayValues.set(fieldName, results[0].label);
+ initialValues[fieldName] = {id: defaultValue, value: results[0].label}
}
}
}
@@ -598,6 +597,7 @@ function EntityForm(props: Props): JSX.Element
isSubmitting,
}) => (