Reputation: 23
I don't have much experience with JavaScript or jQuery.
I tried to use Tampermonkey to auto correct the input field for a MAC address.
The site wants a MAC address formatted as 00:00:00:00:00:00
.
So I wrote this script for Tampermonkey so it automatically adds the colons while I'm typing:
// ==UserScript==
// @name Name
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Adds colons to the mac adress of the Mac Field
// @author You
// @match Somesite
// @grant none
// @require http://code.jquery.com/jquery-latest.js
// ==/UserScript==
document.getElementById("MAC").addEventListener('keyup', function() {
var mac = document.getElementById('MAC').value;
var macs = mac.split('');
var colons = ["2", "5", "8", "11", "14"];
for (var col in colons) {
if (macs[col] == "-") {
macs[col] = ":";
} else if (macs[col] != "") {
} else if (macs[col] != ":") {
var colo = col + 1;
macs[colo] = macs[col];
macs[col] = ":";
}
}
mac = macs.toString();
});
<input id=MAC />
But it don't work. The ID of the inputfield is MAC
.
Where and how much did I do wrong?
SOLUTION
Thanks to @i-wrestled-a-bear-once and @freginold for the , my oppion, best solutions
I'm using now a slightly changed version from @freginold
var back = true;
function isHex(char) {
// check if char is a hex char
if (!isNaN(parseInt(char))) {
return true;
} else {
switch (char.toLowerCase()) {
case "a":
case "b":
case "c":
case "d":
case "e":
case "f":
return true;
}
return false;
}
}
document.getElementById("MAC").addEventListener('keydown', function() {
var key = event.keyCode || event.charCode;
if( key == 8 || key == 46 ) {
back = false;
}
});
document.getElementById("MAC").addEventListener('keyup', function() {
var key = event.keyCode || event.charCode;
var mac = document.getElementById('MAC').value;
var newMac = mac.replace("-", ""); // remove any dashes
if ((isHex(mac[mac.length - 1]) && (isHex(mac[mac.length - 2])) && (mac.length <= 16) && (back))) {
// if last two chars are numbers, insert a colon
newMac = newMac + ":";
}
back = true;
document.getElementById('MAC').value = newMac; // put new value into input field
});
Upvotes: 1
Views: 4708
Reputation: 11
built on @KungWaz's answer by using jQuery and supporting backspace/delete
$("#MAC").keydown(function(e) {
// firefox has different values for keys
if ([186, 189, 59, 173, 32].includes(e.which))
return false;
});
$("#MAC").keyup(function(e) {
let start = $(this).prop("selectionStart")
let end = $(this).prop("selectionEnd")
let addedColon = false
// ignore backspace and delete
if ([8, 46].includes(e.which)) {
return true
}
var macs = $(this).val().split('');
var colons = [2, 5, 8, 11, 14];
for (var col in colons) {
if (colons[col] <= macs.length) {
if (macs[colons[col]] !== ":") {
if (macs[colons[col] - 1] == ":" || macs[colons[col] + 1] == ":") {
// dont add colon if there is one nearby
// that way you can edit the middle of the mac address
continue
}
macs.splice(colons[col], 0, ":");
addedColon = true
$(this).focus()
}
}
}
$(this).val(macs.join('').substring(0, 17))
if (start == end && addedColon) {
//if not selecting text
$(this)[0].setSelectionRange(start + 1, end + 1)
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id=MAC maxlength="17"/>
Upvotes: 0
Reputation: 3956
You could simplify it and check if the last two characters in the string are hex characters (0-9, A-F) and if so, insert a :
. You can also use .replace()
to remove any occurrence of -
if you (or someone else) types a dash instead of a colon.
That way you can cover inserting colons if you don't type them at all, as well as converting any typed dashes to colons.
Here's a working example:
// ==UserScript==
// @name Name
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Adds colons to the mac adress of the Mac Field
// @author You
// @match Somesite
// @grant none
// @require http://code.jquery.com/jquery-latest.js
// ==/UserScript==
function isHex(char) {
if (!isNaN(parseInt(char))) {
return true;
} else {
switch (char.toLowerCase()) {
case "a":
case "b":
case "c":
case "d":
case "e":
case "f":
return true;
break;
}
return false;
}
}
document.getElementById("MAC").addEventListener('keyup', function() {
var mac = document.getElementById('MAC').value;
if (mac.length < 2) {
return;
}
var newMac = mac.replace("-", "");
if ((isHex(mac[mac.length - 1]) && (isHex(mac[mac.length - 2])))) {
newMac = newMac + ":";
}
document.getElementById('MAC').value = newMac;
});
document.getElementById('MAC').focus(); // autofocus for testing
<input id=MAC />
Upvotes: 1
Reputation: 23409
replace(/[^\d|A-Z]/g, '')
removes any non alphanumeric charsmatch(/.{1,2}/g)
breaks the string into chunks of 2join(":")
joins the chunks and puts a colon in between them// ==UserScript==
// @name Name
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Adds colons to the mac adress of the Mac Field
// @author You
// @match Somesite
// @grant none
// @require http://code.jquery.com/jquery-latest.js
// ==/UserScript==
document.getElementById("MAC").addEventListener('keyup', function() {
// remove non digits, break it into chunks of 2 and join with a colon
this.value =
(this.value.toUpperCase()
.replace(/[^\d|A-Z]/g, '')
.match(/.{1,2}/g) || [])
.join(":")
});
<input id=MAC />
Upvotes: 7
Reputation: 8781
Just tried a simple logic.
var macelem = document.getElementById("MAC");
macelem.addEventListener('keyup', function() {
var mac = macelem.value,index=(mac.match(/\:/g)||[]).length;
if(index < 5 && index*3+2 == mac.length)
{
mac += ":";index++;
}
macelem.value = mac.substr(0,17);
});
<input id="MAC">
Upvotes: 0
Reputation: 1956
This should do the trick for you, you replace or add the ":" where it is needed. Then you cap the length of the string before you add it back to the input, to avoid getting to long MAC addresses.
Btw, you had some problems with your colons[col] slection to get your code to work.
document.getElementById("MAC").addEventListener('keyup', function() {
var mac = document.getElementById('MAC').value;
var macs = mac.split('');
var colons = [2, 5, 8, 11, 14];
for (var col in colons) {
if (colons[col] <= macs.length) {
if (macs[colons[col]] !== ":") {
macs.splice(colons[col], 0, ":");
}
}
}
document.getElementById('MAC').value = macs.join('').substring(0,17);
});
<input id=MAC />
Upvotes: 0
Reputation: 27051
You can use the function chunk
: (not my code, I just included it and modified your code to work with it.)
function chunk(str, n) {
var ret = [];
var i;
var len;
for(i = 0, len = str.length; i < len; i += n) {
ret.push(str.substr(i, n))
}
return ret
};
Then your code should look like:
document.getElementById("MAC").addEventListener('keyup', function() {
var mac = document.getElementById('MAC').value;
var macs = mac.split(':').join('');
macs = chunk(macs, 2).join(':');
document.getElementById('MAC').value = macs.toString();
});
demo
// ==UserScript==
// @name Name
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Adds colons to the mac adress of the Mac Field
// @author You
// @match Somesite
// @grant none
// @require http://code.jquery.com/jquery-latest.js
// ==/UserScript==
document.getElementById("MAC").addEventListener('keyup', function() {
var mac = document.getElementById('MAC').value;
var macs = mac.split(':').join('');
macs = chunk(macs, 2).join(':');
document.getElementById('MAC').value = macs.toString();
});
function chunk(str, n) {
var ret = [];
var i;
var len;
for(i = 0, len = str.length; i < len; i += n) {
ret.push(str.substr(i, n))
}
return ret
};
<input id=MAC maxlength="17"/>
Upvotes: 0