js automatically converts the input in the input box to half capitalized (tax number input box)

  • 2021-07-21 07:16:02
  • OfStack

In the past two days, there has been such a demand. When entering the tax number, it needs to be automatically converted into half-angle capitalization, and the input of punctuation marks and Chinese characters is prevented. (The following will be: full half angle conversion, text box selection, cursor position judgment, cursor position setting, etc.)

Then I began to search for information slowly.

Firstly, the difference between the whole half angle and how to transform it are checked.


var str = " Chinese ; ; A ";
for (var i = 0; i < str.length; i++) {
 if (str[i].match(/[\u0000-\u00ff]/)) {
 console.log(" Half-angle character ");
 } else if (str[i].match(/[\uff00-\uffff]/)) {
 console.log(" Full-width character  " + str[i] + " " + toSBC(str[i]));
 } else {
 console.log(str[i]);
 //  Text other than digital English, including Chinese and other national languages. 
 }
}

This is the difference between the two. After the text is converted into unicode, it can be compared. Both of them have their own ranges, with a half angle of 0x20 ~ 0x7E and a full angle of 0xFF01 ~ 0xFF5E. (This is hexadecimal, and the previous 0x means hexadecimal.)

In the case of conversion, except for the difference in spaces, all the others are full angle-half angle = 65248 (0xFEE0)

The specific conversion function is as follows: (This is a reliable method on the Internet, but the online method generally writes SBC and DBC backwards, and I corrected it here.)


//  Turn to full-width characters 
function toSBC(str) {
 var result = "";
 var len = str.length;
 for (var i = 0; i < len; i++) {
 var cCode = str.charCodeAt(i);
 // Difference between full angle and half angle (except space): 65248(10 Binary system )
 cCode = (cCode>=0x0021 && cCode<=0x007E)?(cCode + 65248) : cCode;
 // Handling Spaces 
 cCode = (cCode==0x0020)?0x03000:cCode;
 result += String.fromCharCode(cCode);
 }
 return result;
}
//  Turn half-angle character 
function toDBC(str) {
 var result = "";
 var len = str.length;
 for (var i = 0; i < len; i++) {
 var cCode = str.charCodeAt(i);
 // Difference between full angle and half angle (except space): 65248 ( 10 Binary) 
 cCode = (cCode>=0xFF01 && cCode<=0xFF5E)?(cCode - 65248) : cCode;
 // Handling Spaces 
 cCode = (cCode==0x03000)?0x0020:cCode;
 result += String.fromCharCode(cCode);
 }
 return result;
}

The difference between full angle and half angle is also found out, and we began to find a way to transform it, using input method.


var oldValue = "";
var $thisDom; //  Pretend to have jquery Adj. dom Element 
$thisDom.unbind().bind("input", function (e) {
 var reg = /^[0-9A-Za-z]*$/;
 var str = toDBC(e.target.value).toUpperCase();
 if (reg.test(str)) {
 oldValue = str;
 $(this).val(str);
 } else {
 $(this).val(oldValue);
 }
});

But there is a problem, that is, there is a problem with the cursor, which is always fine when entering in the last 1 bit, but when entering in the middle, the cursor will always jump to the last 1 bit. So I have the following cursor-related knowledge.

The following related codes are found on the Internet to control the cursor position.


function getCursortPosition(ctrl){
 var CaretPos = 0;
 if (document.selection) {
 ctrl.focus();
 var Sel = document.selection.createRange();
 Sel.moveStart('character', -ctrl.value.length);
 CaretPos = Sel.text.length;
 } else if (ctrl.selectionStart || ctrl.selectionStart == '0') {
 CaretPos = ctrl.selectionStart;
 }
 return (CaretPos);
}
function setCaretPosition(ctrl, pos){
 if (ctrl.setSelectionRange) {
 ctrl.focus();
 ctrl.setSelectionRange(pos, pos);
 } else if (ctrl.createTextRange) {
 var range = ctrl.createTextRange();
 range.collapse(true);
 range.moveEnd('character', pos);
 range.moveStart('character', pos);
 range.select();
 }
}

These are getting the cursor position and setting the cursor position. The textRange object is used here.

The TextRange object is an advanced feature of Dynamic HTML (DHTML) that enables many text-related tasks, such as searching and selecting text. Text range allows you to selectively select characters, words and sentences from the document. An TextRange object is an abstract object that establishes a start and end position on the text stream that an HTML document will display.

The following are the common properties and methods of TextRange:

Attributes:

boundingHeight Gets the height of the rectangle to which the TextRange object is bound

boundingLeft Gets the distance between the left edge of the rectangle that binds the TextRange object and the left side that contains the TextRange object

offsetLeft Gets the calculated left-hand position of the object relative to the layout or the parent coordinates specified by the offsetParent property

offsetTop gets the calculated top position of the object relative to the layout or the parent coordinates specified by the offsetParent attribute

htmlText Gets the width of the rectangle to which the TextRange object is bound

text Sets or gets the text contained in the scope

Methods:

moveStart Change the starting position of the scope

moveEnd End of Change Scope

collapse moves the insertion point to the beginning or end of the current range

move collapses a given range of text and moves an empty range by a given number of units

execCommand Executes a command on the current document, the current selection, or a given range

select sets the current selection to the current object

