Skip to content

Instantly share code, notes, and snippets.

@carsenchan
Created February 12, 2020 18:38
Show Gist options
  • Save carsenchan/6875b2c7588fe07fc361e167d7acdfd8 to your computer and use it in GitHub Desktop.
Save carsenchan/6875b2c7588fe07fc361e167d7acdfd8 to your computer and use it in GitHub Desktop.
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