UNPKG

@syncfusion/ej2-inputs

Version:

A package of Essential JS 2 input components such as Textbox, Color-picker, Masked-textbox, Numeric-textbox, Slider, Upload, and Form-validator that is used to get input from the users.

709 lines (708 loc) 28.4 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { NotifyPropertyChanges, Component, Property, getUniqueID, isNullOrUndefined, addClass, attributes, removeClass, remove, Event, EventHandler } from '@syncfusion/ej2-base'; var INPUTFIELD = 'e-otp-input-field'; var RTL = 'e-rtl'; /** * Specifies the type of input for the Otp (One-Time Password) input component. */ export var OtpInputType; (function (OtpInputType) { /** * Specifies the type of input to be number for the Otp input. */ OtpInputType["Number"] = "number"; /** * Specifies the type of input to be text for the Otp input. */ OtpInputType["Text"] = "text"; /** * Specifies the type of input to be password for the Otp input. */ OtpInputType["Password"] = "password"; })(OtpInputType || (OtpInputType = {})); /** * Specifies the style variant for the Otp (One-Time Password) input component. */ export var OtpInputStyle; (function (OtpInputStyle) { /** * Specifies the style of the Otp input to be outlined. */ OtpInputStyle["Outlined"] = "outlined"; /** * Specifies the style of the Otp input to be underlined. */ OtpInputStyle["Underlined"] = "underlined"; /** * Specifies the style of the Otp input to be filled. */ OtpInputStyle["Filled"] = "filled"; })(OtpInputStyle || (OtpInputStyle = {})); /** * Enum for the case transformation options for OTP input text. * * @readonly * @enum {string} */ export var TextTransform; (function (TextTransform) { /** * No case transformation. The input text remains unchanged. */ TextTransform["None"] = "none"; /** * Convert the input text to uppercase. */ TextTransform["Uppercase"] = "uppercase"; /** * Convert the input text to lowercase. */ TextTransform["Lowercase"] = "lowercase"; })(TextTransform || (TextTransform = {})); /** * Represents the Otp component that allows the user to enter the otp values. * ```html * <div id='OTPInput'></div> * ``` * ```typescript * <script> * var OtpinputObj = new OtpInput(); * OtpinputObj.appendTo('#OTPInput'); * </script> * ``` */ var OtpInput = /** @class */ (function (_super) { __extends(OtpInput, _super); function OtpInput(options, element) { var _this = _super.call(this, options, element) || this; /* Private variables */ _this.inputs = []; _this.previousValue = ''; _this.separatorElements = []; _this.shouldFireFocus = true; _this.shouldFireBlur = true; _this.isFocusInCalled = false; _this.isFocusOutCalled = false; _this.handleWheelEvent = function (e) { e.preventDefault(); }; return _this; } OtpInput.prototype.preRender = function () { if (!this.element.id) { this.element.id = getUniqueID('e-' + this.getModuleName()); } }; OtpInput.prototype.render = function () { this.initialize(); }; OtpInput.prototype.initialize = function () { attributes(this.element, { 'role': 'group' }); this.renderInputs(); this.renderSeparator(1, this.inputs.length); this.addPlaceHolder(); this.updateCssClass(this.cssClass); this.updateVariantClass(); this.updateAriaLabel(this.ariaLabels); this.setElementAttributes(this.htmlAttributes, this.element); if (this.enableRtl) { this.element.classList.add(RTL); } this.previousValue = this.value.toString(); if (this.autoFocus) { this.focusIn(); } }; OtpInput.prototype.renderInputs = function () { this.hiddenInputEle = this.createElement('input', { id: 'otpInput_hidden', attrs: { name: this.element.id, type: 'hidden', value: this.type === 'number' ? this.value.toString().replace(/\D/g, '') : this.value.toString(), autoComplete: 'off' } }); this.element.appendChild(this.hiddenInputEle); for (var i = 0; i < this.length; i++) { this.createOtpInput(i); } }; OtpInput.prototype.createOtpInput = function (index) { var valueContainer = this.getDefaultValue(); var inputValue = ''; if (valueContainer) { var valueAtIndex = valueContainer[parseInt(index.toString(), 10)]; if (this.type === 'number') { if (!isNaN(Number(valueAtIndex))) { inputValue = valueAtIndex; } } else { inputValue = valueAtIndex || ''; } } var inputEle = this.createElement('input', { id: this.element.id + "-" + (index + 1), className: INPUTFIELD + ' ' + 'e-input', attrs: { maxlength: '1', type: this.type, inputmode: this.htmlAttributes['inputmode'] || (this.type === 'number' ? 'numeric' : 'text') } }); if (this.disabled) { inputEle.setAttribute('disabled', 'disabled'); } this.element.appendChild(inputEle); this.inputs.push(inputEle); if (inputValue) { inputEle.value = inputValue; } this.wireEvents(inputEle, index); }; OtpInput.prototype.renderSeparator = function (index, length) { if (this.separator.length > 0) { for (var i = index; i < length; i++) { var separatorElement = this.createElement('span', { className: 'e-otp-separator' }); separatorElement.textContent = this.separator; this.separatorElements.push(separatorElement); this.element.insertBefore(separatorElement, this.inputs[parseInt(i.toString(), 10)]); } } }; OtpInput.prototype.updateSeparatorValue = function () { var _this = this; if (this.separator === '') { this.separatorElements.forEach(function (element) { return remove(element); }); this.separatorElements = []; } else { this.separatorElements.forEach(function (element) { element.textContent = _this.separator; }); } }; OtpInput.prototype.addPlaceHolder = function () { for (var i = 0; i < this.inputs.length; i++) { var placeholderValue = this.placeholder.length <= 1 ? this.placeholder : this.placeholder.charAt(i); this.setElementAttributes({ 'placeholder': placeholderValue }, this.inputs[parseInt(i.toString(), 10)]); } }; OtpInput.prototype.updateInputType = function (inputType) { var inputMode = this.htmlAttributes['inputmode'] || (inputType === 'number' ? 'numeric' : 'text'); this.inputs.forEach(function (input) { input.type = inputType; input.setAttribute('inputmode', inputMode); }); }; OtpInput.prototype.getDefaultValue = function () { var extractedValue = typeof this.value === 'number' ? this.value.toString() : this.value; if (this.textTransform) { extractedValue = this.getTransformedText(extractedValue); } // To remove the white space if present. var value = extractedValue.replace(/\s/g, ''); return value.length > 0 ? value.split('') : undefined; }; OtpInput.prototype.getTransformedText = function (transformingText) { var transformedText = this.textTransform.toLowerCase() === TextTransform.Lowercase ? transformingText.toLowerCase() : this.textTransform.toLowerCase() === TextTransform.Uppercase ? transformingText.toUpperCase() : transformingText; return transformedText; }; OtpInput.prototype.handleInputChange = function (index, event) { var currentInputElement = this.inputs[parseInt(index.toString(), 10)]; if (currentInputElement && index < this.length - 1 && currentInputElement.value.length > 0) { var nextInputElement = this.inputs[parseInt(index.toString(), 10) + 1]; this.shouldFireFocus = this.shouldFireBlur = false; nextInputElement.focus(); if (nextInputElement && nextInputElement.value.length > 0) { nextInputElement.select(); } } var target = event.target; if (target.value.length > 1) { target.value = target.value.slice(0, 1); } if (this.textTransform) { target.value = this.getTransformedText(target.value); } this.triggerInputEvent(index, event); this.triggerValuechanged(event, true); }; OtpInput.prototype.handleKeyAction = function (index, event) { if (event.key.length > 1 && !((index === 0 && event.key === 'Backspace') || (index === this.length - 1 && event.key === 'Delete'))) { this.shouldFireFocus = this.shouldFireBlur = false; } var currentInputElement = this.inputs[parseInt(index.toString(), 10)]; var previousInputElement = this.inputs[parseInt(index.toString(), 10) - 1]; var nextInputElement = this.inputs[parseInt(index.toString(), 10) + 1]; if (event.key === 'Delete') { var value = ''; if (currentInputElement.value.length > 0) { value = currentInputElement.value; currentInputElement.value = ''; } else if (index !== this.inputs.length - 1) { value = nextInputElement.value; nextInputElement.value = ''; nextInputElement.focus(); } if (value.length > 0) { this.triggerInputEvent(index, event); } } else if (event.key === 'Backspace') { if (index !== 0 && currentInputElement.value.length === 0) { var previousValue = previousInputElement.value; previousInputElement.value = ''; previousInputElement.focus(); if (previousValue.length > 0) { this.triggerInputEvent(index, event); } } } else if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') { if (event.key === 'ArrowLeft' && index > 0) { previousInputElement.focus(); previousInputElement.select(); } else if (event.key === 'ArrowRight' && index < this.inputs.length - 1) { nextInputElement.focus(); nextInputElement.select(); } event.preventDefault(); } else if (event.key === 'ArrowUp' || event.key === 'ArrowDown') { event.preventDefault(); } else if (event.key !== 'Tab' && !event.shiftKey && !event.ctrlKey) { if (this.type === 'number' && (/\D/.test(event.key.toLocaleLowerCase()))) { event.preventDefault(); } } }; OtpInput.prototype.handleSelection = function (index) { var currentInputElement = this.inputs[parseInt(index.toString(), 10)]; if (currentInputElement.value) { currentInputElement.select(); } }; OtpInput.prototype.handleFocus = function (index, event) { addClass([this.inputs[parseInt(index.toString(), 10)]], 'e-otp-input-focus'); if (this.shouldFireFocus) { var eventArgs = { element: this.element, event: event, index: index, isInteracted: this.isFocusInCalled ? false : true, value: this.value }; this.trigger('focus', eventArgs); } this.shouldFireFocus = true; }; OtpInput.prototype.handleBlur = function (index, event) { removeClass([this.inputs[parseInt(index.toString(), 10)]], 'e-otp-input-focus'); if (this.shouldFireBlur) { var eventArgs = { element: this.element, event: event, value: this.value, index: index, isInteracted: this.isFocusOutCalled ? false : true }; this.trigger('blur', eventArgs); } this.shouldFireBlur = true; }; OtpInput.prototype.handlePaste = function (index, event) { var clipboardData = event.clipboardData; if (clipboardData) { var pastedText = clipboardData.getData('text'); var pastedValues = pastedText.split(''); var pastedValueIndex = 0; for (var i = index; i < this.inputs.length; i++) { if (pastedValues.length > 0 && pastedValues[parseInt(pastedValueIndex.toString(), 10)]) { this.inputs[parseInt(i.toString(), 10)].value = pastedValues[parseInt(pastedValueIndex.toString(), 10)]; pastedValueIndex++; this.updateValueProperty(); } } this.focusIn(); this.triggerValuechanged(event, true); } }; OtpInput.prototype.triggerInputEvent = function (index, event) { var previousValue = this.value.toString(); this.updateValueProperty(); var inputEventArgs = { element: this.element, event: event, previousValue: previousValue, value: this.value.toString(), index: index }; this.trigger('input', inputEventArgs); }; OtpInput.prototype.triggerValuechanged = function (event, isInteracted) { if (this.length === this.value.toString().length) { if (this.previousValue !== this.value) { var eventArgs = { element: this.element, event: event, isInteracted: isInteracted ? isInteracted : false, previousValue: this.previousValue, value: this.value }; this.trigger('valueChanged', eventArgs); this.previousValue = this.value.toString(); } } }; OtpInput.prototype.wireEvents = function (inputEle, index) { EventHandler.add(inputEle, 'focus', this.handleFocus.bind(this, index), this); EventHandler.add(inputEle, 'blur', this.handleBlur.bind(this, index), this); EventHandler.add(inputEle, 'input', this.handleInputChange.bind(this, index), this); EventHandler.add(inputEle, 'keydown', this.handleKeyAction.bind(this, index), this); EventHandler.add(inputEle, 'click', this.handleSelection.bind(this, index), this); EventHandler.add(inputEle, 'paste', this.handlePaste.bind(this, index), this); EventHandler.add(inputEle, 'wheel', this.handleWheelEvent, this); }; OtpInput.prototype.unWireEvents = function () { for (var i = 0; i < this.inputs.length; i++) { var currentInputElement = this.inputs[parseInt(i.toString(), 10)]; EventHandler.remove(currentInputElement, 'focus', this.handleFocus.bind(this, i)); EventHandler.remove(currentInputElement, 'blur', this.handleBlur.bind(this, i)); EventHandler.remove(currentInputElement, 'input', this.handleInputChange.bind(this, i)); EventHandler.remove(currentInputElement, 'keydown', this.handleKeyAction.bind(this, i)); EventHandler.remove(currentInputElement, 'click', this.handleSelection.bind(this, i)); EventHandler.remove(currentInputElement, 'paste', this.handlePaste.bind(this, i)); EventHandler.remove(currentInputElement, 'wheel', this.handleWheelEvent); } }; OtpInput.prototype.updateValueProperty = function () { var value = ''; this.inputs.forEach(function (input) { value += input.value; }); var prevOnChange = this.isProtectedOnChange; this.isProtectedOnChange = true; this.value = typeof this.value === 'number' ? parseInt(value, 10) : value; this.isProtectedOnChange = prevOnChange; this.hiddenInputEle.value = this.value.toString(); }; OtpInput.prototype.updateInputValue = function (previousValue) { var stringifiedValue = this.value.toString(); if (this.textTransform) { stringifiedValue = this.getTransformedText(stringifiedValue); } var previousStringValue = previousValue.toString(); for (var i = 0; i < this.inputs.length; i++) { if (previousStringValue.charAt(i) !== stringifiedValue.charAt(i)) { this.inputs[parseInt(i.toString(), 10)].value = stringifiedValue.charAt(i); this.hiddenInputEle.value = stringifiedValue; } } this.focusIn(); }; OtpInput.prototype.updateCssClass = function (addCss, removeCss) { if (removeCss === void 0) { removeCss = ''; } var _a, _b; var cssClasses; if (removeCss) { cssClasses = removeCss.trim().split(' '); (_a = this.element.classList).remove.apply(_a, cssClasses); } if (addCss) { cssClasses = addCss.trim().split(' '); (_b = this.element.classList).add.apply(_b, cssClasses); } }; OtpInput.prototype.updateVariantClass = function () { var variantClass = this.stylingMode.toLocaleLowerCase() === 'outlined' ? 'outline' : this.stylingMode.toLocaleLowerCase(); var validClasses = ['underlined', 'filled', 'outline']; if (validClasses.indexOf(variantClass) !== -1) { removeClass([this.element], validClasses.map(function (cls) { return "e-" + cls; })); addClass([this.element], "e-" + variantClass); } }; OtpInput.prototype.updateAriaLabel = function (customAriaLabel) { this.inputs.forEach(function (input, index) { var defaultLabel = "Enter Otp Character " + (index + 1); var ariaLabel = customAriaLabel && customAriaLabel.length > 0 ? customAriaLabel[parseInt(index.toString(), 10)] || defaultLabel : defaultLabel; input.setAttribute('aria-label', ariaLabel); }); }; OtpInput.prototype.updateDisabledState = function () { var _this = this; this.inputs.forEach(function (input) { if (_this.disabled) { input.setAttribute('disabled', 'disabled'); } else { input.removeAttribute('disabled'); } }); }; OtpInput.prototype.setElementAttributes = function (htmlAttributes, element) { if (!isNullOrUndefined(htmlAttributes)) { for (var key in htmlAttributes) { if (key === 'class') { var elementClass = htmlAttributes['class'].replace(/\s+/g, ' ').trim(); if (elementClass) { addClass([element], elementClass.split(' ')); } } else if (key === 'inputmode') { this.setInputMode(htmlAttributes["" + key]); } else if (key === 'name' && this.element.id === element.id) { this.hiddenInputEle.setAttribute(key, htmlAttributes["" + key]); } else { element.setAttribute(key, htmlAttributes["" + key]); } } } }; OtpInput.prototype.setInputMode = function (inputModeValue) { for (var i = 0; i < this.inputs.length; i++) { this.inputs[parseInt(i.toString(), 10)].setAttribute('inputmode', inputModeValue); } }; OtpInput.prototype.handleLengthChange = function (currentValue, previousValue) { var isLengthAdded = (currentValue - previousValue) > 0; if (isLengthAdded) { for (var i = previousValue; i < currentValue; i++) { this.createOtpInput(i); } this.renderSeparator(previousValue, currentValue); this.addPlaceHolder(); this.updateAriaLabel(this.ariaLabels); } else { if (currentValue >= 0 && this.inputs.length > 0) { for (var i = currentValue; i < this.inputs.length; i++) { remove(this.inputs[parseInt(i.toString(), 10)]); } this.inputs.splice(currentValue); if (this.separatorElements.length > 0) { // separator should be completely removed when length is 0 or 1; var index = currentValue === 0 ? 0 : currentValue - 1; for (var i = index; i < this.separatorElements.length; i++) { remove(this.separatorElements[parseInt(i.toString(), 10)]); } this.separatorElements.splice(index); } } } }; /** * To get component name. * * @returns {string} - Module Name * @private */ OtpInput.prototype.getModuleName = function () { return 'otpinput'; }; /** * To get the properties to be maintained in the persisted state. * * @returns {string} - Persist data */ OtpInput.prototype.getPersistData = function () { return this.addOnPersist([]); }; /** * Destroy the Otp input. * * @returns {void} */ OtpInput.prototype.destroy = function () { _super.prototype.destroy.call(this); this.unWireEvents(); this.inputs.forEach(function (input) { remove(input); }); this.separatorElements.forEach(function (separatorElement) { remove(separatorElement); }); remove(this.hiddenInputEle); removeClass([this.element], ['e-underlined', 'e-filled', 'e-outline', 'e-rtl']); if (this.cssClass) { removeClass([this.element], this.cssClass.trim().split(' ')); } this.element.removeAttribute('role'); this.inputs = []; this.separatorElements = []; this.hiddenInputEle = null; }; /** * Sets the focus to the Otp input for interaction. * * @returns {void} */ OtpInput.prototype.focusIn = function () { this.isFocusInCalled = true; var focusIndex = this.inputs.length - 1; for (var index = 0; index < this.inputs.length; index++) { if (!(this.inputs[parseInt(index.toString(), 10)].value.length > 0)) { focusIndex = index; break; } } this.inputs[parseInt(focusIndex.toString(), 10)].focus(); this.isFocusInCalled = false; }; /** * Remove the focus from Otp input, if it is in focus state. * * @returns {void} */ OtpInput.prototype.focusOut = function () { this.isFocusOutCalled = true; this.inputs.forEach(function (input) { input.blur(); }); this.isFocusOutCalled = false; }; /** * Called internally if any of the property value changed. * * @param {OtpInputModel} newProp - Specifies new properties * @param {OtpInputModel} oldProp - Specifies old properties * @returns {void} * @private */ OtpInput.prototype.onPropertyChanged = function (newProp, oldProp) { for (var _i = 0, _a = Object.keys(newProp); _i < _a.length; _i++) { var prop = _a[_i]; switch (prop) { case 'textTransform': this.updateInputValue(this.value); break; case 'value': this.updateInputValue(oldProp.value); this.triggerValuechanged(); break; case 'placeholder': this.addPlaceHolder(); break; case 'disabled': this.updateDisabledState(); break; case 'cssClass': this.updateCssClass(newProp.cssClass, oldProp.cssClass); break; case 'separator': if (oldProp.separator === '') { this.renderSeparator(1, this.inputs.length); } else { this.updateSeparatorValue(); } break; case 'htmlAttributes': this.setElementAttributes(newProp.htmlAttributes, this.element); break; case 'type': this.updateInputType(newProp.type); break; case 'stylingMode': this.updateVariantClass(); break; case 'ariaLabels': this.updateAriaLabel(newProp.ariaLabels); break; case 'length': this.handleLengthChange(newProp.length, oldProp.length); break; case 'enableRtl': this.element.classList[this.enableRtl ? 'add' : 'remove'](RTL); break; case 'autoFocus': if (this.autoFocus) { this.focusIn(); } break; } } }; __decorate([ Property(4) ], OtpInput.prototype, "length", void 0); __decorate([ Property('') ], OtpInput.prototype, "value", void 0); __decorate([ Property(OtpInputType.Number) ], OtpInput.prototype, "type", void 0); __decorate([ Property('') ], OtpInput.prototype, "separator", void 0); __decorate([ Property('') ], OtpInput.prototype, "placeholder", void 0); __decorate([ Property(OtpInputStyle.Outlined) ], OtpInput.prototype, "stylingMode", void 0); __decorate([ Property(false) ], OtpInput.prototype, "disabled", void 0); __decorate([ Property('') ], OtpInput.prototype, "cssClass", void 0); __decorate([ Property(false) ], OtpInput.prototype, "autoFocus", void 0); __decorate([ Property(TextTransform.None) ], OtpInput.prototype, "textTransform", void 0); __decorate([ Property({}) ], OtpInput.prototype, "htmlAttributes", void 0); __decorate([ Property([]) ], OtpInput.prototype, "ariaLabels", void 0); __decorate([ Event() ], OtpInput.prototype, "created", void 0); __decorate([ Event() ], OtpInput.prototype, "valueChanged", void 0); __decorate([ Event() ], OtpInput.prototype, "focus", void 0); __decorate([ Event() ], OtpInput.prototype, "blur", void 0); __decorate([ Event() ], OtpInput.prototype, "input", void 0); OtpInput = __decorate([ NotifyPropertyChanges ], OtpInput); return OtpInput; }(Component)); export { OtpInput };