findText searches for text within text and sets the start and end points of the range to enclosing search strings.

For specific use, please see other people's articles at the address: https://www.ofstack.com/article/105787. htm

To get back to business, I spelled the above code into my code.


function toDBC(str) {
 var result = "";
 var len = str.length;
 for (var i = 0; i < len; i++) {
 var cCode = str.charCodeAt(i);
 // Difference between full angle and half angle (except space): 65248 ( 10 Binary) 
 cCode = (cCode>=0xFF01 && cCode<=0xFF5E)?(cCode - 65248) : cCode;
 // Handling Spaces 
 cCode = (cCode==0x03000)?0x0020:cCode;
 result += String.fromCharCode(cCode);
 }
 return result;
}
function getCursortPosition(ctrl){
 var CaretPos = 0;
 if (document.selection) {
 ctrl.focus();
 var Sel = document.selection.createRange();
 Sel.moveStart('character', -ctrl.value.length);
 CaretPos = Sel.text.length;
 } else if (ctrl.selectionStart || ctrl.selectionStart == '0') {
 CaretPos = ctrl.selectionStart;
 }
 return (CaretPos);
}
function setCaretPosition(ctrl, pos){
 if (ctrl.setSelectionRange) {
 ctrl.focus();
 ctrl.setSelectionRange(pos, pos);
 } else if (ctrl.createTextRange) {
 var range = ctrl.createTextRange();
 range.collapse(true);
 range.moveEnd('character', pos);
 range.moveStart('character', pos);
 range.select();
 }
}
var oldValue = this.model.get("taxNo");
$taxNoDom.unbind().bind("input", function (e) {
 var reg = /^[0-9A-Za-z]*$/;
 var position = getCursortPosition($taxNoDom[0]);
 var str = toDBC(e.target.value).toUpperCase();
 if (reg.test(str) && str.length <= 25) {
 oldValue = str;
 $(this).val(str);
 setCaretPosition($taxNoDom[0], position);
 } else {
 $(this).val(oldValue);
 setCaretPosition($taxNoDom[0], position - 1);
 }
});

In the above code I write is the bottom of the binding event, a closer look at 1 should be able to understand. However, the above code has an bug, which is actually the bug of getCursortPosition.

That is, in the Chinese input method, the input letter is selected when the input event is executed, and the cursor is in front of the letter, so that the position is deviated from the imagination, and the word 1 typed at the correct time is straight after the cursor.

At that time, I was very upset and felt hopeless in my life. . I thought of several methods:

1. By default, the left arrow of the keyboard is triggered and then the right arrow is triggered. In this way, whether the cursor is selected or not, it should be in the correct position.

2. Check whether there is selected text on the current page. If there is selected text, the returned cursor position is +1.

I checked the first method on the Internet for 1 time and immediately gave up. There are few related materials, and the limitations are quite large, and the differences between browsers are also large, so it doesn't seem to be a good method.

Then I found the method of the second method. window. getSelection and document. selection

IE9 The following support: document. selection

IE9, Firefox, Safari, Chrome, and Opera Support: window. getSelection ()

(Since our company project only supports ie9 and above, we did not try document. selection.)

I tried it myself once, if there is a selected text, window. getSelection (). type = = = "Range", if there is no selected window. getSelection (). type = = = "Caret".

So the final code is as follows:


function toDBC(str) {
 var result = "";
 var len = str.length;
 for (var i = 0; i < len; i++) {
 var cCode = str.charCodeAt(i);
 // Difference between full angle and half angle (except space): 65248 ( 10 Binary) 
 cCode = (cCode>=0xFF01 && cCode<=0xFF5E)?(cCode - 65248) : cCode;
 // Handling Spaces 
 cCode = (cCode==0x03000)?0x0020:cCode;
 result += String.fromCharCode(cCode);
 }
 return result;
}
function getCursortPosition(ctrl){
 var CaretPos = 0;
 if (document.selection) {
 ctrl.focus();
 var Sel = document.selection.createRange();
 Sel.moveStart('character', -ctrl.value.length);
 CaretPos = Sel.text.length;
 } else if (ctrl.selectionStart || ctrl.selectionStart == '0') {
 if (window.getSelection().type === "Range") {
 CaretPos = ctrl.selectionStart + 1;
 } else {
 CaretPos = ctrl.selectionStart;
 }
 }
 return (CaretPos);
}
function setCaretPosition(ctrl, pos){
 if (ctrl.setSelectionRange) {
 ctrl.focus();
 ctrl.setSelectionRange(pos, pos);
 } else if (ctrl.createTextRange) {
 var range = ctrl.createTextRange();
 range.collapse(true);
 range.moveEnd('character', pos);
 range.moveStart('character', pos);
 range.select();
 }
}
var oldValue = this.model.get("commercialTax").taxNo;
$taxNoDom.unbind().bind("input", function (e) {
 var reg = /^[0-9A-Za-z]*$/;
 var position = getCursortPosition($taxNoDom[0]);
 var str = toDBC(e.target.value).toUpperCase();
 if (reg.test(str) && str.length <= 25) {
 oldValue = str;
 $(this).val(str);
 setCaretPosition($taxNoDom[0], position);
 } else {
 $(this).val(oldValue);
 setCaretPosition($taxNoDom[0], position - 1);
 }
});

Related articles: