32

I have a TextField for phone numbers in a short form. And then i want to mask this form field like (0)xxx xxx xx xx.

I'm trying to use react-input-mask plugin with Material-UI. But if i want to change input value, this is not updating the my main TextField.

        <TextField
          ref="phone"
          name="phone"
          type="text"
          value={this.state.phone}
          onChange={this.onChange}
        >
          <InputMask value={this.state.phone} onChange={this.onChange} mask="(0)999 999 99 99" maskChar=" " />            
        </TextField>

Actually, I couldn't find any documentation for masking with Material-UI. I'm trying to figure out how can i use with another plugins.

Jules Dupont
  • 7,259
  • 7
  • 39
  • 39
Batuhan Tozun
  • 487
  • 1
  • 5
  • 11

7 Answers7

32

Update

versions: material-ui 0.20.2, react-input-mask 2.0.4

Seems like the API changed a bit:

<InputMask
  mask="(0)999 999 99 99"
  value={this.state.phone}
  disabled={false}
  maskChar=" "
>
  {() => <TextField />}
</InputMask>

Demo

Edit throbbing-bird-9qgw9

Original

This should do the trick:

<TextField
  ref="phone"
  name="phone"
  type="text"
  value={this.state.phone}
  onChange={this.onChange}
>
  <InputMask mask="(0)999 999 99 99" maskChar=" " />
</TextField>

Demo:

Edit yl8p9jvq9

Kuf
  • 17,318
  • 6
  • 67
  • 91
  • Thanks for your answer. But, If I use like this I cant update state, and i cant trigger on change function... Real problem is this. – Batuhan Tozun Aug 21 '17 at 08:02
  • not sure what you mean. you can see in the example how changing the input updates the state using the `onChange` callback. can you explain what u meant? – Kuf Aug 21 '17 at 18:34
  • https://codesandbox.io/s/q8v1259oq6 please check this my label test floatingLabelText is hidden How I solve. – Thilina Sampath Sep 27 '17 at 10:57
  • 14
    This is a top hit on google but it is no longer valid with newer versions of material-ui – Swazimodo Mar 01 '18 at 18:47
  • In my case when I am using my previous number from auto suggestion then I didn't get last 4 digit for this masking :- `(999)-999-9999` – Sanat Gupta Dec 29 '21 at 12:13
23

For current version of Material-UI and react-input-mask, the following answer worked:

          <InputMask
            mask="(1)999 999 9999"
            value={self.state.inputValue}
            onChange={this.getTextFieldValue}
            className={this.props.classes.textField}
          >
            {() => <TextField
              id={attribute}
              label={attribute}
              name={attribute}
              className={this.props.classes.textField}
              margin="normal"
              type="text"
              />}
          </InputMask>
Sylvester
  • 421
  • 3
  • 6
2

This is valid for current version of react-input-mask and material-ui:

<InputMask
  mask="(0)999 999 99 99"
  value={this.state.phone}
  onChange={this.onChange}
>
  {() => <TextField />}
</InputMask>
piotros
  • 585
  • 5
  • 9
1

In mui 5 we can implement in the following way with help of react-imask library

customMaskComponent.js

import React, { useCallback } from 'react'
import PropTypes from 'prop-types'
import { IMaskInput } from 'react-imask'


const TextInput = React.forwardRef(function TextInput(props, ref) {
    const { onChange, ...other } = props
    return (
        <IMaskInput
            {...other}
            mask='00-0000000'
            definitions={{
                '#': /[1-9]/,
            }}
            placeholder={'XX-XXXXXXX'}
            inputRef={ref}
            onAccept={useCallback(value =>
                onChange({ target: { name: props.name, value } })
            )}
            overwrite
        />
    )
})

TextInput.propTypes = {
    name: PropTypes.string.isRequired,
    onChange: PropTypes.func.isRequired,
}

export { TextInput }

and form Component

<TextField
    label='Name'
    name={'Name'}
    fullWidth
    value={row.data.name}
    size='small'
    variant='standard'
    required={row.formDesc.name.is_mandatory === 'Y'}
    disabled={row.formDesc.name.is_editable === 'N'}
    onChange={useCallback(event =>
        onChangeRow(
            rowIndex,
            'name',
            event.target.value
        )
    )}
    InputLabelProps={{
        style: {
            fontSize: 18,
        }
    }}
    InputProps={{
        inputComponent: TextInput, // we are added the mask component here
    }}
    error={hasError('name')}
    helperText={getError('name')}
/>
KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133
0

Question:

codesandbox.io/s/q8v1259oq6 please check this my label test floatingLabelText is hidden How I solve. – Thilina Sampath

Work Around:

You can controll Label Position with "floatingLabelFixed" prop. At your handleChange look to state input value.

...when create with value:

constructor(props) {
    super(props);
    let value = props && props.value ? props.value : '';
    let floatingLabelFixed = !!value;

    this.state = {
        value,
        floatingLabelFixed,
    };

    this.handleChange = this.handleChange.bind(this);
}

...when edit (onChange):

handleChange(event) {
        let value = event && event.target && event.target.value ? event.target.value : '';
        let floatingLabelFixed = !!value;
        this.setState({
            value,
            floatingLabelFixed
        });
   }

...your input:

<TextField
        onChange={this.handleChange}
        value={this.state.value}
        floatingLabelFixed={this.state.floatingLabelFixed}/>
0

You can also use https://github.com/text-mask/text-mask. Seems like a solid project, even though it is not maintained anymore.

It provides a demo page for testing stuff and some addons that I successfully used to create a custom price input field (with material ui TextField component).

There's also an example codesandbox that I found somethere in the docs page, I believe.

Copy/pasting the codesandbox example here (you would need to adjust the mask to your needs):

// ... React imports.

import MaskedInput from "react-text-mask";
import createAutoCorrectedDatePipe from "text-mask-addons/dist/createAutoCorrectedDatePipe";


const autoCorrectedDatePipe = createAutoCorrectedDatePipe("mm/dd/yyyy", {
  minYear: 1900,
  maxYear: 2099
});

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

  return (
    <MaskedInput
      {...other}
      ref={ref => {
        inputRef(ref ? ref.inputElement : null);
      }}
      mask={[/\d/, /\d/, "/", /\d/, /\d/, "/", /\d/, /\d/, /\d/, /\d/]}
      placeholderChar={"\u2000"}
      pipe={autoCorrectedDatePipe}
      guide
      keepCharPositions
    />
  );
}

// ...

<div>
  <TextField
    label="react-text-mask"
    value={values.textmask}
    onChange={handleChange("textmask")}
    InputProps={{
      inputComponent: TextMaskCustom
    }}
    helperText="mm/dd/yyyy"
    variant="outlined"
    margin="dense"
  />
</div>

marcelocra
  • 2,094
  • 2
  • 24
  • 37
-2
<InputMask 
 mask="99999" // Format you need implemented
 value={cellNumber}
 onChange={this.inputHandler}
 placeholder="Cell Number"
 name="cellNumber" 
 required disableUnderline 
 style={style.inputfeild} 
 maskChar= {'_'}> // To display when there is no character typed

 {(inputProps) =>
  <Input {...inputProps}/>}

 </InputMask>

Just provide all your props to InputMask and then pass them as input props to the call back method in which you display your Textfield or Input field and it should work just fine.

Wakas Abbasid
  • 372
  • 2
  • 11