1

I have an input field where i am trying to block the special characters [dot, hiphen, space comma and e] so that user can't enter this special characters on both mobile and chrome.

function App() {
  const handleInput = (event) => {
    event.target.value = event.target.value.replace(/[e\.\- ]/g, "");
  };

  return ( <
    div className = "App" >
    <
    input type = "number"
    onInput = {
      handleInput
    }
    /> < /
    div >
  );
}

// Render it
ReactDOM.render( <
  App / > ,
  document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Facing two issues on this, one is (999.) I am able to enter dot in between numbers, also when I enter some numbers and type hiphen then its clearing all the numbers (999-) => ().

How can I stop this two behaviour so that user can enter only 0-9 digits

dev
  • 814
  • 10
  • 27
  • I have added the snippet which can be runned @T.J.Crowder . Thanks – dev Dec 16 '21 at 07:58
  • Does this answer your question? [HTML text input allow only numeric input](https://stackoverflow.com/questions/469357/html-text-input-allow-only-numeric-input) – Lahcen Dec 16 '21 at 08:43

1 Answers1

0

Replacing the value when the user is typing makes for poor UX (the cursor jumps around). In your previous questions you were preventing those characters via keydown, which seems like the better approach. It may not work on all mobile browsers, but since you presumably want the numeric on-screen keyboard they provide for type="number", you may have to accept that and so some post-processing when you're going to use the value (rather than as they're typing it).

Here's an example of that pragmatic approach, preventing where you can, post-processing the value when using it in case you weren't able to prevent the invalid chars on some mobile devices. I've also made the input a controlled input since that makes it easier to use its value elsewhere in the component:

const {useState} = React;

const invalid = new Set(["e", ".", "-", " "]);
function App() {
    const [value, setValue] = useState("");
    
    const handleInput = (event) => {
        if (invalid.has(event.key)) {
            event.preventDefault();
        }
    };
    
    const useValue = (event) => {
        const prepped = value.replace(/[e.\- ]/g, "");
        console.log(`Using value "${value}"`);
    };
  
    return (
        <div className="App">
            <input
                type="number"
                onKeyDown={handleInput}
                onChange={e => setValue(e.target.value)}
                value={value}
            />
            <input type="button" value="Use Value" onClick={useValue} />
        </div>
    );
}

ReactDOM.render(<App />, document.getElementById("root"));
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    why i was using onInput because when I try to paste it, it will block, if you 999-99 copy and paste this this accepts in onKeyDown – dev Dec 16 '21 at 08:27
  • 1
    @dev - Good point. The post-processing would handle that, but we may be able to do both, let me see... – T.J. Crowder Dec 16 '21 at 08:29
  • @dev - Unfortunately, I don't think you can prevent the `9-9` (and similar) pasting issue if you keep `type="number"`. The reason is that pasting something like that results in an invalid number, so `value` is `""` (because what the user has provided so far is invalid). As far as I can tell, there's **no way** to access the invalid text in the `input`! (Which strikes me as truly bizarre.) See the answers to [this question](https://stackoverflow.com/questions/40073053/) and [this one](https://stackoverflow.com/questions/18852244/). – T.J. Crowder Dec 16 '21 at 09:12
  • So I suggest using CSS to indicate that the value is invalid (with the `::invalid` pseudo-class) and don't worry about it. Your code won't see the value `"9-9"` (it'll see `""` instead). – T.J. Crowder Dec 16 '21 at 09:12
  • @ T.J so there is no way to make it working isn't if I use onInput then it will work for copy and paste but (999.) this is an issue, if I use onKeyDown on copy pasting (999.99) able to enter but on typing it will block – dev Dec 16 '21 at 09:17
  • @dev - I don't quite understand your question there, but no, using `onInput` will not make it work for paste -- the `input` doesn't even tell us what the text is that was pasted. That information is just not available from the DOM input. – T.J. Crowder Dec 16 '21 at 09:20
  • So to the current answer which you have shared, is there a way to block when pasting it can we block it or can we remove the special characters and input it (999.99-9) => (999999) – dev Dec 16 '21 at 09:28
  • @dev - Again, no, because the `input` doesn't tell us what those characters are. – T.J. Crowder Dec 16 '21 at 09:30
  • So this will be the closes solution we can isn't – dev Dec 16 '21 at 09:31
  • do we have a way to block copy paste for input field – dev Dec 16 '21 at 09:32
  • @dev - Sadly, I think it is the closest. Re paste: Yes, you can (`onPaste={e => e.preventDefault()}`), but **don't**. Users should be able to paste into fields. Again, just highlight for the user that what they've typed is invalid and move on. – T.J. Crowder Dec 16 '21 at 09:34
  • one more doubt, when i type spacebare two times, I am able to see dot in the input field (999) => (two times spacebar) => (999.) – dev Dec 16 '21 at 09:36
  • @dev - No idea why your browser does that with `type="number"`, but those spaces won't be in the value. – T.J. Crowder Dec 16 '21 at 09:37
  • https://codesandbox.io/s/awesome-night-o6nh1 – dev Dec 16 '21 at 10:01
  • This is working in browser on desktop but not in mobile androd, I have added the sandbox link, this is not working in mobile – dev Dec 16 '21 at 10:03
  • @dev - "Not working" doesn't tell me anything. **Again**, note that the input may well have text that you cannot see in your code (invalid numeric chars, like `9-9`). **Again**, just flag it up for the user and don't worry about it, your code won't see them, and valid numeric chars you want to remove can be removed when you go to use the value (as I said in the answer above). I'm going to have to step away from this now. Good luck. – T.J. Crowder Dec 16 '21 at 10:06
  • okay, understood, i was trying to make it working on browser and mobile, since same code is behaving in both ways I was confused – dev Dec 16 '21 at 10:14
  • @dev - FYI, I found a way to get the invalid text, at least on Chromium-based browsers: https://stackoverflow.com/a/70377326/157247 Sadly not on Firefox, and heaven only knows on various mobile ones. (And now I really have to disappear. :-) ) – T.J. Crowder Dec 16 '21 at 10:24