如何通过验证(javascript 或 angularjs)将冒号自动放入 mac 地址的文本框中?

How to put colon automatically in text box for mac address with validation (javascript or angularjs)?

我需要在每两位数字后自动加上冒号 (:)。 所以它看起来像:DD:A4:55:FD:56:CC

我已经写了一个逻辑,现在我也可以输入冒号了,但是当我按下退格键时,我无法从冒号返回。

当我将光标放在已经写入的两位数上时,它允许写入多于两位数,这是我不想要的。

这是我的代码:
HTML:

    <input type="text" ng-model="mac.macAddress" name="macAddress" id="macAddress" 
           maxlength="17" ng-change="macAddressFormat(mac)">

JS:

$scope.macAddressFormat = function(mac){

        var macAddress  = mac.macAddress;

        var filteredMac = macAddress.replace(/\:/g, '');
        var length  = filteredMac.length;

        if(length % 2 == 0 && length > 1 && length < 12){
            mac.macAddress  = mac.macAddress + ':';
        }
        else{
           console.log('no');
        }
    }

请知道我哪里错了。 谢谢 !提前...

您可以使用 Regex 进行简化。我在您的输入中添加了一个默认值,并添加了一个按钮,如果 macAddress 的长度有效,该按钮将调用这行代码:

macAddr.replace(/(.{2})/g,":").slice(0,-1).toUpperCase();

代码:

var app = angular.module("macformat", []); 
app.controller("myCtrl", function($scope) {
  $scope.macAddressFormat = function(mac){

    mac.macAddress = mac.macAddress.toUpperCase();
    var macAddr  = mac.macAddress;
    var alphaNum= /^[A-Za-z0-9]+$/;

    // The Input will be changed only if the length is 12 and is alphanumeric
    if(macAddr.length == 12 && alphaNum.test(macAddr)){
  
        // A lot is going on here. 
        // .replace(/(.{2})/g,":") - adds ':' every other 2 characters
        // .slice(0,-1) - cuts the last character, because ':' is added
        // .toUpperCase() - because it's good practice for writing MAC Addresses
        macAddr = macAddr.replace(/(.{2})/g,":").slice(0,-1).toUpperCase();
    
        // Place Formatted MAC Address to Input
        mac.macAddress = macAddr;
        console.log("Tadaaa");
    }
    // Developer info in console if length is not 12
    else if (macAddr.length < 12 && alphaNum.test(macAddr)){
        console.log(12 - macAddr.length + " characters left");
    }
    else if (macAddr.length > 12 && alphaNum.test(macAddr)){
        console.log(macAddr.length - 12 + " characters too many");
    }
    // Developer info in console if macAddress contains non alpha-numeric
    else if (!alphaNum.test(macAddr)){
        console.log("only alpha-numeric allowed");
    }
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div ng-app="macformat" ng-controller="myCtrl">
  <p>Write MAC Address here without ":" and it will be formatted automatically:</p>
  <input type="text" ng-model="mac.macAddress" name="macAddress" id="macAddress" 
           maxlength="17" ng-change="macAddressFormat(mac)">
  <p><i>Check console for info</i></p>
</div>

好的,所以,这是我的解决方案。这会过滤 non-hex、auto-inserts 冒号,在删除时跳过它们,允许插入,并处理特殊情况(比如跳过已经存在的冒号)。丑吗?是的,也许。它有效吗?是的,到目前为止我发现的所有情况。如果发现并修复它们,我会在出现任何遗漏案例时进行更新。随意在您自己的代码中使用它,赚取 $$$,过上好日子。

ngOnInit() {
    this.subs.push(
        this.macForm.controls.mac.valueChanges.subscribe((mac: string) => {
            let start = this.searchField.nativeElement.selectionStart;
            let colonStartedAtRight;
            const noColons = mac.replace(/([^A-Za-z0-9])/g, '').toLowerCase();
            const isHex = (parseInt(noColons, 16).toString(16).padStart(noColons.length, ‘0’) === noColons);
            if (!isHex) { start--; }
            if (this.searchMeterForm.controls.searchMeterField.value.charAt(this.searchField.nativeElement.selectionStart) === ':') {
                colonStartedAtRight = true;
            }
            let updatedMac = mac
                .replace(/(^:|[^A-Fa-f0-9:]|:{2,})/g, '') // Restrict characters to only those in MAC addresses
                .toUpperCase();


            for (let i = 0; i < 4; i++) {
                updatedMac = updatedMac
                    .replace(/(?:^|:)([A-Fa-f0-9]{1}):/g, '') // Auto remove colons around single characters
                    .replace(/([A-Fa-f0-9]{2})([A-Fa-f0-9]{2}|[A-Fa-f0-9]{1})/g, ':'); // Auto insert colon every 2 characters
            }

            this.searchMeterForm.controls.searchMeterField.patchValue(
                updatedMac.substring(0, 17),
                { emitEvent: false, onlySelf: true }
            );
            const colonBeforeCount = mac.split(':').length - 1;
            const colonAfterCount = this.searchMeterForm.controls.searchMeterField.value.split(':').length - 1;
            const colonAdded = colonAfterCount > colonBeforeCount && start % 3 === 0 ? 1 : 0;
            this.searchField.nativeElement.setSelectionRange(
                start + colonAdded,
                start + colonAdded
            );
            let nowTotalColons = 0;
            for (let i = 0, length = mac.length; i < length; i++) {
                nowTotalColons += mac.charAt(i) === ':' ? 1 : 0;
            }
            if (this.searchMeterForm.controls.searchMeterField.value.charAt(this.searchField.nativeElement.selectionStart) === ':' &&
                !(this.beforeTotalColons > nowTotalColons)) {
                this.searchField.nativeElement.setSelectionRange(
                    this.searchField.nativeElement.selectionStart + 1,
                    this.searchField.nativeElement.selectionStart + 1
                );
            }
            this.beforeTotalColons = nowTotalColons;

            if (this.searchMeterForm.controls.searchMeterField.value.charAt(this.searchField.nativeElement.selectionStart - 1) === ':' &&
                colonStartedAtRight &&
                this.searchField.nativeElement.selectionStart === start) {
                this.searchField.nativeElement.setSelectionRange(
                    this.searchField.nativeElement.selectionStart + 1,
                    this.searchField.nativeElement.selectionStart + 1
                );
            }
        })
    );
}