react-input-mask icon indicating copy to clipboard operation
react-input-mask copied to clipboard

How to mask IP Address

Open deepaktomar12 opened this issue 8 years ago • 6 comments

Hi,

How to mask IP Address, because ip address may be 111.111.111.111 or 11.11.11.11 or 121.11.1.111,

do you have setting format please share with us

deepaktomar12 avatar Sep 28 '17 12:09 deepaktomar12

@deepaktomar12 it should be something along the lines of <InputMask mask="(999.999.999.999)" maskChar="0" />

jwilson64 avatar Nov 15 '17 17:11 jwilson64

But it needs to support a range of characters in each 'block' of the mask. cleave.js and react-number-format don't seem to support this either.

sorahn avatar Feb 25 '18 22:02 sorahn

I did something like this:

import React from 'react'
import MaskedInput from 'react-text-mask'
import PropTypes from 'prop-types'

const IpMaskInput = ({ inputRef, ...other }) => {
  return <MaskedInput
    {...other}
    ref={ref => {
      inputRef(ref ? ref.inputElement : null)
    }}
    // 192.168.1.1
    mask={[/[1-2]/, /[0-9]/, /[0-9]/, '.', /[1-2]/, /[0-9]/, /[0-9]/, '.', /[1-2]/, /[0-9]/, /[0-9]/, '.', /[1-2]/, /[0-9]/, /[0-9]/]}
    // ensures that every subsection of the ip address is greater than 0 and lower than 256
    pipe={value => {
      const subips = value.split('.')
      const invalidSubips = subips.filter(ip => {
        ip = parseInt(ip) 
        return ip < 0 || ip > 255
      })
      return invalidSubips.length > 0 ? false : value
    }}
    placeholderChar={'\u2000'}
    keepCharPositions={true}
    showMask
  />
}

PropTypes.propTypes = {
  inputRef: PropTypes.func.isRequired
}

export default IpMaskInput
``

wilk avatar Jan 14 '19 11:01 wilk

My code in react-input-mask

import React from "react";
import InputMask from "react-input-mask";
// 127.0.0.1
function InputIPAddress(props) {
  function checkIpValue(value) {
    const subips = value.split('.')
    if (subips.length > 4) {
      return false
    }
    const invalidSubips = subips.filter(ip => {
      ip = parseInt(ip)
      return ip < 0 || ip > 255
    })
    if (invalidSubips.length !== 0) {
      return false
    }
    let emptyIpCount = 0
    subips.forEach(ip => {
      if (ip === "") {
        emptyIpCount++
      }
    })
    if (emptyIpCount > 1) {
      return false
    }
    return true
  }

  return (
    <InputMask
      formatChars={{
        '9': '[0-9\.]',
      }}
      mask="999999999999999"
      maskChar={null}
      alwaysShowMask={false}
      beforeMaskedValueChange={(newState, oldState, userInput) => {
        let value = newState.value;
        const oldValue = oldState.value;
        let selection = newState.selection;
        let cursorPosition = selection ? selection.start : null;
        const result = checkIpValue(value)
        if (!result) {
          value = value.trim()
          // try to add . before the last char to see if it is valid ip address
          const newValue = value.substring(0, value.length - 1) + "." + value.substring(value.length - 1);
          if (checkIpValue(newValue)) {
            cursorPosition++
            selection = { start: cursorPosition, end: cursorPosition };
            value = newValue
          } else {
            value = oldValue
          }
        }

        return {
          value,
          selection
        };
      }}
    />
  )
}

export default InputIPAddress;

mplulu avatar Jun 02 '20 11:06 mplulu

I did something like this:

import React from 'react'
import MaskedInput from 'react-text-mask'
import PropTypes from 'prop-types'

const IpMaskInput = ({ inputRef, ...other }) => {
  return <MaskedInput
    {...other}
    ref={ref => {
      inputRef(ref ? ref.inputElement : null)
    }}
    // 192.168.1.1
    mask={[/[1-2]/, /[0-9]/, /[0-9]/, '.', /[1-2]/, /[0-9]/, /[0-9]/, '.', /[1-2]/, /[0-9]/, /[0-9]/, '.', /[1-2]/, /[0-9]/, /[0-9]/]}
    // ensures that every subsection of the ip address is greater than 0 and lower than 256
    pipe={value => {
      const subips = value.split('.')
      const invalidSubips = subips.filter(ip => {
        ip = parseInt(ip) 
        return ip < 0 || ip > 255
      })
      return invalidSubips.length > 0 ? false : value
    }}
    placeholderChar={'\u2000'}
    keepCharPositions={true}
    showMask
  />
}

PropTypes.propTypes = {
  inputRef: PropTypes.func.isRequired
}

export default IpMaskInput
``

ip mask

The new version has a property changed.

The beforeMaskedStateChange replaced the old beforeMaskedValueChange property, I put the code here

import React from 'react';
import InputMask from 'react-input-mask';
import PropTypes from 'prop-types';
import { OutlinedInput } from '@mui/material';

// 127.0.0.1
function InputIPAddress(props) {
    function checkIpValue(value) {
        const subips = value.split('.');
        if (subips.length > 4) {
            return false;
        }
        const invalidSubips = subips.filter((ip) => {
            ip = parseInt(ip);
            return ip < 0 || ip > 255;
        });
        if (invalidSubips.length !== 0) {
            return false;
        }
        let emptyIpCount = 0;
        subips.forEach((ip) => {
            if (ip === '') {
                emptyIpCount++;
            }
        });
        if (emptyIpCount > 1) {
            return false;
        }
        return true;
    }

    const beforeMaskedStateChange = ({ previousState, currentState, nextState }) => {
        let { value, selection } = currentState;
        let oldValue = previousState?.value;
        console.log('[DEBUG]:', currentState, previousState);

        if (value && !/^[\d\.]+$/.test(value)) {
            return previousState;
        }
        let cursorPosition = selection ? selection.start : null;
        let result = checkIpValue(value);
        if (!result) {
            value = value.trim();
            const newValue = value.substring(0, value.length - 1) + '.' + value.substring(value.length - 1);
            if (checkIpValue(newValue)) {
                cursorPosition++;
                selection = { start: cursorPosition, end: cursorPosition };
                value = newValue;
            } else {
                value = oldValue;
            }
        }

        return {
            ...nextState,
            selection,
            value
        };
    };

    return (
        <InputMask
            mask="999999999999999"
            value={props.value}
            onChange={props.onChange}
            alwaysShowMask={false}
            beforeMaskedStateChange={beforeMaskedStateChange}
        >
            <OutlinedInput />
        </InputMask>
    );
}

export default InputIPAddress;

InputIPAddress.propTypes = {
    value: PropTypes.string,
    onChange: PropTypes.func,
    innerRef: PropTypes.object
};

yangwawa0323 avatar Dec 15 '22 14:12 yangwawa0323

Have we made any progress on this matter?

ezequiel88 avatar Feb 28 '24 23:02 ezequiel88