19

I want to only allow specific characters to be entered into a Material-UI TextField. I have seen different examples that I have tried but I can't get any of them to work. In my last try I cut everything back to the bare minimum and had this

<TextField
  inputProps={{ pattern: "[a-z]" }}
/>

It seems as though the pattern is just being ignored.

Is this still a valid way to apply a pattern

Thank you to anyone that can help me

Ryan Cogswell
  • 75,046
  • 9
  • 218
  • 198
Keith Withall
  • 201
  • 1
  • 2
  • 4

1 Answers1

16

Below is an example showing this working. The "pattern" attribute on input won't prevent invalid characters from being entered, but it will mark the input with the ":invalid" pseudoclass. Here is one resource where you can read more. I have added some styling so that you can tell the pattern is working.

If you want to prevent invalid characters from being entered, then you can see my previous answer for an example (based on the demos) using react-text-mask: How can I set material-ui TextField to accept only Hexidecimal characters

import React from "react";
import ReactDOM from "react-dom";

import TextField from "@material-ui/core/TextField";
import { withStyles } from "@material-ui/core/styles";

const styles = {
  input: {
    "&:invalid": {
      border: "red solid 2px"
    }
  }
};
function App({ classes }) {
  return (
    <TextField
      inputProps={{ className: classes.input, pattern: "[a-z]{1,15}" }}
    />
  );
}
const StyledApp = withStyles(styles)(App);
const rootElement = document.getElementById("root");
ReactDOM.render(<StyledApp />, rootElement);

Edit TextField pattern

Ryan Cogswell
  • 75,046
  • 9
  • 218
  • 198
  • The reason that I am doing this is so that large chunks of text can be copy/pasted from a mainframe system to a webpage. The mainframe uses characters that conflict with other systems so wanted to remove them. I had looked at your previous answer but discounted it because you had to set up a mask for each character and I don't know how many characters I will get. Is there a way of making the mask dynamic? – Keith Withall Mar 20 '19 at 15:03
  • react-text-mask is definitely more geared towards fixed length, but you can look at the "mask function" option to see if it will meet your needs: https://github.com/text-mask/text-mask/blob/master/componentDocumentation.md#mask-function – Ryan Cogswell Mar 20 '19 at 15:09
  • The simplest approach may be to just do a custom `onChange` that strips out the invalid characters. – Ryan Cogswell Mar 20 '19 at 17:58
  • I started out doing that but that causes a problem for React. If you are inserting text into the middle of the string as soon as you enter an invalid character that is stripped out the cursor moves to the end of the input field. It seems that you can't change the string during onChange processing. It is detailed here https://github.com/mui-org/material-ui/issues/4430 – Keith Withall Mar 21 '19 at 12:02
  • I guess I’m not surprised that it’s problematic. If you use the pattern to detect invalid input, you could provide a “clean” button or automatically clean it before sending it to the backend. Depends on whether the cleaning is likely to change it in a way that may require manual remediation after stripping out invalid characters. – Ryan Cogswell Mar 21 '19 at 12:19
  • I am trying to use your example to make the mask dynamic but I can't see how to pass the mask into TextMaskCustom. Do you know how to do that – Keith Withall Mar 21 '19 at 13:57
  • Here is an example of how to use the function: https://codesandbox.io/s/827m9m4o9j – Ryan Cogswell Mar 21 '19 at 17:23
  • Thank you for that answer but what I meant was how do I make hexRegEx dynamic. I would like to be able to have different regular expressions for different TextFields – Keith Withall Mar 21 '19 at 17:30
  • Here is an example using two different regular expressions: https://codesandbox.io/s/5wwpxklrwp – Ryan Cogswell Mar 21 '19 at 18:53