bdb-vendors
Version:
Proveedores de funcionalidad transversales a todos los productos del laboratorio BDB.
190 lines (149 loc) • 7.58 kB
text/typescript
import { InputManager } from "./input.manager";
export class InputService {
private inputManager: InputManager;
constructor(private htmlInputElement: any, private options: any) {
this.inputManager = new InputManager(htmlInputElement);
}
addNumber(keyCode: number): void {
if (!this.rawValue) {
this.rawValue = this.applyMask(false, "0");
}
let keyChar = String.fromCharCode(keyCode);
let selectionStart = this.inputSelection.selectionStart;
let selectionEnd = this.inputSelection.selectionEnd;
this.rawValue = this.rawValue.substring(0, selectionStart) + keyChar + this.rawValue.substring(selectionEnd, this.rawValue.length);
this.updateFieldValue(selectionStart + 1);
}
applyMask(isNumber: boolean, rawValue: string): string {
let { allowNegative, decimal, precision, prefix, suffix, thousands, millions } = this.options;
rawValue = isNumber ? new Number(rawValue).toFixed(precision) : rawValue;
let onlyNumbers = rawValue.replace(/[^0-9]/g, "");
if (!onlyNumbers) {
return "";
}
let integerPart = onlyNumbers.slice(0, onlyNumbers.length - precision).replace(/^0*/g, "").replace(/\B(?=(\d{3})+(?!\d))/g, thousands);
if (integerPart == "") {
integerPart = "0";
}
let newRawValue = integerPart;
let decimalPart = onlyNumbers.slice(onlyNumbers.length - precision);
if (precision > 0) {
decimalPart = "0".repeat(precision - decimalPart.length) + decimalPart;
newRawValue += decimal + decimalPart;
}
let isZero = parseInt(integerPart) == 0 && (parseInt(decimalPart) == 0 || decimalPart == "");
let operator = (rawValue.indexOf("-") > -1 && allowNegative && !isZero) ? "-" : "";
let newValue = operator + prefix + newRawValue + suffix;
if (this.options.millions && this.options.millions !== '') {
newValue = newValue.replace( /(?=(?:.{8})*$)(?=\.)./g, millions);
}
return newValue;
}
clearMask(rawValue: string): number {
if (rawValue == null || rawValue == "") {
return null;
}
let value = rawValue.replace(this.options.prefix, "").replace(this.options.suffix, "");
if (this.options.thousands) {
value = value.replace(new RegExp("\\" + this.options.thousands, "g"), "");
}
if (this.options.millions) {
value = value.replace(new RegExp("\\" + this.options.millions, "g"), "");
}
if (this.options.decimal) {
value = value.replace(this.options.decimal, ".");
}
return parseFloat(value);
}
changeToNegative(): void {
if (this.options.allowNegative && this.rawValue != "" && this.rawValue.charAt(0) != "-" && this.value != 0) {
let selectionStart = this.inputSelection.selectionStart;
this.rawValue = "-" + this.rawValue;
this.updateFieldValue(selectionStart + 1);
}
}
changeToPositive(): void {
let selectionStart = this.inputSelection.selectionStart;
this.rawValue = this.rawValue.replace("-", "");
this.updateFieldValue(selectionStart - 1);
}
fixCursorPosition(forceToEndPosition?: boolean): void {
let currentCursorPosition = this.inputSelection.selectionStart;
//if the current cursor position is after the number end position, it is moved to the end of the number, ignoring the prefix or suffix. this behavior can be forced with forceToEndPosition flag
if (currentCursorPosition > this.getRawValueWithoutSuffixEndPosition() || forceToEndPosition) {
this.inputManager.setCursorAt(this.getRawValueWithoutSuffixEndPosition());
//if the current cursor position is before the number start position, it is moved to the start of the number, ignoring the prefix or suffix
} else if (currentCursorPosition < this.getRawValueWithoutPrefixStartPosition()) {
this.inputManager.setCursorAt(this.getRawValueWithoutPrefixStartPosition());
}
}
getRawValueWithoutSuffixEndPosition(): number {
return this.rawValue.length - this.options.suffix.length;
}
getRawValueWithoutPrefixStartPosition(): number {
return this.value != null && this.value < 0 ? this.options.prefix.length + 1 : this.options.prefix.length;
}
removeNumber(keyCode: number): void {
let { decimal, thousands } = this.options;
let selectionEnd = this.inputSelection.selectionEnd;
let selectionStart = this.inputSelection.selectionStart;
if (selectionStart > this.rawValue.length - this.options.suffix.length) {
selectionEnd = this.rawValue.length - this.options.suffix.length;
selectionStart = this.rawValue.length - this.options.suffix.length;
}
//there is no selection
if (selectionEnd == selectionStart) {
//delete key and the target digit is a number
if ((keyCode == 46 || keyCode == 63272) && /^\d+$/.test(this.rawValue.substring(selectionStart, selectionEnd + 1))) {
selectionEnd = selectionEnd + 1;
}
//delete key and the target digit is the decimal or thousands divider
if ((keyCode == 46 || keyCode == 63272) && (this.rawValue.substring(selectionStart, selectionEnd + 1) == decimal || this.rawValue.substring(selectionStart, selectionEnd + 1) == thousands)) {
selectionEnd = selectionEnd + 2;
selectionStart = selectionStart + 1;
}
//backspace key and the target digit is a number
if (keyCode == 8 && /^\d+$/.test(this.rawValue.substring(selectionStart - 1, selectionEnd))) {
selectionStart = selectionStart - 1;
}
//backspace key and the target digit is the decimal or thousands divider
if (keyCode == 8 && (this.rawValue.substring(selectionStart - 1, selectionEnd) == decimal || this.rawValue.substring(selectionStart - 1, selectionEnd) == thousands)) {
selectionStart = selectionStart - 2;
selectionEnd = selectionEnd - 1;
}
}
this.rawValue = this.rawValue.substring(0, selectionStart) + this.rawValue.substring(selectionEnd, this.rawValue.length);
this.updateFieldValue(selectionStart);
}
updateFieldValue(selectionStart?: number): void {
let newRawValue = this.applyMask(false, this.rawValue || "");
selectionStart = selectionStart == undefined ? this.rawValue.length : selectionStart;
this.inputManager.updateValueAndCursor(newRawValue, this.rawValue.length, selectionStart);
}
updateOptions(options: any): void {
let value: number = this.value;
this.options = options;
this.value = value;
}
get canInputMoreNumbers(): boolean {
return this.inputManager.canInputMoreNumbers;
}
get inputSelection(): any {
return this.inputManager.inputSelection;
}
get rawValue(): string {
return this.inputManager.rawValue;
}
set rawValue(value: string) {
this.inputManager.rawValue = value;
}
get storedRawValue(): string {
return this.inputManager.storedRawValue;
}
get value(): number {
return this.clearMask(this.rawValue);
}
set value(value: number) {
this.rawValue = this.applyMask(true, "" + value);
}
}