11

I'm trying to apply a mask in a TextField component, but im without success.

I already tried this solution but not worked. I tried every way but seems to not work anymore.

I tried to follow the instructions given in docs but they use the Input component and this component is breaking my design.

Anyone knows a way to mask the TextField component? I'm using material-ui 1.0.0-beta.24

KyleMit
  • 30,350
  • 66
  • 462
  • 664
Eduardo Lima
  • 143
  • 1
  • 2
  • 7
  • Could you provide some of the code you're using? Also, how does the `Input` component break your design? – Jules Dupont Feb 12 '18 at 10:31
  • 1
    @julesDupont When I use the input component it gets different from the TextField component visually speaking. As you can see is [this screenshot](https://i.imgur.com/6G42zAk.png). The code is really necessary? if it is, i'll post. but it's just a bunch of Grids and TextField inputs – Eduardo Lima Feb 12 '18 at 13:04
  • There's probably no need for code - I just wasn't clear about what you meant when you said the `Input` affected formatting. I've given you a solution that should allow you to use a `TextField` with a mask. – Jules Dupont Feb 12 '18 at 15:40

1 Answers1

16

Use InputProps to set the mask directly on a TextField component. For example, suppose your desired mask is represented by the TextMaskCustom component. Then, instead of applying it to an Input directly, you can apply it to your TextField using the InputProps like so:

<TextField
  id="maskExample"
  label="Mask Example"
  className={classes.textField}
  margin="normal"
  InputProps={{
    inputComponent: TextMaskCustom,
    value: this.state.textmask,
    onChange: this.handleChange('textmask'),
  }}
/>

This works because a TextField is actually a wrapper around an Input component (with some other things mixed in). The InputProps prop of the TextField gives you access to the internal Input, so you can set the mask that way while preserving the styling of the TextField component.

Here's a full working example adapted from the demos in the docs:

import React from 'react';
import MaskedInput from 'react-text-mask';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import TextField from 'material-ui/TextField';

const styles = theme => ({
  container: {
    display: 'flex',
    flexWrap: 'wrap',
  },
  input: {
    margin: theme.spacing.unit,
  },
});

const TextMaskCustom = (props) => {
  const { inputRef, ...other } = props;

  return (
    <MaskedInput
      {...other}
      ref={inputRef}
      mask={['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/]}
      placeholderChar={'\u2000'}
      showMask
    />
  );
}

TextMaskCustom.propTypes = {
  inputRef: PropTypes.func.isRequired,
};

class FormattedInputs extends React.Component {
  state = {
    textmask: '(1  )    -    ',
  };

  handleChange = name => event => {
    this.setState({
      [name]: event.target.value,
    });
  };

  render() {
    const { classes } = this.props;
    return (
      <div className={classes.container}>
        <TextField
          id="maskExample"
          label="Mask Example"
          className={classes.textField}
          margin="normal"
          InputProps={{
            inputComponent: TextMaskCustom,
            value:this.state.textmask,
            onChange: this.handleChange('textmask'),
          }}
        />
      </div>
    );
  }
}

FormattedInputs.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(FormattedInputs);
Jules Dupont
  • 7,259
  • 7
  • 39
  • 39
  • 1
    How to pass custom prefix to inputComponent as props. For instance, if I want to change the currency sign for inputComponent in NumberFormated Type – Eltaf Hussain Sep 06 '18 at 15:10
  • ``` InputProps={{ inputComponent: TextMaskCustom, inputProps: {...} }} ``` adding the (lowerCase) inputProps lets you pass in props for use in your inputComponent. – Nate- Oct 21 '19 at 21:34
  • 7
    If you're using the newer Material UI (imported with '@material-ui/core', then you will get this error: "Material-UI: you have provided a `inputComponent` to the input component that does not correctly handle the `inputRef` prop. Make sure the `inputRef` prop is called with a HTMLInputElement." To fix this, change the `ref=` line in `TextMaskCustom` for: ```ref={ref => { inputRef(ref ? ref.inputElement : null); }}``` – jon1467 Dec 12 '19 at 17:06