diff --git a/src/app/shared/components/form-input/form-input.component.html b/src/app/shared/components/form-input/form-input.component.html
index b1ef73456..0b56d1a82 100644
--- a/src/app/shared/components/form-input/form-input.component.html
+++ b/src/app/shared/components/form-input/form-input.component.html
@@ -15,26 +15,28 @@
/>
}
@if (type === 'select') {
-
-}
-@if (type === 'select') {
-
- {{ getOptionTextFromValue(control.value) || placeholder }}
+
+
+
}
diff --git a/src/app/shared/components/form-input/form-input.component.scss b/src/app/shared/components/form-input/form-input.component.scss
index 6deabe989..5bc44eafc 100644
--- a/src/app/shared/components/form-input/form-input.component.scss
+++ b/src/app/shared/components/form-input/form-input.component.scss
@@ -3,3 +3,41 @@
cursor: not-allowed;
user-select: none;
}
+
+.select-wrapper {
+ position: relative;
+ width: 100%;
+ border: 1px solid #ced4da;
+ padding: 10px 0px;
+}
+
+.real-select {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ opacity: 0;
+ z-index: 2;
+ cursor: pointer;
+}
+
+.input-vertical-select-placeholder {
+ position: relative;
+ z-index: 1;
+}
+
+.select-wrapper {
+ position: relative;
+ width: 100%;
+}
+
+.styled-select {
+ width: 100%;
+ cursor: pointer;
+}
+
+.open-toggle {
+ cursor: pointer;
+ top: 24px;
+}
diff --git a/src/app/shared/components/form-input/form-input.component.spec.ts b/src/app/shared/components/form-input/form-input.component.spec.ts
new file mode 100644
index 000000000..531ffaf80
--- /dev/null
+++ b/src/app/shared/components/form-input/form-input.component.spec.ts
@@ -0,0 +1,106 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import {
+ FormsModule,
+ ReactiveFormsModule,
+ UntypedFormControl,
+} from '@angular/forms';
+import { By } from '@angular/platform-browser';
+import {
+ FormInputComponent,
+ FormInputSelectOption,
+} from './form-input.component';
+
+describe('FormInputComponent', () => {
+ let component: FormInputComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [FormInputComponent],
+ imports: [FormsModule, ReactiveFormsModule],
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(FormInputComponent);
+ component = fixture.componentInstance;
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should render a text input when type is not "select"', () => {
+ component.type = 'text';
+ component.fieldName = 'username';
+ component.placeholder = 'Enter username';
+ component.control = new UntypedFormControl('');
+ fixture.detectChanges();
+
+ const inputEl = fixture.debugElement.query(By.css('input.form-control'));
+
+ expect(inputEl).toBeTruthy();
+ expect(inputEl.nativeElement.placeholder).toBe('Enter username');
+ });
+
+ it('should render a select when type is "select"', () => {
+ component.type = 'select';
+ component.fieldName = 'country';
+ component.placeholder = 'Select country';
+ component.selectOptions = [
+ { value: 'us', text: 'USA' },
+ { value: 'ca', text: 'Canada' },
+ ];
+ component.control = new UntypedFormControl('');
+ fixture.detectChanges();
+
+ const selectEl = fixture.debugElement.query(By.css('select'));
+
+ expect(selectEl).toBeTruthy();
+ const options = selectEl.queryAll(By.css('option'));
+
+ expect(options.length).toBe(2);
+ });
+
+ it('should toggle openStatus when openSelect() is called', () => {
+ expect(component.openStatus).toBeFalse();
+ component.openSelect();
+
+ expect(component.openStatus).toBeTrue();
+ component.openSelect();
+
+ expect(component.openStatus).toBeFalse();
+ });
+
+ it('should reset openStatus and alert when handleChange() is called', () => {
+ spyOn(window, 'alert');
+ component.openStatus = true;
+ component.handleChange();
+
+ expect(component.openStatus).toBeFalse();
+ expect(window.alert).toHaveBeenCalledWith('Element selected... closed');
+ });
+
+ it('should display the correct option text from value', () => {
+ const options: FormInputSelectOption[] = [
+ { text: 'Apple', value: 'a' },
+ { text: 'Banana', value: 'b' },
+ ];
+ component.selectOptions = options;
+ const result = component.getOptionTextFromValue('b');
+
+ expect(result).toBe('Banana');
+ });
+
+ it('should hide label if value is empty and type is number', () => {
+ component.type = 'number';
+ component.control = new UntypedFormControl('');
+
+ expect(component.isLabelHidden()).toBeTrue();
+ });
+
+ it('should not hide label if type is date', () => {
+ component.type = 'date';
+ component.control = new UntypedFormControl('');
+
+ expect(component.isLabelHidden()).toBeFalse();
+ });
+});
diff --git a/src/app/shared/components/form-input/form-input.component.ts b/src/app/shared/components/form-input/form-input.component.ts
index c71fe2bdc..569141a3b 100644
--- a/src/app/shared/components/form-input/form-input.component.ts
+++ b/src/app/shared/components/form-input/form-input.component.ts
@@ -47,6 +47,8 @@ export class FormInputComponent implements OnInit, AfterViewInit {
@HostBinding('class.right-align') rightAlign = false;
@HostBinding('class.input-vertical') inputVertical = true;
+ openStatus = false;
+
@Input() config: FormInputConfig;
constructor(private element: ElementRef) {}
@@ -125,4 +127,11 @@ export class FormInputComponent implements OnInit, AfterViewInit {
getOptionTextFromValue(value: string) {
return find(this.selectOptions, { value })?.text;
}
+ openSelect() {
+ this.openStatus = !this.openStatus;
+ }
+
+ handleChange() {
+ this.openStatus = false;
+ }
}