s-yadav / react-number-format

React component to format numbers in an input or as a text.
MIT License
3.9k stars 410 forks source link

Invisible characters in state values #853

Closed cemck closed 3 months ago

cemck commented 3 months ago

Hi I'm getting unexpected behavior when updating value state with custom button clicks (custom onscreen keyboard). When using hardware keyboard there is no problem at all. There are "invisible" characters in my states, these characters are not visible in the input field (happens for both inputs) (check screenshots of the issue). I'm using Ionic Framework with React

State logic:

const [fields, setFields] = useState<{[key: string]: string}>({
  balance: "",
  risk: "",
});

const updateField = (field: string, newValue: string) => {
  setFields((prevFields) => ({
    ...prevFields,
    [field]: newValue,
  }));
};

Custom Keyboard: (activeField is referencing clicked input field (balance or risk)

const handleButtonClick = (value: string) => {
  if (!activeField) return;

  if (value === "DEL") {
    updateField(activeField, fields[activeField].slice(0, -1));
  } else if (value === "RESET") {
    setFields({
      balance: "",
      risk: "",
    });
  } else {
    updateField(activeField, fields[activeField] + value);
  }
};

return (
  <CustomKeyboard onButtonClick={handleButtonClick} />
);

NumericFormat:

<NumericFormat
  className={styles.input}
  value={fields.balance}
  onClick={() => setActiveField("balance")}
  onValueChange={(values: { formattedValue: any }, sourceInfo) => {
    updateField("balance", values.formattedValue);
  }}
  prefix={"$"}
  allowNegative={false}
  thousandSeparator
  decimalScale={2} // Limit to 2 decimal places
  inputMode="none" // Disable the keyboard
  placeholder="$0.00"
/>

<NumericFormat
  className={styles.input}
  value={fields.risk}
  onClick={() => setActiveField("risk")}
  onValueChange={(values: { formattedValue: any }, sourceInfo) => {
    updateField("risk", values.formattedValue);
  }}
  suffix="%" // Add a percentage sign
  allowNegative={false} // Do not allow negative values
  decimalScale={2} // Limit to 2 decimal places
  inputMode="none" // Disable the keyboard
  placeholder="0%"
/>

Screenshots:

(Printed fields) Bildschirmfoto 2024-08-22 um 22 26 54

Bildschirmfoto 2024-08-22 um 22 27 57

I would really appreciate any help

s-yadav commented 3 months ago

The problem is on button click you are always appending at the end. The library has added logic to maintain the cursor position before suffix, but the value is getting corrupted as the state is getting updated outside. For number format, it will just trim out anything after the suffix so that the library value is not changing and hence shows the correct value.

To solve this you need to do updateField(activeField, fields[activeField].slice(0, -1) + value); inside handleButtonClick. However there many cases around caret position. So if you are creating custom keyboard, you will have to handle all those cases.

This should be handled outside, as its custom implementation of the keyboard. So closing this.