UNPKG

sdk-textbox

Version:

Simple to use (Angular) textbox for controlling input while typing.

807 lines (805 loc) 55.1 kB
import * as i0 from '@angular/core'; import { EventEmitter, Component, Input, Output, ViewChild, NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; import * as i1 from '@angular/common'; import { DatePipe, formatCurrency, formatNumber, CommonModule } from '@angular/common'; class CalendarComponent { constructor(datePipe) { this.datePipe = datePipe; this.date = ""; this.show = false; this.height = "180px"; this.width = "180px"; this.fontSize = "1.0em"; this.setDateEvent = new EventEmitter(); this.showCalendar = true; this.showMonths = false; this.showYears = false; this.calendarHtml = ""; this.year = 0; this.month = ""; this.monthNumber = 0; this.dayNumber = 0; this.months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; this.days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; this.newData = ""; } ngOnInit() { this.setCalendar(); setTimeout(() => { this.setStyle(); }, 1); } ngOnChanges() { this.newData = this.date; } setDate(date) { this.setDateEvent.emit(date); } getToday() { this.newData = new Date().toString(); this.setCalendar(); } getMonth() { this.showMonths = true; this.showCalendar = false; } setMonth(month) { this.showCalendar = true; this.showMonths = false; this.newData = new Date(this.year, month, this.dayNumber).toString(); this.setCalendar(); } getYear() { this.showYears = true; this.showCalendar = false; } setYear() { if (this.yearText?.nativeElement.value !== "" && this.yearText?.nativeElement.value.length === 4) { this.showCalendar = true; this.showYears = false; this.newData = new Date(this.yearText?.nativeElement.value, this.monthNumber - 1, this.dayNumber).toString(); this.setCalendar(); } } onKeyDown(event) { let text = event.target.value; if (event.key === "Enter") { this.setYear(); } else if (event.key === "Backspace" || event.key === "Tab" || event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "Meta" || event.key === "Control") { // DO NOTHING } else { if (!(event.metaKey && event.key === "v") && !(event.metaKey && event.key === "c")) { if (!event.key.match(/[0-9]/) || text.length >= 4) { event.preventDefault(); } } } } /************************************************************************** * Protected Methods **************************************************************************/ setCalendar() { let dt = (this.newData && this.newData !== "") ? new Date(this.newData) : new Date(); this.year = dt.getFullYear(); this.month = this.months[dt.getMonth()]; this.monthNumber = (dt.getMonth() + 1); this.dayNumber = dt.getDate(); let fistDay = new Date(this.year, dt.getMonth(), 1).getDay(); let totalDays = this.getTotalDays(dt.getFullYear(), dt.getMonth() + 1); let weeks = Math.floor(totalDays / 7); let isToday = false; let isSelected = false; if (fistDay > 0) weeks = weeks + 1; if ((totalDays + fistDay) > (weeks * 7)) weeks = weeks + 1; let plotDay = 1; this.calDays = []; for (let w = 0; w < weeks; w++) { for (let d = 0; d < 7; d++) { let currentDay = ((7 * w) + (d + 1)); if (currentDay < (fistDay + 1)) { this.calDays.push({ date: "", day: "" }); } else { if (plotDay <= totalDays) { if (this.datePipe.transform(new Date(this.year, this.monthNumber - 1, plotDay), 'yyyy-MM-dd') === this.datePipe.transform(new Date(), 'yyyy-MM-dd')) { isToday = true; } else { isToday = false; } if (this.datePipe.transform(new Date(this.year, this.monthNumber - 1, plotDay), 'yyyy-MM-dd') === this.datePipe.transform(this.date, 'yyyy-MM-dd')) { isSelected = true; } else { isSelected = false; } this.calDays.push({ date: this.datePipe.transform(new Date(this.year, this.monthNumber - 1, plotDay), 'yyyy-MM-dd'), day: plotDay.toString(), today: isToday, selected: isSelected }); plotDay++; } else { this.calDays.push({ date: "", day: "" }); } } } } } getTotalDays(year, month) { return new Date(year, month, 0).getDate(); } setStyle() { let element = this.calendar?.nativeElement; if (element) { element.style.setProperty("--height", this.height); element.style.setProperty("--width", this.width); element.style.setProperty("--font-size", this.fontSize); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: CalendarComponent, deps: [{ token: i1.DatePipe }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.10", type: CalendarComponent, selector: "calendar", inputs: { date: "date", show: "show", height: "height", width: "width", fontSize: "fontSize" }, outputs: { setDateEvent: "setDateEvent" }, viewQueries: [{ propertyName: "calendar", first: true, predicate: ["calendar"], descendants: true }, { propertyName: "yearText", first: true, predicate: ["yearText"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div #calendar *ngIf=\"show\" class=\"sdk-textbox-calendar\" [style.height]=\"((calDays.length * 30) + 30) + 'px'\">\n <div class=\"frame\" *ngIf=\"showCalendar\">\n <div class=\"header\">\n <div class=\"month\" (click)=\"getMonth()\">{{ month }}</div>\n <div class=\"today\" (click)=\"getToday()\">Today</div>\n <div class=\"year\" (click)=\"getYear()\">{{ year }}</div>\n </div>\n <div class=\"calendar\">\n <div class=\"grid\">\n <div class=\"label\">Sun</div>\n <div class=\"label\">Mon</div>\n <div class=\"label\">Tue</div>\n <div class=\"label\">Wed</div>\n <div class=\"label\">Thu</div>\n <div class=\"label\">Fri</div>\n <div class=\"label\">Sat</div>\n <div class=\"item\" [ngClass]=\"{ today: day.today, selected: day.selected }\" *ngFor=\"let day of calDays; let i = index\" (mousedown)=\"setDate(day.date)\">{{ day.day }}</div>\n </div>\n </div>\n </div>\n \n <table *ngIf=\"showMonths\" class=\"table\">\n <tbody>\n <tr>\n <td (click)=\"setMonth(0)\">Jan</td>\n <td (click)=\"setMonth(1)\">Feb</td>\n <td (click)=\"setMonth(2)\">Mar</td>\n <td (click)=\"setMonth(3)\">Apr</td>\n </tr>\n <tr>\n <td (click)=\"setMonth(4)\">May</td>\n <td (click)=\"setMonth(5)\">Jun</td>\n <td (click)=\"setMonth(6)\">Jul</td>\n <td (click)=\"setMonth(7)\">Aug</td>\n </tr>\n <tr>\n <td (click)=\"setMonth(8)\">Sep</td>\n <td (click)=\"setMonth(9)\">Oct</td>\n <td (click)=\"setMonth(10)\">Nov</td>\n <td (click)=\"setMonth(11)\">Dec</td>\n </tr>\n </tbody>\n </table>\n\n <table *ngIf=\"showYears\" class=\"table\">\n <tbody>\n <tr>\n <td>\n <div class=\"year-box\">\n <input #yearText class=\"year\" type=\"number\" (keydown)=\"onKeyDown($event)\" [value]=\"year\" />\n <button class=\"set\" (click)=\"setYear()\">SET</button>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n</div>\n", styles: [".sdk-textbox-calendar{position:absolute;left:0;right:0;z-index:999;min-height:var(--height, 180px);min-width:var(--width, 175px);max-height:var(--height, 180px);max-width:var(--width, 175px);border:1px solid rgb(200,200,200);background-color:#fff;overflow:hidden;font-size:var(--font-size, 1em)}.sdk-textbox-calendar .frame *{box-sizing:content-box}.sdk-textbox-calendar .frame .header{height:20px;padding:5px;font-weight:600;font-size:.8em;text-align:center}.sdk-textbox-calendar .frame .header .month{display:inline-flex;float:left}.sdk-textbox-calendar .frame .header .month:hover{color:#0066b2;cursor:pointer}.sdk-textbox-calendar .frame .header .today{display:inline-flex;color:#0066b2}.sdk-textbox-calendar .frame .header .today:hover{color:#fff;background-color:#0066b2;padding:2px;cursor:pointer}.sdk-textbox-calendar .frame .header .year{display:inline-flex;float:right}.sdk-textbox-calendar .frame .header .year:hover{color:#0066b2;cursor:pointer}.sdk-textbox-calendar .frame .calendar{height:calc(var(--height, 180px) - 32px);width:100%}.sdk-textbox-calendar .frame .calendar .grid{height:100%;width:100%;overflow:hidden;display:grid;grid-template-columns:repeat(7,1fr)}.sdk-textbox-calendar .frame .calendar .grid .label{display:flex;justify-content:center;align-items:center;background-color:#ebebeb;border:.5px solid rgb(200,200,200);font-size:.6em}.sdk-textbox-calendar .frame .calendar .grid .item{display:flex;justify-content:center;align-items:center;border:.5px solid rgb(200,200,200);font-size:.7em}.sdk-textbox-calendar .frame .calendar .grid .item.selected{background-color:#c5ffb1}.sdk-textbox-calendar .frame .calendar .grid .item.today{border-width:1px;border-color:#0066b2;color:#0066b2;font-weight:700}.sdk-textbox-calendar .frame .calendar .grid .item:hover{background-color:#dbf0ff}.sdk-textbox-calendar .table{height:100%;width:100%;max-height:100%;max-width:100%;font-size:1.2em;border-collapse:separate;border-spacing:0}.sdk-textbox-calendar .table thead tr th{padding:2px;font-weight:600;font-size:.7em;text-align:center;border:.5px solid rgb(200,200,200);background-color:#dcdcdc}.sdk-textbox-calendar .table thead tr td{padding-bottom:5px}.sdk-textbox-calendar .table thead tr td .header{font-size:.75em;margin:5px}.sdk-textbox-calendar .table thead tr td .header .month{float:left}.sdk-textbox-calendar .table thead tr td .header .month:hover{color:#0066b2;cursor:pointer}.sdk-textbox-calendar .table thead tr td .header .year{float:right}.sdk-textbox-calendar .table thead tr td .header .year:hover{color:#0066b2;cursor:pointer}.sdk-textbox-calendar .table tbody tr td{font-size:.8em;text-align:center;align-items:center;border:.5px solid rgb(225,225,225)}.sdk-textbox-calendar .table tbody tr td .year-box .year{font-size:1.2em;width:40%}.sdk-textbox-calendar .table tbody tr td .year-box .set{font-size:1.2em;margin-left:5px}.sdk-textbox-calendar .table tbody tr td:hover{background-color:#dbf0ff}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: CalendarComponent, decorators: [{ type: Component, args: [{ selector: 'calendar', template: "<div #calendar *ngIf=\"show\" class=\"sdk-textbox-calendar\" [style.height]=\"((calDays.length * 30) + 30) + 'px'\">\n <div class=\"frame\" *ngIf=\"showCalendar\">\n <div class=\"header\">\n <div class=\"month\" (click)=\"getMonth()\">{{ month }}</div>\n <div class=\"today\" (click)=\"getToday()\">Today</div>\n <div class=\"year\" (click)=\"getYear()\">{{ year }}</div>\n </div>\n <div class=\"calendar\">\n <div class=\"grid\">\n <div class=\"label\">Sun</div>\n <div class=\"label\">Mon</div>\n <div class=\"label\">Tue</div>\n <div class=\"label\">Wed</div>\n <div class=\"label\">Thu</div>\n <div class=\"label\">Fri</div>\n <div class=\"label\">Sat</div>\n <div class=\"item\" [ngClass]=\"{ today: day.today, selected: day.selected }\" *ngFor=\"let day of calDays; let i = index\" (mousedown)=\"setDate(day.date)\">{{ day.day }}</div>\n </div>\n </div>\n </div>\n \n <table *ngIf=\"showMonths\" class=\"table\">\n <tbody>\n <tr>\n <td (click)=\"setMonth(0)\">Jan</td>\n <td (click)=\"setMonth(1)\">Feb</td>\n <td (click)=\"setMonth(2)\">Mar</td>\n <td (click)=\"setMonth(3)\">Apr</td>\n </tr>\n <tr>\n <td (click)=\"setMonth(4)\">May</td>\n <td (click)=\"setMonth(5)\">Jun</td>\n <td (click)=\"setMonth(6)\">Jul</td>\n <td (click)=\"setMonth(7)\">Aug</td>\n </tr>\n <tr>\n <td (click)=\"setMonth(8)\">Sep</td>\n <td (click)=\"setMonth(9)\">Oct</td>\n <td (click)=\"setMonth(10)\">Nov</td>\n <td (click)=\"setMonth(11)\">Dec</td>\n </tr>\n </tbody>\n </table>\n\n <table *ngIf=\"showYears\" class=\"table\">\n <tbody>\n <tr>\n <td>\n <div class=\"year-box\">\n <input #yearText class=\"year\" type=\"number\" (keydown)=\"onKeyDown($event)\" [value]=\"year\" />\n <button class=\"set\" (click)=\"setYear()\">SET</button>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n</div>\n", styles: [".sdk-textbox-calendar{position:absolute;left:0;right:0;z-index:999;min-height:var(--height, 180px);min-width:var(--width, 175px);max-height:var(--height, 180px);max-width:var(--width, 175px);border:1px solid rgb(200,200,200);background-color:#fff;overflow:hidden;font-size:var(--font-size, 1em)}.sdk-textbox-calendar .frame *{box-sizing:content-box}.sdk-textbox-calendar .frame .header{height:20px;padding:5px;font-weight:600;font-size:.8em;text-align:center}.sdk-textbox-calendar .frame .header .month{display:inline-flex;float:left}.sdk-textbox-calendar .frame .header .month:hover{color:#0066b2;cursor:pointer}.sdk-textbox-calendar .frame .header .today{display:inline-flex;color:#0066b2}.sdk-textbox-calendar .frame .header .today:hover{color:#fff;background-color:#0066b2;padding:2px;cursor:pointer}.sdk-textbox-calendar .frame .header .year{display:inline-flex;float:right}.sdk-textbox-calendar .frame .header .year:hover{color:#0066b2;cursor:pointer}.sdk-textbox-calendar .frame .calendar{height:calc(var(--height, 180px) - 32px);width:100%}.sdk-textbox-calendar .frame .calendar .grid{height:100%;width:100%;overflow:hidden;display:grid;grid-template-columns:repeat(7,1fr)}.sdk-textbox-calendar .frame .calendar .grid .label{display:flex;justify-content:center;align-items:center;background-color:#ebebeb;border:.5px solid rgb(200,200,200);font-size:.6em}.sdk-textbox-calendar .frame .calendar .grid .item{display:flex;justify-content:center;align-items:center;border:.5px solid rgb(200,200,200);font-size:.7em}.sdk-textbox-calendar .frame .calendar .grid .item.selected{background-color:#c5ffb1}.sdk-textbox-calendar .frame .calendar .grid .item.today{border-width:1px;border-color:#0066b2;color:#0066b2;font-weight:700}.sdk-textbox-calendar .frame .calendar .grid .item:hover{background-color:#dbf0ff}.sdk-textbox-calendar .table{height:100%;width:100%;max-height:100%;max-width:100%;font-size:1.2em;border-collapse:separate;border-spacing:0}.sdk-textbox-calendar .table thead tr th{padding:2px;font-weight:600;font-size:.7em;text-align:center;border:.5px solid rgb(200,200,200);background-color:#dcdcdc}.sdk-textbox-calendar .table thead tr td{padding-bottom:5px}.sdk-textbox-calendar .table thead tr td .header{font-size:.75em;margin:5px}.sdk-textbox-calendar .table thead tr td .header .month{float:left}.sdk-textbox-calendar .table thead tr td .header .month:hover{color:#0066b2;cursor:pointer}.sdk-textbox-calendar .table thead tr td .header .year{float:right}.sdk-textbox-calendar .table thead tr td .header .year:hover{color:#0066b2;cursor:pointer}.sdk-textbox-calendar .table tbody tr td{font-size:.8em;text-align:center;align-items:center;border:.5px solid rgb(225,225,225)}.sdk-textbox-calendar .table tbody tr td .year-box .year{font-size:1.2em;width:40%}.sdk-textbox-calendar .table tbody tr td .year-box .set{font-size:1.2em;margin-left:5px}.sdk-textbox-calendar .table tbody tr td:hover{background-color:#dbf0ff}\n"] }] }], ctorParameters: () => [{ type: i1.DatePipe }], propDecorators: { date: [{ type: Input }], show: [{ type: Input }], height: [{ type: Input }], width: [{ type: Input }], fontSize: [{ type: Input }], setDateEvent: [{ type: Output }], calendar: [{ type: ViewChild, args: ["calendar"] }], yearText: [{ type: ViewChild, args: ["yearText"] }] } }); class SDKTextboxComponent { constructor() { /************************************************************************** * Input/Output Parameters **************************************************************************/ this.validCharacters = ""; this.value = ""; this.hint = ""; this.pattern = ""; this.locale = "en-US"; this.multiLine = false; this.showCalendarIcon = true; this.calHeight = "180px"; this.calWidth = "180px"; this.calFontSize = "1.0em"; this.blurCallBackEvent = new EventEmitter(); this.changeCallBackEvent = new EventEmitter(); this.enterCallBackEvent = new EventEmitter(); this.calendarDate = ""; this.showCalendar = false; this.lockCalendar = false; this.pArray = []; this.fArray = []; } //****************************************************************************** // Component Life-cycle Methods //****************************************************************************** ngOnInit() { if (this.validCharacters) { this.validCharacters = this.validCharacters.toString().toLocaleLowerCase(); switch (this.validCharacters) { case "calendar": if (!this.pattern || this.pattern === "") this.pattern = "YYYY-MM-DD"; let divider = this.pattern.replace(/[ymdYMD]/g, "").substring(0, 1); let dividerArray = this.pattern.split(divider); this.hint = this.pattern; this.createPattern(dividerArray[0].replace(/[ymdYMD]/g, "#") + divider + dividerArray[1].replace(/[ymdYMD]/g, "#") + divider + dividerArray[2].replace(/[ymdYMD]/g, "#")); if (this.value && this.value !== "") { let datePipe = new DatePipe(this.locale); let pattern = this.pattern.replace(/[yY]/g, "y").replace(/[mM]/g, "M").replace(/[dD]/g, "d"); let value = this.value.split("T")[0]; this.value = datePipe.transform(value, pattern) || ""; } setTimeout(() => { if (!this.width) { this.text.nativeElement.style.width = `${this.pattern.length * 10}px`; } if (this.component.nativeElement.parentNode.hasAttribute("nocomponent")) { this.showCalendarIcon = false; } }, 1); break; case "email": this.hint = "name@company.com"; break; case "custom": if (this.pattern && this.pattern.indexOf("#") > -1 && !this.pattern.startsWith("[") && !this.pattern.endsWith("]")) { this.hint = this.pattern; this.createPattern(); } break; } } } ngAfterViewInit() { setTimeout(() => { if (this.validCharacters === "calendar" && this.component && this.text) { this.component.nativeElement.style.width = (this.text.nativeElement.clientWidth + 25) + "px"; } }, 100); } //************************************************************************* // Protected Methods //************************************************************************* onKeyDown(event) { this.showCalendar = false; if (event.key === "Enter" && !event.shiftKey) { this.text.nativeElement.blur(); if (this.enterCallBackEvent.observed) { this.enterCallBackEvent.emit(event.target.value); } } else if (event.key === "Backspace" || event.key === "Tab" || event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "Meta" || event.key === "Control") { // DO NOTHING } else { let text = this.removeSelection(event); if (!(event.metaKey && event.key === "v") && !(event.metaKey && event.key === "c")) { switch (this.validCharacters) { case "alpha": if (!event.key.match(/[a-zA-Z]/)) { event.preventDefault(); } break; case "numeric": if (!event.key.match(/[0-9]/)) { event.preventDefault(); } break; case "alphanumeric": if (!event.key.match(/[a-zA-Z0-9]/)) { event.preventDefault(); } break; case "decimal": case "currency": if (!event.key.match(/[-0-9.]/) || (event.key === "." && text.match(/[.]/g)) || (event.key === "-" && (event.target.selectionStart !== 0 || text.match(/[-]/g)))) { event.preventDefault(); } let periodArray = text.toString().split("."); if (this.validCharacters === "currency" && periodArray.length > 1 && periodArray[1].length >= 2) { event.preventDefault(); } break; case "calendar": if (!event.key.match(/[0-9]/) || text.replace(/[^0-9]/g, "").length === this.pattern.replace(/[^ymdYMD]/g, "").length) { event.preventDefault(); } break; case "email": if (!event.key.match(/[a-zA-Z0-9._%+-@]/) || (event.key === "@" && text.match(/[@]/g)) || (!text.match(/[@]/g) && text.length >= 64) || (text.match(/[@]/g) && text.length >= 254)) { event.preventDefault(); } let atArray = text.toString().split("@"); if (atArray.length > 1 && event.target.selectionStart > atArray[0].length && !event.key.match(/[a-zA-Z0-9-.]/)) { event.preventDefault(); } break; case "latitude": let latrx = /^([\-]?|[\-]?[1-9]|[\-]?[1-8][0-9]|[\-]?90)(?:[.]\d{0,15})?$/; let lattext = text + event.key; if (!lattext.match(new RegExp(latrx))) { event.preventDefault(); } break; case "longitude": let longrx = /^([\-]?|[\-]?[1-9]|[\-]?[1-9]\d|[\-]?[1][0-7]\d|[\-]?180)(?:[.]\d{0,15})?$/; let longtext = text + event.key; if (!longtext.match(new RegExp(longrx))) { event.preventDefault(); } break; case "custom": if (this.pattern && this.pattern.indexOf("#") > -1 && !this.pattern.startsWith("[") && !this.pattern.endsWith("]") && (!event.key.match(/[0-9]/) || text.length === this.pattern.length)) { event.preventDefault(); } if (this.pattern && this.pattern.startsWith("[") && this.pattern.endsWith("]")) { if (!event.key.match(new RegExp(this.pattern, "g"))) { event.preventDefault(); } } if (this.pattern && this.pattern.startsWith("^") && this.pattern.endsWith("$")) { let newText = text + event.key; if (!newText.match(new RegExp(this.pattern))) { event.preventDefault(); } } break; default: break; } } } } onBlur(event) { let text = event.target.value; if (this.validCharacters && text && text !== "") { text = this.cleanText(text); text = this.formatText(text); event.target.value = text; } if (this.validCharacters) { this.validCharacters = this.validCharacters.toString().toLocaleLowerCase(); switch (this.validCharacters) { case "calendar": if (!this.lockCalendar) { this.showCalendar = false; } break; } } if (this.blurCallBackEvent.observed) { this.blurCallBackEvent.emit(this.text.nativeElement.value); } } onInput(event) { if (this.validCharacters === "decimal" || this.validCharacters === "currency") { this.setNumericText(event); } if (this.validCharacters === "calendar") { this.setCalendarText(event); } if (this.validCharacters === "email") { this.setEmailText(event); } if (this.validCharacters === "latitude") { this.setLatitude(event); } if (this.validCharacters === "longitude") { this.setLongitude(event); } if (this.validCharacters === "custom" && this.pArray.length > 0) { this.setCustomText(event); } if (this.changeCallBackEvent.observed) { this.changeCallBackEvent.emit(this.text.nativeElement.value); } } onCut(event) { let textLeft = event.target.value.toString().substring(0, event.target.selectionStart); let textRight = event.target.value.toString().substring(event.target.selectionEnd); let text = textLeft + textRight; let clipboardData = event.clipboardData || event.originalEvent.clipboardData; clipboardData.items.add(text, 'text/plain'); } onPaste(event) { let clipboardData = event.clipboardData || event.originalEvent.clipboardData; let text = clipboardData.getData('text'); let textLeft = event.target.value.toString().substring(0, event.target.selectionStart); let textRight = event.target.value.toString().substring(event.target.selectionEnd); text = textLeft + text + textRight; event.preventDefault(); if ((this.validCharacters === "custom" && this.pattern.startsWith("^") && this.pattern.endsWith("$")) || this.validCharacters === "latitude" || this.validCharacters === "longitude") { event.target.value = ""; } else { text = this.cleanText(text); event.target.value = text; } if (this.changeCallBackEvent.observed) { this.changeCallBackEvent.emit(this.text.nativeElement.value); } } showComponent(event) { if (this.validCharacters) { this.validCharacters = this.validCharacters.toString().toLocaleLowerCase(); switch (this.validCharacters) { case "calendar": if (!this.component.nativeElement.parentNode.hasAttribute("nocomponent")) { this.calendarDate = this.text.nativeElement.value; this.showCalendar = true; } break; } } } setDate(date) { this.text.nativeElement.value = this.formatText(date); if (this.changeCallBackEvent.observed) { this.changeCallBackEvent.emit(this.text.nativeElement.value); } this.showCalendar = false; } //************************************************************************* // Private Methods //************************************************************************* setNumericText(event) { let text = event.target.value; let newText = ""; let beforeLength = text.length; let afterLength = 0; let cursorStart = event.target.selectionStart; let cursor = 0; event.preventDefault(); newText = text.toString().replace(/[^-0-9.]/g, ""); newText = newText.toString().replace(/\B(?=([0-9]{3})+(?![0-9]))/g, ","); let periodArray = newText.toString().split("."); if (periodArray.length > 1) { newText = periodArray[0] + "." + periodArray[1].replace(/[,]/g, ""); } afterLength = newText.length; cursor = cursorStart + (afterLength - beforeLength); event.target.value = newText; event.target.selectionStart = cursor; event.target.selectionEnd = cursor; } setCalendarText(event) { let text = event.target.value; let newText = ""; let beforeLength = text.length; let afterLength = 0; let cursorStart = event.target.selectionStart; let cursor = 0; event.preventDefault(); newText = text.toString().replace(/[^0-9]/g, ""); for (let x = 0; x < this.pArray.length; x++) { newText = newText.replace(new RegExp(this.pArray[x]), this.fArray[x]); } afterLength = newText.length; cursor = cursorStart + (afterLength - beforeLength); event.target.value = newText; event.target.selectionStart = cursor; event.target.selectionEnd = cursor; } setEmailText(event) { let text = event.target.value; let newText = ""; let beforeLength = text.length; let afterLength = 0; let cursorStart = event.target.selectionStart; let cursor = 0; event.preventDefault(); newText = text.toString().replace(/[^a-zA-Z0-9._%+-@]/g, ""); let atArray = newText.toString().split("@"); if (atArray.length > 1) { newText = atArray[0].substring(0, 63) + "@" + atArray.slice(1).toString().replace(/[^a-zA-Z0-9-.]/g, ""); } else { newText = newText.substring(0, 63); } newText = newText.substring(0, 253); afterLength = newText.length; cursor = cursorStart + (afterLength - beforeLength); event.target.value = newText; event.target.selectionStart = cursor; event.target.selectionEnd = cursor; } setLatitude(event) { let text = event.target.value; let newText = text; event.preventDefault(); if (Number(text) < -90) { newText = -90; } if (Number(text) > 90) { newText = 90; } event.target.value = newText; } setLongitude(event) { let text = event.target.value; let newText = text; event.preventDefault(); if (Number(text) < -180) { newText = -180; } if (Number(text) > 180) { newText = 180; } event.target.value = newText; } setCustomText(event) { let text = event.target.value; let newText = ""; let beforeLength = text.length; let afterLength = 0; let cursorStart = event.target.selectionStart; let cursor = 0; event.preventDefault(); if (text === "+1 ") text = ""; newText = text.toString().replace(/[^0-9]/g, ""); for (let x = 0; x < this.pArray.length; x++) { newText = newText.replace(new RegExp(this.pArray[x]), this.fArray[x]); } afterLength = newText.length; cursor = cursorStart + (afterLength - beforeLength); event.target.value = newText; event.target.selectionStart = cursor; event.target.selectionEnd = cursor; } removeSelection(event) { let textLeft = event.target.value.toString().substring(0, event.target.selectionStart); let textRight = event.target.value.toString().substring(event.target.selectionEnd + 1); return textLeft + textRight; } cleanText(text) { if (this.validCharacters?.toString().startsWith("[")) { let format = "[^" + this.validCharacters?.toString().split("[")[1]; text = text.toString().replace(new RegExp(format, "g"), ""); } else { switch (this.validCharacters) { case "alpha": text = text.toString().replace(/[^a-zA-Z]/g, ""); break; case "numeric": text = text.toString().replace(/[^0-9]/g, ""); break; case "alphanumeric": text = text.toString().replace(/[^a-zA-Z0-9]/g, ""); break; case "decimal": case "currency": text = text.toString().replace(/[^0-9.-]|(?:\/[.].*)[.]|(?!^)-/g, ""); break; case "calendar": if (this.pattern) { let re = "[^0-9" + this.encodeText(Array.from(new Set(this.pattern.replace(/[a-zA-Z0-9]/g, "").split(""))).join("")) + "]"; text = text.toString().replace(new RegExp(re, "g"), ""); } break; case "email": text = text.toString().replace(/[^a-zA-Z0-9._%+-@]/g, ""); let atArray = text.toString().split("@"); if (atArray.length > 1) { let periodArray = atArray[1].toString().split("."); if (periodArray.length > 1) { let type = periodArray.slice(periodArray.length - 1); type = type.toString().replace(/[^a-zA-Z]/g, ""); periodArray.pop(); text = atArray[0] + "@" + periodArray.join(".") + "." + type; } } break; case "latitude": case "longitude": let re = "(" + this.pattern + ")"; text = text.toString().replace(new RegExp(re, "g"), "$1"); break; case "custom": if (this.pattern) { if (this.pattern.indexOf("#") > -1 && !this.pattern.startsWith("[") && !this.pattern.endsWith("]")) { let re = "[^0-9" + this.encodeText(Array.from(new Set(this.pattern.split(""))).join("")) + "]"; text = text.toString().replace(new RegExp(re.replace("#", ""), "g"), ""); text = text.substring(0, this.pattern.length); } if (this.pattern.startsWith("[") && this.pattern.endsWith("]")) { let re = this.pattern.replace("[", "[^"); if (this.pattern.startsWith("[^")) { re = this.pattern.replace("[^", "["); } text = text.toString().replace(new RegExp(re, "g"), ""); } if (this.pattern.startsWith("^") && this.pattern.endsWith("$")) { let re = "(" + this.pattern + ")"; text = text.toString().replace(new RegExp(re, "g"), "$1"); } } break; default: break; } } return text; } formatText(text) { if (this.validCharacters === "currency") { text = formatCurrency(parseFloat(text), this.locale, this.pattern ?? '$'); } else if (this.validCharacters === "custom" || this.validCharacters === "latitude" || this.validCharacters === "longitude") { // DO NOTHING } else if (this.validCharacters === "calendar") { const datepipe = new DatePipe(this.locale); let pattern = this.pattern.replace(/[yY]/g, "y").replace(/[mM]/g, "M").replace(/[dD]/g, "d"); try { text = datepipe.transform(text, pattern, undefined, this.locale); this.text.nativeElement.style.backgroundColor = ""; } catch { setTimeout(() => { this.text.nativeElement.style.backgroundColor = "rgb(255, 210, 217)"; this.text.nativeElement.focus(); }, 1); } } else { if (this.pattern) { text = formatNumber(parseFloat(text), this.locale, this.pattern); } } return text; } createPattern(pattern = "") { if (pattern === "") { pattern = this.pattern?.trim() ?? ""; } let ws = pattern.replace(/([\#])\1+/g, "#"); let wsPattern = ""; let breakArray = []; let cnt = 1; let wsBreak = ""; for (let x = 0; x < ws.length; x++) { if (ws[x] === "#") { wsPattern += `$${cnt}`; cnt++; } else { wsPattern += ws[x]; } wsBreak = ws[x]; if (ws[x] === " " || ws[x] === "-" || ws[x] === "." || ws[x] === "/" || ws[x] === "_") { breakArray.push(wsBreak); wsBreak = ""; } } let charArray = []; let chars = ""; for (let x = 0; x < pattern.length; x++) { if (pattern[x] === "#") { chars += "#"; } else { if (chars !== "") { charArray.push(chars); } chars = ""; } } // Add any remaining chars. if (chars !== "") { charArray.push(chars); } let patternArray = []; for (let x = 0; x < charArray.length; x++) { patternArray.push(`[0-9]{1,${charArray[x].length}}`); } this.pArray = []; this.fArray = []; let wsFilter = ws; let wspFilter = wsPattern; let f = ""; let p = ""; for (let l = 0; l < patternArray.length; l++) { f = wsFilter.split(breakArray[l])[0]; wsFilter = wsFilter.substring(f.length + 1); p = wspFilter.split(breakArray[l])[0]; wspFilter = wspFilter.substring(p.length + 1); for (let x = l; x < patternArray.length; x++) { if (this.pArray[x] === undefined) this.pArray.push(""); if (this.fArray[x] === undefined) this.fArray.push(""); let m = (l > 0) ? "*" : ""; // build left-side (pArray) if (f.startsWith("#") && f.endsWith("#")) { // number only if (x === l) { this.pArray[x] += m + "(" + patternArray[l] + ")"; } else { this.pArray[x] += this.encodeText(f).replace("#", m + "(" + patternArray[l].replace("1,", "") + ")") + this.encodeText(breakArray[l]); } } if (!f.startsWith("#") && !f.endsWith("#")) { // wrapper if (x === l) { this.pArray[x] += m + "(" + patternArray[l] + ")"; } else if (x === (l + 1)) { this.pArray[x] += m + "(" + patternArray[l].replace("1,", "") + ")" + this.encodeText(breakArray[l]); } else { this.pArray[x] += this.encodeText(f).replace("#", m + "(" + patternArray[l].replace("1,", "") + ")") + this.encodeText(breakArray[l]); } } if (!f.startsWith("#") && f.endsWith("#")) { // starts with non-digit if (x === l) { this.pArray[x] += m + "(" + patternArray[l] + ")"; } else { this.pArray[x] += m + "(" + patternArray[l].replace("1,", "") + ")" + this.encodeText(breakArray[l]); } } if (f.startsWith("#") && !f.endsWith("#")) { // ends with non-digit if (x === l) { this.pArray[x] += m + "(" + patternArray[l] + ")"; } else { this.pArray[x] += m + "(" + patternArray[l].replace("1,", "") + ")" + this.encodeText(breakArray[l]); } } // build right-side (fArray) if (f.startsWith("#") && f.endsWith("#")) { // number only if (l === x) { this.fArray[x] += p; } else { this.fArray[x] += p + (breakArray[l] ?? ""); } } if (!f.startsWith("#") && !f.endsWith("#")) { // wrapper if (l === x) { this.fArray[x] += p.replace(/[^$0-9]/g, ""); } else { this.fArray[x] += p + (breakArray[l] ?? ""); } } if (!f.startsWith("#") && f.endsWith("#")) { // starts with non-digit if (l === x) { this.fArray[x] += p; } else { this.fArray[x] += p + (breakArray[l] ?? ""); } } if (f.startsWith("#") && !f.endsWith("#")) { // ends with non-digit if (l === x) { this.fArray[x] += p.replace(/[^$0-9]/g, ""); } else { this.fArray[x] += p + (breakArray[l] ?? ""); } } } } } encodeText(text) { return text.replace(/[|{}\\()[\]^$+*?.+]/g, '\\$&').replace(/\s/, "\\s"); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: SDKTextboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.10", type: SDKTextboxComponent, selector: "sdk-textbox", inputs: { validCharacters: "validCharacters", value: "value", hint: "hint", pattern: "pattern", locale: "locale", multiLine: "multiLine", border: "border", padding: "padding", margin: "margin", height: "height", width: "width", style: "style", class: "class", showCalendarIcon: "showCalendarIcon", calHeight: "calHeight", calWidth: "calWidth", calFontSize: "calFontSize" }, outputs: { blurCallBackEvent: "blurCallBackEvent", changeCallBackEvent: "changeCallBackEvent", enterCallBackEvent: "enterCallBackEvent" }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true }, { propertyName: "text", first: true, predicate: ["text"], descendants: true }, { propertyName: "calendar", first: true, predicate: ["calendar"], descendants: true }], ngImport: i0, template: "<div #component class=\"sdk_textbox\" style=\"position: relative; padding: 0;\">\n <div *ngIf=\"!multiLine\" [ngStyle]=\"{ 'margin': margin ?? '0', 'border': 'unset', 'height': height ?? 'unset', 'width': width ?? 'unset' }\">\n <input #text type=\"text\" [ngStyle]=\"{ 'padding': padding ?? '5px', 'margin': '0', 'border': border ?? '1px solid rgb(200, 200, 200)', 'height': '100%', 'width': '100%' }\" [class]=\"class\" [style]=\"style\" [placeholder]=\"hint\" (keydown)=\"onKeyDown($event)\" (focus)=\"text.select()\" (blur)=\"onBlur($event)\" (input)=\"onInput($event)\" (cut)=\"onCut($event)\" (paste)=\"onPaste($event)\" (click)=\"!showCalendarIcon ? showComponent($event) : false\" [value]=\"value\" />\n <i *ngIf=\"validCharacters === 'calendar' && showCalendarIcon\" class=\"sdk-icon\" (click)=\"showComponent($event); text.focus(); lockCalendar = true\" (mouseout)=\"lockCalendar = false; showCalendar ? text.focus() : false;\">calendar_month</i>\n <calendar *ngIf=\"showCalendar && validCharacters?.toLocaleLowerCase() === 'calendar'\" #calendar [date]=\"calendarDate\" [show]=\"showCalendar\" [height]=\"calHeight\" [width]=\"calWidth\" [fontSize]=\"calFontSize\" (setDateEvent)=\"setDate($event)\" (mouseover)=\"lockCalendar = true\" (mouseout)=\"lockCalendar = false; text.focus()\"></calendar>\n </div>\n <div *ngIf=\"multiLine\" [ngStyle]=\"{ 'margin': margin ?? '0', 'border': 'unset', 'height': height ?? 'unset', 'width': width ?? 'unset' }\">\n <textarea #text [ngStyle]=\"{ 'padding': padding ?? '5px', 'margin': '0', 'border': border ?? '1px solid rgb(200, 200, 200)', 'height':'100%', 'width': '100%' }\" [class]=\"class\" [style]=\"style\" [placeholder]=\"hint\" (keydown)=\"onKeyDown($event)\" (focus)=\"text.select()\" (blur)=\"onBlur($event)\" (input)=\"onInput($event)\" (cut)=\"onCut($event)\" (paste)=\"onPaste($event)\" (click)=\"!showCalendarIcon ? showComponent($event) : false\" [value]=\"value\"></textarea>\n </div>\n</div>\n", styles: [".sdk_textbox input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-o-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.sdk_textbox textarea{resize:none;box-sizing:border-box;outline:none}.sdk-icon{position:absolute;top:50%;transform:translateY(-50%);color:#b9b9b9;font-size:1.4em;cursor:pointer}::placeholder{color:#dcdcdc;opacity:1}:-ms-input-placeholder{color:#dcdcdc}::-ms-input-placeholder{color:#dcdcdc}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: CalendarComponent, selector: "calendar", inputs: ["date", "show", "height", "width", "fontSize"], outputs: ["setDateEvent"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: SDKTextboxComponent, decorators: [{ type: Component, args: [{ selector: 'sdk-textbox', template: "<div #component class=\"sdk_textbox\" style=\"position: relative; padding: 0;\">\n <div *ngIf=\"!multiLine\" [ngStyle]=\"{ 'margin': margin ?? '0', 'border': 'unset', 'height': height ?? 'unset', 'width': width ?? 'unset' }\">\n <input #text type=\"text\" [ngStyle]=\"{ 'padding': padding ?? '5px', 'margin': '0', 'border': border ?? '1px solid rgb(200, 200, 200)', 'height': '100%', 'width': '100%' }\" [class]=\"class\" [style]=\"style\" [placeholder]=\"hint\"