jb-national-input
Version:
national input web component
76 lines (73 loc) • 3.11 kB
text/typescript
import CSS from "./jb-national-input.scss";
import "jb-input";
// eslint-disable-next-line no-duplicate-imports
import { JBInputWebComponent,type JBInputValue} from "jb-input";
import { type ValidationItem } from "jb-validation";
import { faToEnDigits } from "jb-core";
export * from "./types";
//TODO: add barcode scanner or nfc reader
//TODO: add showPersianNumber
export class JBNationalInputWebComponent extends JBInputWebComponent{
constructor() {
super();
//to prevent initWebComponent method override
this.initMobileInputWebComponent();
}
initMobileInputWebComponent() {
const html = `<style>${CSS}</style>`;
const element = document.createElement("template");
element.innerHTML = html;
this.shadowRoot.appendChild(element.content.cloneNode(true));
this.validation.addValidationListGetter(this.#getNationalIdValidations.bind(this));
this.#addNationalInputEventListeners();
this.addStandardValueCallback(this.#standardNationalIdValue.bind(this));
}
/**
* @description this function will get user inputted or pasted text and convert it to standard one base on developer config
*/
#standardNationalIdValue(valueString: string): JBInputValue {
let displayValue = '';
let value = '';
// truncate value to 10 digits
const res = /(?<nationalId>[\u06F0-\u06F90-9]{1,10})/g.exec(valueString);
if (res && res.groups) {
displayValue = res.groups.nationalId;
} else {
displayValue = '';
}
//convert persian number to en number
value = faToEnDigits(displayValue);
return { value, displayValue };
}
#addNationalInputEventListeners(){
this.elements.input.addEventListener('beforeinput',this.#onNationalInputBeforeInput.bind(this));
}
#onNationalInputBeforeInput(e:InputEvent) {
const inputtedText = e.data;
const testRes = /[\u06F0-\u06F90-9]{1,10}/g.test(inputtedText);
if (!testRes && e.inputType != 'deleteContentBackward') {
e.preventDefault();
}
}
#getNationalIdValidations():ValidationItem<JBInputValue>[]{
function isValidIranianNationalCode(rawNationalCodeString:string){
if(rawNationalCodeString.length === 0) return true;
//check if input is valid iranian national code
const nationalCode = faToEnDigits(rawNationalCodeString);
if (!/^\d{10}$/.test(nationalCode)) return false;
const check = +nationalCode[9];
const checkNumberArr = nationalCode.split('').slice(0, 9);
const sum = checkNumberArr.reduce((acc, x, i) => acc + +x * (10 - i), 0) % 11;
return sum < 2 ? check === sum : check + sum === 11;
}
const nationalCodeValidation:ValidationItem<JBInputValue> = {
validator:({value}) => isValidIranianNationalCode(value),
message:'کد ملی وارد شده نامعتبر است'
};
return [nationalCodeValidation];
}
}
const myElementNotExists = !customElements.get("jb-national-input");
if (myElementNotExists) {
window.customElements.define("jb-national-input", JBNationalInputWebComponent);
}