Skip to content

Instantly share code, notes, and snippets.

@hxsf
Last active January 10, 2018 09:06
Show Gist options
  • Save hxsf/d6c86877e23e8fd6a6605b6696b62d2e to your computer and use it in GitHub Desktop.
Save hxsf/d6c86877e23e8fd6a6605b6696b62d2e to your computer and use it in GitHub Desktop.
JS Bin// source http://jsbin.com/lulezixobe

a IP/Subnet input component write by only javascript.

feature

  • auto complite
  • Delete & BackSapce Support
  • ArrowLeft & ArrowRight Support
  • IP Support
  • Subnet Support
  • Paste Support
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
IP: <input type="text" id="ip">
Subnet: <input type="text" id="subnet">
<script id="jsbin-javascript">
input = document.getElementById('ipinput')
let iparr = []
let iptemp = 0
input.addEventListener('keydown', (event) => {
const {key, keyCode} = event
console.log(event.target.selectionStart)
if (keyCode < 41 && keyCode > 36 || keyCode === 8 || keyCode === 46) {
return true
}
console.log(keyCode,key)
if (iparr.length >= 4 || (key !== '.' && (key < '0' || key > '9'))) {
event.preventDefault()
return false
}
if (key == '.') {
if (!iptemp || iparr.length >= 3) {
event.preventDefault()
return false
}
iparr.push(iptemp)
iptemp = 0
return true
}
let num = parseInt(key, 10)
if (iptemp < 256 && iptemp * 10 + num < 256) {
iptemp *= 10
iptemp += num
if (iptemp > 25 && iparr.length < 3) {
iparr.push(iptemp)
iptemp = 0
setTimeout(()=> {
event.target.value += '.'
},0)
}
} else {
event.preventDefault()
return false
}
console.log('ip:', iparr)
})
</script>
<script id="jsbin-source-javascript" type="text/javascript">input = document.getElementById('ipinput')
let iparr = []
let iptemp = 0
input.addEventListener('keydown', (event) => {
const {key, keyCode} = event
console.log(event.target.selectionStart)
if (keyCode < 41 && keyCode > 36 || keyCode === 8 || keyCode === 46) {
return true
}
console.log(keyCode,key)
if (iparr.length >= 4 || (key !== '.' && (key < '0' || key > '9'))) {
event.preventDefault()
return false
}
if (key == '.') {
if (!iptemp || iparr.length >= 3) {
event.preventDefault()
return false
}
iparr.push(iptemp)
iptemp = 0
return true
}
let num = parseInt(key, 10)
if (iptemp < 256 && iptemp * 10 + num < 256) {
iptemp *= 10
iptemp += num
if (iptemp > 25 && iparr.length < 3) {
iparr.push(iptemp)
iptemp = 0
setTimeout(()=> {
event.target.value += '.'
},0)
}
} else {
event.preventDefault()
return false
}
console.log('ip:', iparr)
})</script></body>
</html>
!function (window, document, undefined) {
enum KEY_CODE {
Tab = 9,
End = 35,
Home = 36,
ArrowLeft = 37,
ArrowRight = 39,
ForwardSlash = 191,
Dash = 189,
BackSpace = 8,
}
const ALLOW_KEYCODE = new Set([KEY_CODE.Tab, KEY_CODE.End, KEY_CODE.Home, KEY_CODE.ArrowLeft, KEY_CODE.ArrowRight])
enum IpType {
IP = 'ip',
SUB_NET = 'sub_net',
IP_RANGE = 'ip_range'
}
function do_ip(str: string, auto_complite: boolean = true): [boolean, string, number] {
const arr = str.split('.')
if (arr.length > 4) {
return [false, null, 0]
}
let i = 0;
for (; i < arr.length; ++i) {
if (arr[i] === '') {
// arr[i] = '0'
continue
} else {
arr[i] = parseInt(arr[i], 10) + ''
}
if (i > 0 && i < 3) {
if (!/^(?:25[0-5]|2[0-4]\d|(?:1\d{2}|[0-9]?\d))$/.test(arr[i])) {
return [false, null, 0]
}
} else if (!/^(?:25[0-5]|2[0-4]\d|(?:1\d{2}|[1-9]?\d))$/.test(arr[i])) {
return [false, null, 0]
}
}
if (auto_complite && i-1 < 3 && parseInt(arr[i-1], 10) > 25) {
arr.push('')
return [true, arr.join('.'), 1]
}
return [true, arr.join('.'), 0]
}
function do_subnet(str: string, auto_complite: boolean = true): [boolean, string, number] {
const arr = str.split('/')
if (arr.length === 1) {
if (/^(?:25[0-5]|2[0-4]\d|(?:1\d{2}|[1-9]?\d))(?:\.(?:25[0-5]|2[0-4]\d|(?:1\d{2}|[0-9]?\d))){3}$/.test(arr[0]) && parseInt(str.split('.')[3], 10) > 25) {
if (auto_complite) {
return [true, str + '/', 1]
}
return [true, str, 0]
}
return do_ip(str)
} else if (arr.length === 2 && /^(?:25[0-5]|2[0-4]\d|(?:1\d{2}|[1-9]?\d))(?:\.(?:25[0-5]|2[0-4]\d|(?:1\d{2}|[0-9]?\d))){3}$/.test(arr[0])) {
const [is_valid, ip, hit_len] = do_ip(str)
if (!is_valid) {
return [false, null, 0]
}
if (arr[1] == '') {
return [true, ip + '/' + arr[1], hit_len]
}
arr[1] = parseInt(arr[1], 10) + ''
if (parseInt(arr[1], 10) <= 32) {
return [true, ip + '/' + arr[1], hit_len]
}
return [false, null, 0]
}
}
function valid(str: string, type: IpType, auto_complite?: boolean): [boolean, string, number] {
switch (type) {
case IpType.IP:
return do_ip(str, auto_complite)
case IpType.SUB_NET:
return do_subnet(str, auto_complite)
// case IpType.IP_RANGE:
default:
throw new Error('不支持!')
}
}
(<any>window).ip_input_factory = function ip_input_factory(input_element: HTMLInputElement, opts: {type: IpType} = { type: IpType.IP}): void {
input_element.addEventListener('paste', (event) => {
const {selectionStart, selectionEnd, value} = input_element
let tarr = value.split('')
tarr.splice(selectionStart, Math.max(selectionEnd - selectionStart, 0), event.clipboardData.getData('text/plain'))
const val = tarr.join('')
const [is_valid, ip, hit_len] = valid(val, IpType.IP)
if (is_valid) {
input_element.value = ip
input_element.setSelectionRange(ip.length)
}
event.preventDefault()
return false
})
// let iparr[cursor] = 0
input_element.addEventListener('keydown', (event) => {
const { key, keyCode, ctrlKey, altKey, shiftKey, metaKey } = event
const {selectionStart, selectionEnd, value} = input_element
// console.log({keyCode, key, selectionStart, selectionEnd, len: value.length, ctrlKey, altKey, shiftKey, metaKey})
if (ALLOW_KEYCODE.has(keyCode) || (opts.type == IpType.SUB_NET && keyCode == KEY_CODE.ForwardSlash) || (opts.type == IpType.IP_RANGE && keyCode === KEY_CODE.Dash) || (ctrlKey || metaKey)) {
// console.log('true')
return true
}
if (!(((keyCode < 58 && keyCode > 47 || keyCode === 190) && !shiftKey) || (keyCode == 8 || keyCode == 46))) {
event.preventDefault()
return false
}
let tarr = value.split('')
let step = 1
if (keyCode == 8) {
if (selectionEnd === selectionStart) {
tarr.splice(selectionStart - 1, 1)
} else {
tarr.splice(selectionStart, selectionEnd - selectionStart)
}
step = -1
} else if (keyCode == 46) {
tarr.splice(selectionStart, Math.max(selectionEnd - selectionStart, 1))
step = 0
} else {
tarr.splice(selectionStart, selectionEnd - selectionStart, key)
}
const val = tarr.join('')
const [is_valid, ip, hit_len] = valid(val, opts.type, keyCode != KEY_CODE.BackSpace)
if (is_valid) {
input_element.value = ip
input_element.setSelectionRange(selectionStart + step + hit_len, selectionEnd + step + hit_len)
}
event.preventDefault()
// console.log('ip:', input_element.value)
})
}
}(window, document)
input = document.getElementById('ipinput')
let iparr = []
let iptemp = 0
input.addEventListener('keydown', (event) => {
const {key, keyCode} = event
console.log(event.target.selectionStart)
if (keyCode < 41 && keyCode > 36 || keyCode === 8 || keyCode === 46) {
return true
}
console.log(keyCode,key)
if (iparr.length >= 4 || (key !== '.' && (key < '0' || key > '9'))) {
event.preventDefault()
return false
}
if (key == '.') {
if (!iptemp || iparr.length >= 3) {
event.preventDefault()
return false
}
iparr.push(iptemp)
iptemp = 0
return true
}
let num = parseInt(key, 10)
if (iptemp < 256 && iptemp * 10 + num < 256) {
iptemp *= 10
iptemp += num
if (iptemp > 25 && iparr.length < 3) {
iparr.push(iptemp)
iptemp = 0
setTimeout(()=> {
event.target.value += '.'
},0)
}
} else {
event.preventDefault()
return false
}
console.log('ip:', iparr)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment