import { defineWebComponent, faToEnDigits } from "jb-core"; import CSS from "./jb-national-input.css"; import VariablesCSS from "./variables.css"; import "jb-input"; // eslint-disable-next-line no-duplicate-imports import { JBInputWebComponent,type JBInputValue} from "jb-input"; import type { ValidationItem } from "jb-validation"; import { dictionary } from "./i18n"; import { i18n } from "jb-core/i18n"; 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 = ``; 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 = /(?[\u06F0-\u06F90-9]{1,10})/g.exec(valueString); if (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[]{ 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 = { validator:({value}) => isValidIranianNationalCode(value), message:dictionary.get(i18n,"invalidValue"), stateType:"badInput" }; return [nationalCodeValidation]; } } defineWebComponent("jb-national-input", JBNationalInputWebComponent); declare global { interface HTMLElementTagNameMap { "jb-national-input": JBNationalInputWebComponent; } }