sdk-textbox
Version:
Simple to use (Angular) textbox for controlling input while typing.
807 lines (805 loc) • 55.1 kB
JavaScript
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\"