title: How can I update/replace char at any position in the custom input field react
body: <p>I am trying to create a custom currency input field using reactjs .Here I am trying to update the value onKeyDown based on keypress I am able to remove the input value at any position but my input cursor is automatically moving at end of value and when I move the cursor and trying to enter value in between the existing value it is appending to end the existing value but I want to update the value at removed index postion.</p>
  <ol>
  <li>enter amount say 12.23</li>
  <li>Now move the cursor to first digit and remove the 1 and enter 2.</li>
  <li>Observe that user is not able to make amount as 22.23</li>
  <li>Try to edit the value at any place.</li>
  <li>Observe that user fails to edit the digits at particular places.
  Expected Results:
  User should be able to edit the particular digits of Payment amount.
  Actual Results:
  User is not able to edit the particular digits of Payment amount.
  my parent component</li>
  </ol>
  <pre><code>import { useState } from 'react';
  import { CurrencyInput } from './customInput';
  
  function App() {
    let defaultAmount = '' 
  
    const [paymentAmount, setPaymentAmount] = useState(defaultAmount);
    const [paymentAmountValid, setPaymentValid] = useState(true);
  
  
  
    return (
      &lt;div className=&quot;App&quot;&gt;
        &lt;CurrencyInput controlId=&quot;paymentAmount&quot;
          label={&quot;&quot;}
          value={paymentAmount}
          max={3000.00}
          min={1.00}
          message={'payment-invalid-message-residential'}
          setValidity={setPaymentValid}
          setValue={setPaymentAmount}
          defaultValue=&quot;0&quot;&gt;
        &lt;/CurrencyInput&gt;
      &lt;/div&gt;
    );
  }
  
  export default App;
  </code></pre>
  <p>my custom input component</p>
  <pre><code>import React, { useCallback, useRef } from &quot;react&quot;;
  // import { useTranslation } from &quot;react-i18next&quot;;
  import { useState } from &quot;react&quot;;
  import _ from &quot;lodash&quot;;
  import { Form } from &quot;react-bootstrap&quot;;
  
  
  
  
  export const CurrencyInput = ({ value, setValue, controlId, label, max, min, required, message, setValidity,defaultValue }) =&gt; {
      // const { t } = useTranslation();
      const [isValid, setValid] = useState(true);
      const amountInvalidMessage = &quot;amount-invalid&quot;;
      const amountRequiredMessage = &quot;amount-required&quot;;
      const [invalidMessage, setInvalidMessage] = useState(amountInvalidMessage);    
      const formatter = new Intl.NumberFormat(&quot;en-US&quot;, { style: &quot;currency&quot;, currency: &quot;USD&quot;, currencyDisplay: &quot;narrowSymbol&quot;})
      const currencyInput= useRef(null)
      const validate = useCallback(_.debounce((amount) =&gt; {
          let valid = true;
          
          if (amount !== null &amp;&amp; amount !== &quot;&quot;) {
              amount= amount.replace(&quot;$&quot;,&quot;&quot;)
              let amountNumber = parseFloat(amount);
              if (isNaN(amountNumber)) {
                  valid = false;
              } else if (min &gt; amountNumber) {
                  valid = false;
              } else if (max &lt; amountNumber) {
                  valid = false;
              }
  
              if(!valid) {
                  setValue(&quot;&quot;);
                  currencyInput.current.focus()                
                  setInvalidMessage(amountInvalidMessage);
              }
          } else if (required) {
              valid = false;
              setValue(&quot;&quot;);
              currencyInput.current.focus()
              setInvalidMessage(amountRequiredMessage);
          }
          setValid(valid);
          setValidity(valid);
      }, 500), [min, max]);
      
  
      const onBlur = (e) =&gt; {
          if(value !== null &amp;&amp; value !== &quot;&quot;) {
              let formattedValue = parseFloat(value).toFixed(2)
              setValue(formattedValue);
          }
          
          validate(value);
      }
      function removeAtIndex(str, index) {
          return str.substring(0, index - 1) + str.substring(index);
        }
      
      
      const onKeyDown = (e) =&gt; {
        if (e.keyCode === 8 || e.keyCode === 46) {
          e.preventDefault();
          const { selectionStart: i } = e.target;
          const index = e.keyCode === 8 ? i : i + 1;
          let formattedValue = removeAtIndex(value, index)
          if (parseFloat(formattedValue) === 0) {
            formattedValue = &quot;&quot;;
          }
          setValue(formattedValue);
          return;
        }
        let currentInput = &quot;&quot;;
        if (e.keyCode &gt;= 48 &amp;&amp; e.keyCode &lt;= 57) currentInput = e.keyCode - 48;
        else if (e.keyCode &gt;= 96 &amp;&amp; e.keyCode &lt;= 105)
          //if it is non alpha numeric
          currentInput = e.keyCode - 96;
        else return;
        console.log(&quot;currentInput&quot;,currentInput)
        let formattedValue = value * 10 + parseInt(currentInput) / 100;
        console.log(&quot;formattedValue&quot;,formattedValue)
        formattedValue = formattedValue.toFixed(2).toString();
        if (formattedValue === &quot;0.00&quot;) {
          formattedValue = &quot;&quot;;
        }
        setValue(formattedValue);
      };
      return &lt;Form.Group {...{ controlId }}&gt;
          &lt;Form.Control 
              type=&quot;text&quot;
              isInvalid={!isValid}                       
              onBlur={onBlur}
              ref ={currencyInput}
              onKeyDown={onKeyDown}                    
              placeholder= {formatter.format(defaultValue)}  
              value={value}
              pattern=&quot;/\D/g&quot;&gt;
          &lt;/Form.Control&gt;
          {!isValid ? &lt;Form.Control.Feedback className={'classes.feedbackInvalid'} type=&quot;invalid&quot;&gt;{invalidMessage}&lt;/Form.Control.Feedback&gt; : null}
      &lt;/Form.Group&gt;
  }
  </code></pre>