如何通过验证(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
);
}
})
);
}
我需要在每两位数字后自动加上冒号 (:)。 所以它看起来像: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
);
}
})
);
}