Skip to content

Commit bf09c7d

Browse files
committed
Fixed #46 - Change codeLength in app
1 parent f9d40db commit bf09c7d

File tree

1 file changed

+51
-12
lines changed

1 file changed

+51
-12
lines changed

angular-code-input/src/lib/code-input.component.ts

+51-12
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
Inject,
88
Input,
99
OnChanges,
10+
OnDestroy,
1011
OnInit,
1112
Optional,
1213
Output,
@@ -19,6 +20,7 @@ import {
1920
CodeInputComponentConfigToken,
2021
defaultComponentConfig
2122
} from './code-input.component.config';
23+
import { Subscription } from 'rxjs';
2224

2325
enum InputState {
2426
ready = 0,
@@ -31,7 +33,7 @@ enum InputState {
3133
templateUrl: 'code-input.component.html',
3234
styleUrls: ['./code-input.component.scss']
3335
})
34-
export class CodeInputComponent implements AfterViewInit, OnInit, OnChanges, AfterViewChecked, CodeInputComponentConfig {
36+
export class CodeInputComponent implements AfterViewInit, OnInit, OnChanges, OnDestroy, AfterViewChecked, CodeInputComponentConfig {
3537

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

@@ -51,10 +53,11 @@ export class CodeInputComponent implements AfterViewInit, OnInit, OnChanges, Aft
5153
@Output() readonly codeChanged = new EventEmitter<string>();
5254
@Output() readonly codeCompleted = new EventEmitter<string>();
5355

54-
public placeholders !: number[];
56+
public placeholders: number[] = [];
5557

5658
private inputs: HTMLInputElement[] = [];
5759
private inputsStates: InputState[] = [];
60+
private inputsListSubscription !: Subscription;
5861

5962
// tslint:disable-next-line:variable-name
6063
private _codeLength !: number;
@@ -90,20 +93,16 @@ export class CodeInputComponent implements AfterViewInit, OnInit, OnChanges, Aft
9093
*/
9194

9295
ngOnInit(): void {
93-
// defining internal code length prop for skipping external prop updates
94-
this._codeLength = this.codeLength;
95-
this.placeholders = Array(this._codeLength).fill(1);
96+
// defining the state
9697
this.state.isInitialFocusFieldEnabled = !this.isEmpty(this.initialFocusField);
98+
// initiating the code
99+
this.onCodeLengthChanges();
97100
}
98101

99102
ngAfterViewInit(): void {
100-
this.inputsList.forEach((item) => {
101-
this.inputs.push(item.nativeElement);
102-
this.inputsStates.push(InputState.ready);
103-
});
104-
105-
// the @Input code might have value. Checking
106-
this.onInputCodeChanges();
103+
// initiation of the inputs
104+
this.inputsListSubscription = this.inputsList.changes.subscribe(this.onInputsListChanges.bind(this));
105+
this.onInputsListChanges(this.inputsList);
107106
}
108107

109108
ngAfterViewChecked(): void {
@@ -114,6 +113,15 @@ export class CodeInputComponent implements AfterViewInit, OnInit, OnChanges, Aft
114113
if (changes.code) {
115114
this.onInputCodeChanges();
116115
}
116+
if (changes.codeLength) {
117+
this.onCodeLengthChanges();
118+
}
119+
}
120+
121+
ngOnDestroy(): void {
122+
if (this.inputsListSubscription) {
123+
this.inputsListSubscription.unsubscribe();
124+
}
117125
}
118126

119127
/**
@@ -297,6 +305,37 @@ export class CodeInputComponent implements AfterViewInit, OnInit, OnChanges, Aft
297305
});
298306
}
299307

308+
private onCodeLengthChanges(): void {
309+
if (!this.codeLength) {
310+
return;
311+
}
312+
313+
this._codeLength = this.codeLength;
314+
if (this._codeLength > this.placeholders.length) {
315+
const numbers = Array(this._codeLength - this.placeholders.length).fill(1);
316+
this.placeholders.splice(this.placeholders.length - 1, 0, ...numbers);
317+
}
318+
else if (this._codeLength < this.placeholders.length) {
319+
this.placeholders.splice(this._codeLength);
320+
}
321+
}
322+
323+
private onInputsListChanges(list: QueryList<ElementRef>): void {
324+
if (list.length > this.inputs.length) {
325+
const inputsToAdd = list.filter((item, index) => index > this.inputs.length - 1);
326+
this.inputs.splice(this.inputs.length, 0, ...inputsToAdd.map(item => item.nativeElement));
327+
const states = Array(inputsToAdd.length).fill(InputState.ready);
328+
this.inputsStates.splice(this.inputsStates.length, 0, ...states);
329+
}
330+
else if (list.length < this.inputs.length) {
331+
this.inputs.splice(list.length);
332+
this.inputsStates.splice(list.length);
333+
}
334+
335+
// filling the inputs after changing of their count
336+
this.onInputCodeChanges();
337+
}
338+
300339
private focusOnInputAfterAppearing(): void {
301340
if (!this.state.isInitialFocusFieldEnabled) {
302341
return;

0 commit comments

Comments
 (0)