sanniassin / react-input-mask

Input masking component for React. Made with attention to UX.
MIT License
2.22k stars 258 forks source link

How to mask IP Address #104

Open deepaktomar12 opened 6 years ago

deepaktomar12 commented 6 years ago

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

jwilson64 commented 6 years ago

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

sorahn commented 6 years ago

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.

wilk commented 5 years ago

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
``
mplulu commented 4 years ago

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;
yangwawa0323 commented 1 year ago

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
};
ezequiel88 commented 6 months ago

Have we made any progress on this matter?