admin管理员组

文章数量:1393859

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    /
// @version      0.1
// @description  Adds colons to the mac adress of the Mac Field
// @author       You
// @match        Somesite
// @grant        none
// @require .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 />

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/
// @version      0.1
// @description  Adds colons to the mac adress of the Mac Field
// @author       You
// @match        Somesite
// @grant        none
// @require http://code.jquery./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

});
Share Improve this question edited Jan 24, 2018 at 15:17 Hitmare Chelien asked Jan 24, 2018 at 13:45 Hitmare ChelienHitmare Chelien 231 silver badge4 bronze badges 4
  • 2 Have you tried debugging it? – rmlan Commented Jan 24, 2018 at 13:47
  • 2 The immediate problem is that you don't do anything with the results of the function (presumably you want to set the field value to mac). There are other logic problems with the text replacement, but that's the first step. – Daniel Beck Commented Jan 24, 2018 at 13:49
  • 2 Possible duplicate of How can I insert a character after every n characters in javascript? – Carsten Løvbo Andersen Commented Jan 24, 2018 at 13:59
  • @rmlan how can i debug it in Tampermonkey? @daniel-beck ohh yeah with the mac = macs.toString();part i totally had a logic mistake xD . changed it to document.getElementById('MAC').value = macs.toString();and now it enters in the field. now i can searc hthe error in the correction logic because i get a lot of mas in the field – Hitmare Chelien Commented Jan 24, 2018 at 14:01
Add a ment  | 

6 Answers 6

Reset to default 7
  • replace(/[^\d|A-Z]/g, '') removes any non alphanumeric chars
  • match(/.{1,2}/g) breaks the string into chunks of 2
  • join(":") joins the chunks and puts a colon in between them

// ==UserScript==
// @name         Name
// @namespace    http://tampermonkey/
// @version      0.1
// @description  Adds colons to the mac adress of the Mac Field
// @author       You
// @match        Somesite
// @grant        none
// @require http://code.jquery./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 />

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/
// @version      0.1
// @description  Adds colons to the mac adress of the Mac Field
// @author       You
// @match        Somesite
// @grant        none
// @require http://code.jquery./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 />

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/
// @version      0.1
// @description  Adds colons to the mac adress of the Mac Field
// @author       You
// @match        Somesite
// @grant        none
// @require http://code.jquery./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"/>

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 />

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">

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./ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id=MAC maxlength="17"/>

本文标签: javascriptChange input field on keyup to match MAC address formatStack Overflow