Sujeet Raman

Sujeet Raman

  • 825
  • 927
  • 347k

How to Create a Masked Input for All IPv4 format Addresses in React?

Jun 12 2024 6:04 AM

I'm working on a React component to handle IPv4 addresses with a fixed mask format (___ . ___ . ___ . ___), allowing users to edit individual parts of the address. However, I'm encountering some issues with maintaining the mask and ensuring a smooth user experience.
 

Specifically, I'm facing the following challenges:

  1. When clicking inside the text box, the mask disappears.
  2. Users can enter invalid characters and exceed the maximum length of the input field.
  3. Users should be able to input any valid IPv4 address (e.g., 192.168.0.1, 10.0.0.1, 172.16.0.1, 198.51.100.1, 127.0.0.1) and edit it by clicking on the ___ placeholders. They should be able to add up to 1 to 3 digits to each placeholder, but not more than 3 digits. Additionally, if the user clicks outside after editing, the modified IPv4 address should be considered final, but this functionality is not currently working.

I'm seeking advice on how to address these issues and ensure that the mask remains visible while allowing smooth editing of individual parts of the IPv4 address.

Any insights or suggestions would be greatly appreciated!

so far i ive tried

 

import React, { useState, useRef } from 'react';

const isIpv4 = (ip) => {
	const rgx = /\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/;
	return rgx.test(ip);
};

const IpAddressInput = () => {
	const [ value, setValue ] = useState('___ . ___ . ___ . ___');
	const inputRef = useRef(null);

	const handleFocus = () => {
		if (value === '___ . ___ . ___ . ___') {
			setValue('');
		}
	};

	const handleBlur = () => {
		if (!isIpv4(value.replace(/_/g, '0'))) {
			setValue('___ . ___ . ___ . ___');
		}
	};

	const handleChange = (e) => {
		let newValue = e.target.value.toUpperCase();
		newValue = newValue.replace(/[^0-9.]/g, '');

		const parts = newValue.split('.').map((part) => part.padEnd(3, '_')).join('.');

		setValue(parts.slice(0, 15));
	};

	return (
		<input
			type="text"
			value={value}
			onFocus={handleFocus}
			onBlur={handleBlur}
			onChange={handleChange}
			ref={inputRef}
			maxLength={15}
			size={15}
			style={{ width: 'calc(15ch + 10px)', fontFamily: 'monospace' }}
		/>
	);
};

export default IpAddressInput;

 


Answers (3)