Skip to content

Commit

Permalink
- Enable async control. i.e. a response from server says the input va…
Browse files Browse the repository at this point in the history
…lue is not available. ```asyncMsgObj```
  • Loading branch information
Edward Xiao committed Jun 12, 2019
1 parent 3be5722 commit 0d180a2
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 22 deletions.
30 changes: 30 additions & 0 deletions example/index.js
Expand Up @@ -890,6 +890,12 @@ class Index extends Component {
// return true;
// }
}}
// asyncMsgObj={{
// error: false, // Optional.[Bool].Default: false. (Server response) Backend validation result.
// message: '', // Optional.[String].Default: "". (Server response) Your AJAX message. For instance, provide it when backend returns 'USERNAME ALREADY EXIST'
// showOnError: true, // Optional.[Bool].Default: true. (Server response) Show AJAX error message or not.
// showOnSuccess: false, // Optional.[Bool].Default: false. (Server response) Show AJAX success message or not.
// }}
/>
{/*<div>
<input
Expand Down Expand Up @@ -951,6 +957,12 @@ class Index extends Component {
// msgOnError: "Your custom error message if you provide the validationOption['msgOnError']", // Optional.[String].Default: "". Show your custom error message no matter what when it has error if it is provied.
// msgOnSuccess: "Your custom success message if you provide the validationOption['msgOnSuccess']. Otherwise, it will not show, not even green border." // Optional.[String].Default: "". Show your custom success message no matter what when it has error if it is provied.
}}
// asyncMsgObj={{
// error: false, // Optional.[Bool].Default: false. (Server response) Backend validation result.
// message: '', // Optional.[String].Default: "". (Server response) Your AJAX message. For instance, provide it when backend returns 'USERNAME ALREADY EXIST'
// showOnError: true, // Optional.[Bool].Default: true. (Server response) Show AJAX error message or not.
// showOnSuccess: false, // Optional.[Bool].Default: false. (Server response) Show AJAX success message or not.
// }}
/>
{/*<div
onClick={() => {
Expand Down Expand Up @@ -1009,6 +1021,12 @@ class Index extends Component {
// msgOnError: "Your custom error message if you provide the validationOption['msgOnError']", // Optional.[String].Default: "". Show your custom error message no matter what when it has error if it is provied.
// msgOnSuccess: "Your custom success message if you provide the validationOption['msgOnSuccess']. Otherwise, it will not show, not even green border." // Optional.[String].Default: "". Show your custom success message no matter what when it has error if it is provied.
}}
// asyncMsgObj={{
// error: false, // Optional.[Bool].Default: false. (Server response) Backend validation result.
// message: '', // Optional.[String].Default: "". (Server response) Your AJAX message. For instance, provide it when backend returns 'USERNAME ALREADY EXIST'
// showOnError: true, // Optional.[Bool].Default: true. (Server response) Show AJAX error message or not.
// showOnSuccess: false, // Optional.[Bool].Default: false. (Server response) Show AJAX success message or not.
// }}
/>
{/*<div
onClick={() => {
Expand Down Expand Up @@ -1078,6 +1096,12 @@ class Index extends Component {
// msgOnError: "Your custom error message if you provide the validationOption['msgOnError']", // Optional.[String].Default: "". Show your custom error message no matter what when it has error if it is provied.
// msgOnSuccess: "Your custom success message if you provide the validationOption['msgOnSuccess']. Otherwise, it will not show, not even green border." // Optional.[String].Default: "". Show your custom success message no matter what when it has error if it is provied.
}}
// asyncMsgObj={{
// error: false, // Optional.[Bool].Default: false. (Server response) Backend validation result.
// message: '', // Optional.[String].Default: "". (Server response) Your AJAX message. For instance, provide it when backend returns 'USERNAME ALREADY EXIST'
// showOnError: true, // Optional.[Bool].Default: true. (Server response) Show AJAX error message or not.
// showOnSuccess: false, // Optional.[Bool].Default: false. (Server response) Show AJAX success message or not.
// }}
/>
{/*<div
onClick={() => {
Expand Down Expand Up @@ -1152,6 +1176,12 @@ class Index extends Component {
// return true;
// }
}}
// asyncMsgObj={{
// error: false, // Optional.[Bool].Default: false. (Server response) Backend validation result.
// message: '', // Optional.[String].Default: "". (Server response) Your AJAX message. For instance, provide it when backend returns 'USERNAME ALREADY EXIST'
// showOnError: true, // Optional.[Bool].Default: true. (Server response) Show AJAX error message or not.
// showOnSuccess: false, // Optional.[Bool].Default: false. (Server response) Show AJAX success message or not.
// }}
/>
{/*<div>
<input
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "react-inputs-validation",
"version": "3.1.0",
"version": "3.1.1",
"description": "React form input validation components",
"main": "index.js",
"repository": {
Expand Down
40 changes: 37 additions & 3 deletions src/js/Inputs/Checkbox.tsx
Expand Up @@ -13,7 +13,6 @@ interface DefaultValidationOption {
msgOnError?: string;
msgOnSuccess?: string;
}

const getDefaultValidationOption = (obj: DefaultValidationOption) => {
let { name, check, required, showMsg, locale, msgOnError, msgOnSuccess } = obj;
locale = typeof locale !== 'undefined' ? locale : DEFAULT_LOCALE;
Expand All @@ -33,7 +32,25 @@ const getDefaultValidationOption = (obj: DefaultValidationOption) => {
msgOnSuccess,
};
};

interface DefaultAsyncMsgObj {
error?: boolean;
message?: string;
showOnError?: boolean;
showOnSuccess?: boolean;
}
const getDefaultAsyncObj = (obj: DefaultAsyncMsgObj) => {
let { error, message, showOnError, showOnSuccess } = obj;
error = typeof error !== 'undefined' ? error : false;
message = typeof message !== 'undefined' ? message : '';
showOnError = typeof showOnError !== 'undefined' ? showOnError : true;
showOnSuccess = typeof showOnSuccess !== 'undefined' ? showOnSuccess : false;
return {
error,
message,
showOnError,
showOnSuccess,
};
};
interface Props {
tabIndex?: string | number | null;
id?: string;
Expand All @@ -48,6 +65,7 @@ interface Props {
onFocus?: (e: React.FocusEvent<HTMLElement>) => void;
onClick?: (e: React.MouseEvent<HTMLElement>) => void;
validationOption?: object;
asyncMsgObj?: object;
classNameInput?: string;
classNameWrapper?: string;
classNameInputBox?: string;
Expand All @@ -58,7 +76,6 @@ interface Props {
customStyleInputBox?: object;
validationCallback?: (res: boolean) => void;
}

const component: React.FC<Props> = ({
tabIndex = null,
id = '',
Expand All @@ -77,6 +94,7 @@ const component: React.FC<Props> = ({
customStyleInputBox = {},
customStyleContainer = {},
validationOption = {},
asyncMsgObj = {},
onChange = () => {},
onBlur = null,
onFocus = null,
Expand All @@ -89,6 +107,7 @@ const component: React.FC<Props> = ({
const [internalChecked, setInternalChecked] = useState(checked);
const prevInternalChecked = usePrevious(internalChecked);
const option = getDefaultValidationOption(validationOption);
const asyncObj = getDefaultAsyncObj(asyncMsgObj);
const $input = useRef(null);
const $el: { [key: string]: any } | null = $input;
const handleOnBlur = useCallback(
Expand Down Expand Up @@ -198,6 +217,21 @@ const component: React.FC<Props> = ({
},
[prevInternalChecked, internalChecked],
);
useEffect(
() => {
if (asyncObj) {
if (asyncObj.message) {
if (asyncObj.showOnError) {
handleCheckEnd(asyncObj.error, asyncObj.message);
}
if (!asyncObj.error && asyncObj.showOnSuccess) {
setSuccessMsg(asyncObj.message);
}
}
}
},
[asyncMsgObj],
);
const wrapperClass = `${WRAPPER_CLASS_IDENTITIFIER} ${classNameWrapper} ${reactInputsValidationCss[`${TYPE}__wrapper`]} ${internalChecked && reactInputsValidationCss['checked']} ${err &&
reactInputsValidationCss['error']} ${successMsg !== '' && !err && reactInputsValidationCss['success']} ${disabled && reactInputsValidationCss['disabled']}`;
const containerClass = `${classNameContainer} ${reactInputsValidationCss[`${TYPE}__container`]} ${internalChecked && reactInputsValidationCss['checked']} ${err &&
Expand Down
42 changes: 37 additions & 5 deletions src/js/Inputs/Radiobox.tsx
Expand Up @@ -13,7 +13,6 @@ interface DefaultValidationOption {
msgOnError?: string;
msgOnSuccess?: string;
}

const getDefaultValidationOption = (obj: DefaultValidationOption) => {
let { name, check, required, showMsg, locale, msgOnError, msgOnSuccess } = obj;
locale = typeof locale !== 'undefined' ? locale : DEFAULT_LOCALE;
Expand All @@ -33,7 +32,25 @@ const getDefaultValidationOption = (obj: DefaultValidationOption) => {
msgOnSuccess,
};
};

interface DefaultAsyncMsgObj {
error?: boolean;
message?: string;
showOnError?: boolean;
showOnSuccess?: boolean;
}
const getDefaultAsyncObj = (obj: DefaultAsyncMsgObj) => {
let { error, message, showOnError, showOnSuccess } = obj;
error = typeof error !== 'undefined' ? error : false;
message = typeof message !== 'undefined' ? message : '';
showOnError = typeof showOnError !== 'undefined' ? showOnError : true;
showOnSuccess = typeof showOnSuccess !== 'undefined' ? showOnSuccess : false;
return {
error,
message,
showOnError,
showOnSuccess,
};
};
export const isValidValue = (list: OptionListItem[], value: any) => {
let res = false;
if (list.length) {
Expand All @@ -46,12 +63,10 @@ export const isValidValue = (list: OptionListItem[], value: any) => {
}
return res;
};

interface OptionListItem {
id: string;
name: string;
}

interface Props {
tabIndex?: string | number | undefined;
id?: string;
Expand All @@ -65,6 +80,7 @@ interface Props {
onFocus?: (e: React.FocusEvent<HTMLElement>) => void;
onClick?: (e: React.MouseEvent<HTMLElement>) => void;
validationOption?: object;
asyncMsgObj?: object;
classNameWrapper?: string;
classNameInput?: string;
classNameContainer?: string;
Expand All @@ -75,7 +91,6 @@ interface Props {
customStyleOptionListItem?: object;
validationCallback?: (res: boolean) => void;
}

const component: React.FC<Props> = ({
tabIndex = null,
id = '',
Expand All @@ -93,6 +108,7 @@ const component: React.FC<Props> = ({
customStyleInput = {},
customStyleOptionListItem = {},
validationOption = {},
asyncMsgObj = {},
onChange = () => {},
onBlur = null,
onFocus = null,
Expand All @@ -105,6 +121,7 @@ const component: React.FC<Props> = ({
const [internalValue, setInternalValue] = useState(String(value));
const prevInternalValue = usePrevious(internalValue);
const option = getDefaultValidationOption(validationOption);
const asyncObj = getDefaultAsyncObj(asyncMsgObj);
const $input = useRef(null);
const $el: { [key: string]: any } | null = $input;
const handleOnBlur = useCallback(
Expand Down Expand Up @@ -209,6 +226,21 @@ const component: React.FC<Props> = ({
},
[prevInternalValue, internalValue],
);
useEffect(
() => {
if (asyncObj) {
if (asyncObj.message) {
if (asyncObj.showOnError) {
handleCheckEnd(asyncObj.error, asyncObj.message);
}
if (!asyncObj.error && asyncObj.showOnSuccess) {
setSuccessMsg(asyncObj.message);
}
}
}
},
[asyncMsgObj],
);
const wrapperClass = `${WRAPPER_CLASS_IDENTITIFIER} ${classNameWrapper} ${err && reactInputsValidationCss['error']} ${successMsg !== '' && !err && reactInputsValidationCss['success']} ${
reactInputsValidationCss[`${TYPE}__wrapper`]
} ${disabled && reactInputsValidationCss['disabled']}`;
Expand Down

0 comments on commit 0d180a2

Please sign in to comment.