Created
February 12, 2020 18:38
-
-
Save carsenchan/6875b2c7588fe07fc361e167d7acdfd8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const invalidMsg = { | |
emptyQty: "Qty cannot be empty", | |
invalidQty: "Invalid Qty input", | |
zeroQty: "Qty cannot be zero", | |
decimal: "Qty cannot be decimal", | |
} | |
// decimal regex | |
const regexDecimal = /^\d*\.?\d*$/; | |
// integer regx | |
const regexInteger = /(?<=\s|^)\d+(?=\s|$)/; | |
const QtyInput = ({isDecimal = false, | |
isAllowEmpty = false, | |
emptyErrorMsg = invalidMsg.emptyQty, | |
zeroErrorMsg = invalidMsg.zeroQty, | |
invalidErrorMsg = invalidMsg.invalidQty, | |
decimalErrorMsg = invalidMsg.decimal, | |
value = "", | |
label="label", | |
valueCallBack = ()=> {} | |
}):React.FC => { | |
const [validationMsg, setValidationMsg] = useState(""); | |
const [qtyValue, setQtyValue] = useState(value ); | |
const setError = (text: String) => { | |
if(qtyValue.length + 1 === text.length){ | |
setQtyValue(text.slice(0, text.length-1 )); | |
} else { | |
setQtyValue(text); | |
} | |
if(parseFloat(text) === 0){ | |
setValidationMsg(zeroErrorMsg); | |
return; | |
} | |
if(!regexDecimal.test(text) && !regexInteger.test(text) && qtyValue.length + 1 !== text.length){ | |
setValidationMsg(invalidErrorMsg); | |
return; | |
} | |
if( regexDecimal.test(text) && Math.abs(qtyValue.length - text.length)!==1){ | |
setValidationMsg(decimalErrorMsg); | |
} | |
} | |
const decimalTreat = (isDecimal = false, inputString: String) => { | |
if(isDecimal){ | |
const parts = inputString.split("."); | |
if(parts.length === 2){ | |
if(parts[1] && parts[1].length > 2){ | |
const firstPart = parseFloat(parts[0]) === 0 ? "0": parts[0] ; | |
return firstPart +"." + parts[1].substring(0, 2); | |
} else { | |
return inputString; | |
} | |
} else { | |
return parseFloat(inputString) === 0 ? "0": `${parseInt(inputString, 10)}` | |
} | |
} else { | |
return parseFloat(inputString) === 0 ? "0" : `${parseInt(inputString, 10)}` | |
} | |
} | |
const onTextChange = (event: React.ChangeEvent<HTMLInputElement>) => { | |
const text = event.target.value; | |
const testResult = !isDecimal ? regexInteger.test(event.target.value) : regexDecimal.test(event.target.value); | |
if(text.length === 0 && !isAllowEmpty){ | |
setQtyValue(""); | |
setValidationMsg(emptyErrorMsg); | |
return; | |
} | |
if(isDecimal && text === "."){ | |
setQtyValue("."); | |
setValidationMsg(invalidErrorMsg); | |
return; | |
} | |
if(testResult){ | |
setQtyValue( decimalTreat(isDecimal, text) ); | |
setValidationMsg(parseFloat(event.target.value) === 0 ? zeroErrorMsg : ""); | |
} else { | |
setError(event.target.value); | |
} | |
} | |
useEffect(()=> { | |
if(qtyValue.length !==0) { | |
console.log(qtyValue) | |
if(isDecimal && qtyValue === "."){ | |
} else { | |
valueCallBack(qtyValue); | |
} | |
} else if(isAllowEmpty){ | |
valueCallBack(""); | |
} | |
}, [isAllowEmpty, isDecimal, qtyValue, valueCallBack]); | |
return ( | |
<div style={{marginBottom: 10}}> | |
<label htmlFor={label}>{label}</label><br/> | |
<input type="text" name="quantity_input" onChange={onTextChange} value={qtyValue}/><br/> | |
{validationMsg !== "" && <font style={{color: "red"}}>{validationMsg}</font>} | |
</div> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment