Skip to content

Commit

Permalink
Release v 1.3.1:
Browse files Browse the repository at this point in the history
- Fixing #21 #20
- Adjusted tslint issues
  • Loading branch information
AlexMiniApps committed Dec 1, 2020
1 parent d05f28f commit 1c910c2
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 32 deletions.
6 changes: 6 additions & 0 deletions angular-code-input/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 1.3.1 (01.12.2020)
**Note:** The following changes have been made:
- The issue with inline component configuration has been resolved
- Have fixed issues with readonly properties in Angular 11
- Adjusting tslint issues

# 1.3.0 (30.11.2020)
**Note:** The following changes have been made:
- Added the root config of the component
Expand Down
2 changes: 1 addition & 1 deletion angular-code-input/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "angular-code-input",
"version": "1.3.0",
"version": "1.3.1",
"description": "Code or pin code input for Angular 7 - 11+ / Ionic 4, 5 + projects",
"keywords": ["angular", "pincode", "angular-pincode", "otp", "code-input", "angular-otp", "ionic-otp", "ionic-code-input", "ionic-pincode"],
"author": "Alexander Dmitrenko",
Expand Down
1 change: 0 additions & 1 deletion angular-code-input/src/lib/code-input.component.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<span *ngFor="let holder of placeholders; index as i"
[class.empty]="isInputElementEmptyAt(i)"
[class.code-hidden]="isCodeHidden">
<input #input
(click)="onClick($event)"
Expand Down
78 changes: 48 additions & 30 deletions angular-code-input/src/lib/code-input.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,26 +32,29 @@ enum InputState {
})
export class CodeInputComponent implements AfterViewInit, OnInit, OnChanges, AfterViewChecked, CodeInputComponentConfig {

@ViewChildren('input') inputsList: QueryList<ElementRef>;
@ViewChildren('input') inputsList !: QueryList<ElementRef>;

@Input() readonly codeLength;
@Input() readonly inputType;
@Input() readonly initialFocusField?: number;
@Input() codeLength !: number;
@Input() inputType !: string;
@Input() initialFocusField?: number;
/** @deprecated Use isCharsCode prop instead. */
@Input() isNonDigitsCode = false;
@Input() isCharsCode;
@Input() isCodeHidden;
@Input() isPrevFocusableAfterClearing;
@Input() isFocusingOnLastByClickIfFilled;
@Input() code?: string | number;
@Input() isCharsCode !: boolean;
@Input() isCodeHidden !: boolean;
@Input() isPrevFocusableAfterClearing !: boolean;
@Input() isFocusingOnLastByClickIfFilled !: boolean;
@Input() code ?: string | number;

@Output() readonly codeChanged = new EventEmitter<string>();
@Output() readonly codeCompleted = new EventEmitter<string>();

public placeholders: number[];
public placeholders !: number[];

private inputs: HTMLInputElement[] = [];
private inputsStates: InputState[] = [];

// tslint:disable-next-line:variable-name
private _codeLength !: number;
private state = {
isFocusingAfterAppearingCompleted: false,
isInitialFocusFieldEnabled: false
Expand All @@ -74,6 +77,7 @@ export class CodeInputComponent implements AfterViewInit, OnInit, OnChanges, Aft
continue;
}

// @ts-ignore
this[prop] = config[prop];
}
}
Expand All @@ -83,7 +87,9 @@ export class CodeInputComponent implements AfterViewInit, OnInit, OnChanges, Aft
*/

ngOnInit(): void {
this.placeholders = Array(this.codeLength).fill(1);
// defining internal code length prop for skipping external prop updates
this._codeLength = this.codeLength;
this.placeholders = Array(this._codeLength).fill(1);
this.state.isInitialFocusFieldEnabled = !this.isEmpty(this.initialFocusField);
}

Expand Down Expand Up @@ -118,14 +124,14 @@ export class CodeInputComponent implements AfterViewInit, OnInit, OnChanges, Aft
}

const target = e.target;
const last = this.inputs[this.codeLength - 1];
const last = this.inputs[this._codeLength - 1];
// already focused
if (target === last) {
return;
}

// check filling
const isFilled = this.getCurrentFilledCode().length >= this.codeLength;
const isFilled = this.getCurrentFilledCode().length >= this._codeLength;
if (!isFilled) {
return;
}
Expand Down Expand Up @@ -155,7 +161,7 @@ export class CodeInputComponent implements AfterViewInit, OnInit, OnChanges, Aft
this.setInputValue(target, value.toString().charAt(0));
this.emitChanges();

if (next > this.codeLength - 1) {
if (next > this._codeLength - 1) {
target.blur();
return;
}
Expand All @@ -174,7 +180,8 @@ export class CodeInputComponent implements AfterViewInit, OnInit, OnChanges, Aft
}

// Convert paste text into iterable
const values = data.split('');
// tslint:disable-next-line:no-non-null-assertion
const values = data!.split('');
let valIndex = 0;

for (let j = i; j < this.inputs.length; j++) {
Expand Down Expand Up @@ -228,15 +235,6 @@ export class CodeInputComponent implements AfterViewInit, OnInit, OnChanges, Aft
}
}

isInputElementEmptyAt(index: number): boolean {
const input = this.inputs[index];
if (!input) {
return true;
}

return this.isEmpty(input.value);
}

private onInputCodeChanges(): void {
if (!this.inputs.length) {
return;
Expand All @@ -249,16 +247,20 @@ export class CodeInputComponent implements AfterViewInit, OnInit, OnChanges, Aft
return;
}

const chars = this.code.toString().trim().split('');
// tslint:disable-next-line:no-non-null-assertion
const chars = this.code!.toString().trim().split('');
// checking if all the values are correct
let isAllCharsAreAllowed = true;
for (const char of chars) {
if (!this.canInputValue(char)) {
return;
isAllCharsAreAllowed = false;
break;
}
}

this.inputs.forEach((input: HTMLInputElement, index: number) => {
this.setInputValue(input, chars[index]);
const value = isAllCharsAreAllowed ? chars[index] : null;
this.setInputValue(input, value);
});
}

Expand All @@ -271,6 +273,10 @@ export class CodeInputComponent implements AfterViewInit, OnInit, OnChanges, Aft
return;
}

if (!this.initialFocusField) {
return;
}

this.inputs[this.initialFocusField].focus();
this.state.isFocusingAfterAppearingCompleted = document.activeElement === this.inputs[this.initialFocusField];
}
Expand All @@ -284,7 +290,7 @@ export class CodeInputComponent implements AfterViewInit, OnInit, OnChanges, Aft

this.codeChanged.emit(code);

if (code.length >= this.codeLength) {
if (code.length >= this._codeLength) {
this.codeCompleted.emit(code);
}
}
Expand Down Expand Up @@ -327,8 +333,20 @@ export class CodeInputComponent implements AfterViewInit, OnInit, OnChanges, Aft

private setInputValue(input: HTMLInputElement, value: any): void {
const isEmpty = this.isEmpty(value);
input.value = isEmpty ? null : value;
input.className = isEmpty ? '' : 'has-value';
const valueClassCSS = 'has-value';
const emptyClassCSS = 'empty';
if (isEmpty) {
input.value = '';
input.classList.remove(valueClassCSS);
// tslint:disable-next-line:no-non-null-assertion
input.parentElement!.classList.add(emptyClassCSS);
}
else {
input.value = value;
input.classList.add(valueClassCSS);
// tslint:disable-next-line:no-non-null-assertion
input.parentElement!.classList.remove(emptyClassCSS);
}
}

private canInputValue(value: any): boolean {
Expand Down

0 comments on commit 1c910c2

Please sign in to comment.