From 99e04439c028f4005e1c52c7a3a70fba3b6f7dbb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tormod=20Nyg=C3=A5rd?= <tormodny@stud.ntnu.no>
Date: Tue, 16 Feb 2021 22:34:51 +0100
Subject: [PATCH] Issue: Custom input components (#3)

---
 .../posts/post-form/post-form.component.html  | 16 ++++-----
 .../app/shared/button/button.component.html   |  1 +
 .../app/shared/button/button.component.scss   |  3 ++
 .../shared/button/button.component.spec.ts    | 25 ++++++++++++++
 .../src/app/shared/button/button.component.ts | 15 +++++++++
 .../number-input/number-input.component.html  | 12 +++++++
 .../number-input/number-input.component.scss  |  3 ++
 .../number-input.component.spec.ts            | 25 ++++++++++++++
 .../number-input/number-input.component.ts    | 33 +++++++++++++++++++
 .../app/shared/select/select.component.html   | 13 ++++++++
 .../app/shared/select/select.component.scss   |  3 ++
 .../shared/select/select.component.spec.ts    | 25 ++++++++++++++
 .../src/app/shared/select/select.component.ts | 33 +++++++++++++++++++
 client/src/app/shared/shared.module.ts        | 22 ++++++++++---
 .../text-input/text-input.component.html      | 14 ++++++--
 .../text-input/text-input.component.scss      |  2 +-
 .../shared/text-input/text-input.component.ts | 21 ++++++++++--
 17 files changed, 247 insertions(+), 19 deletions(-)
 create mode 100644 client/src/app/shared/button/button.component.html
 create mode 100644 client/src/app/shared/button/button.component.scss
 create mode 100644 client/src/app/shared/button/button.component.spec.ts
 create mode 100644 client/src/app/shared/button/button.component.ts
 create mode 100644 client/src/app/shared/number-input/number-input.component.html
 create mode 100644 client/src/app/shared/number-input/number-input.component.scss
 create mode 100644 client/src/app/shared/number-input/number-input.component.spec.ts
 create mode 100644 client/src/app/shared/number-input/number-input.component.ts
 create mode 100644 client/src/app/shared/select/select.component.html
 create mode 100644 client/src/app/shared/select/select.component.scss
 create mode 100644 client/src/app/shared/select/select.component.spec.ts
 create mode 100644 client/src/app/shared/select/select.component.ts

diff --git a/client/src/app/posts/post-form/post-form.component.html b/client/src/app/posts/post-form/post-form.component.html
index bbe7faa..e898035 100644
--- a/client/src/app/posts/post-form/post-form.component.html
+++ b/client/src/app/posts/post-form/post-form.component.html
@@ -1,22 +1,18 @@
 <h3>Lag annonse</h3>
 
-<label for="title">Tittel</label>
-<input id="title" [(ngModel)]="title" (blur)="checkForm()">
+<app-text-input [(inputModel)]="title" label="Tittel" (blur)="checkForm()"></app-text-input>
 
-<label for="description">Beskrivelse</label>
-<input id="description" [(ngModel)]="description" (blur)="checkForm()">
+<app-text-input [(inputModel)]="description" label="Beskrivelse" (blur)="checkForm()"></app-text-input>
 
-<label for="price">Pris</label>
-<input type="number" id="price" [(ngModel)]="price" (blur)="checkForm()">
+<app-number-input [(inputModel)]="price" label="Pris" (blur)="checkForm()"></app-number-input>
 
-<label for="category">Kategori</label>
-<select id="category" [(ngModel)]="categoryid" (change)="checkForm()" >
+<app-select [(inputModel)]="categoryid" (change)="checkForm()" label="Kategori">
     <option value="0" selected>Velg kategori</option>
     <option value="1">Antikviteter og Kunst</option>
     <option value="2">Dyr og Utstyr</option>
     <option value="3">Elektronikk og Hvitevarer</option>
-</select>
+</app-select>
 
 <p>{{statusMessage}}</p>
 
-<button (click)="publishPost()">Publiser</button>
\ No newline at end of file
+<app-button (click)="publishPost()" text="Publiser"></app-button>
\ No newline at end of file
diff --git a/client/src/app/shared/button/button.component.html b/client/src/app/shared/button/button.component.html
new file mode 100644
index 0000000..e9923aa
--- /dev/null
+++ b/client/src/app/shared/button/button.component.html
@@ -0,0 +1 @@
+<button>{{text}}</button>
\ No newline at end of file
diff --git a/client/src/app/shared/button/button.component.scss b/client/src/app/shared/button/button.component.scss
new file mode 100644
index 0000000..2b4a216
--- /dev/null
+++ b/client/src/app/shared/button/button.component.scss
@@ -0,0 +1,3 @@
+button{
+    padding: 5px;
+}
\ No newline at end of file
diff --git a/client/src/app/shared/button/button.component.spec.ts b/client/src/app/shared/button/button.component.spec.ts
new file mode 100644
index 0000000..534a5ba
--- /dev/null
+++ b/client/src/app/shared/button/button.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ButtonComponent } from './button.component';
+
+describe('ButtonComponent', () => {
+  let component: ButtonComponent;
+  let fixture: ComponentFixture<ButtonComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ ButtonComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ButtonComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/client/src/app/shared/button/button.component.ts b/client/src/app/shared/button/button.component.ts
new file mode 100644
index 0000000..605e843
--- /dev/null
+++ b/client/src/app/shared/button/button.component.ts
@@ -0,0 +1,15 @@
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+
+@Component({
+  selector: 'app-button',
+  templateUrl: './button.component.html',
+  styleUrls: ['./button.component.scss']
+})
+export class ButtonComponent {
+
+  @Input()
+  text: string;
+
+  constructor() { }
+
+}
diff --git a/client/src/app/shared/number-input/number-input.component.html b/client/src/app/shared/number-input/number-input.component.html
new file mode 100644
index 0000000..f8ce8b6
--- /dev/null
+++ b/client/src/app/shared/number-input/number-input.component.html
@@ -0,0 +1,12 @@
+<label>
+    {{label}}
+
+    <input  
+    type="number"
+    [placeholder]="placeholder"
+    [(ngModel)]="inputModel" 
+    (ngModelChange)="inputModelChange.emit(inputModel)" 
+    (change)="change.emit($event)"
+    (focus)="focus.emit($event)"
+    (blur)="blur.emit($event)">
+</label>
\ No newline at end of file
diff --git a/client/src/app/shared/number-input/number-input.component.scss b/client/src/app/shared/number-input/number-input.component.scss
new file mode 100644
index 0000000..00cdc2a
--- /dev/null
+++ b/client/src/app/shared/number-input/number-input.component.scss
@@ -0,0 +1,3 @@
+input{
+    padding: 5px;
+}
\ No newline at end of file
diff --git a/client/src/app/shared/number-input/number-input.component.spec.ts b/client/src/app/shared/number-input/number-input.component.spec.ts
new file mode 100644
index 0000000..2ff4b9f
--- /dev/null
+++ b/client/src/app/shared/number-input/number-input.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NumberInputComponent } from './number-input.component';
+
+describe('NumberInputComponent', () => {
+  let component: NumberInputComponent;
+  let fixture: ComponentFixture<NumberInputComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ NumberInputComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(NumberInputComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/client/src/app/shared/number-input/number-input.component.ts b/client/src/app/shared/number-input/number-input.component.ts
new file mode 100644
index 0000000..7552012
--- /dev/null
+++ b/client/src/app/shared/number-input/number-input.component.ts
@@ -0,0 +1,33 @@
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+
+@Component({
+  selector: 'app-number-input',
+  templateUrl: './number-input.component.html',
+  styleUrls: ['./number-input.component.scss']
+})
+export class NumberInputComponent {
+
+  @Input()
+  label: string = "";
+
+  @Input()
+  inputModel: number;
+
+  @Input()
+  placeholder: string = "";
+
+  @Output()
+  inputModelChange = new EventEmitter<number>();
+
+  @Output()
+  change = new EventEmitter();
+
+  @Output()
+  focus = new EventEmitter();
+
+  @Output()
+  blur = new EventEmitter();
+
+  constructor() { }
+
+}
diff --git a/client/src/app/shared/select/select.component.html b/client/src/app/shared/select/select.component.html
new file mode 100644
index 0000000..e7e4e7f
--- /dev/null
+++ b/client/src/app/shared/select/select.component.html
@@ -0,0 +1,13 @@
+<label>
+    {{label}}
+    
+    <select
+        [(ngModel)]="inputModel"
+        (ngModelChange)="inputModelChange.emit($event)"
+        (change)="change.emit($event)"
+        (focus)="focus.emit($event)"
+        (blur)="blur.emit($event)">
+
+        <ng-content></ng-content>
+    </select>
+</label>
\ No newline at end of file
diff --git a/client/src/app/shared/select/select.component.scss b/client/src/app/shared/select/select.component.scss
new file mode 100644
index 0000000..ffd6836
--- /dev/null
+++ b/client/src/app/shared/select/select.component.scss
@@ -0,0 +1,3 @@
+select{
+    padding: 5px;
+}
\ No newline at end of file
diff --git a/client/src/app/shared/select/select.component.spec.ts b/client/src/app/shared/select/select.component.spec.ts
new file mode 100644
index 0000000..2fb4207
--- /dev/null
+++ b/client/src/app/shared/select/select.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SelectComponent } from './select.component';
+
+describe('SelectComponent', () => {
+  let component: SelectComponent;
+  let fixture: ComponentFixture<SelectComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ SelectComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(SelectComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/client/src/app/shared/select/select.component.ts b/client/src/app/shared/select/select.component.ts
new file mode 100644
index 0000000..81e1d4b
--- /dev/null
+++ b/client/src/app/shared/select/select.component.ts
@@ -0,0 +1,33 @@
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+
+@Component({
+  selector: 'app-select',
+  templateUrl: './select.component.html',
+  styleUrls: ['./select.component.scss']
+})
+export class SelectComponent {
+
+  @Input()
+  label: string = "";
+
+  @Input()
+  inputModel: any;
+
+  @Input()
+  placeholder: string = "";
+
+  @Output()
+  inputModelChange = new EventEmitter<any>();
+
+  @Output()
+  change = new EventEmitter();
+
+  @Output()
+  focus = new EventEmitter();
+
+  @Output()
+  blur = new EventEmitter();
+
+  constructor() { }
+
+}
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts
index cfbb9db..8459044 100644
--- a/client/src/app/shared/shared.module.ts
+++ b/client/src/app/shared/shared.module.ts
@@ -1,14 +1,28 @@
 import { NgModule } from '@angular/core';
 import { CommonModule } from '@angular/common';
 import { TextInputComponent } from './text-input/text-input.component';
-
+import { FormsModule } from '@angular/forms';
+import { NumberInputComponent } from './number-input/number-input.component';
+import { ButtonComponent } from './button/button.component';
+import { SelectComponent } from './select/select.component';
 
 
 @NgModule({
-  declarations: [TextInputComponent],
-  exports: [TextInputComponent],
+  declarations: [
+    TextInputComponent,
+    NumberInputComponent,
+    ButtonComponent,
+    SelectComponent
+  ],
+  exports: [
+    TextInputComponent,
+    NumberInputComponent,
+    ButtonComponent,
+    SelectComponent
+  ],
   imports: [
-    CommonModule
+    CommonModule,
+    FormsModule
   ]
 })
 export class SharedModule { }
diff --git a/client/src/app/shared/text-input/text-input.component.html b/client/src/app/shared/text-input/text-input.component.html
index 75c9ae0..52b28fd 100644
--- a/client/src/app/shared/text-input/text-input.component.html
+++ b/client/src/app/shared/text-input/text-input.component.html
@@ -1,2 +1,12 @@
-<label for="textField">{{label}}</label>
-<input type="text" id="textField">
\ No newline at end of file
+<label>
+    {{label}}
+
+    <input  
+    type="text"
+    [placeholder]="placeholder"
+    [(ngModel)]="inputModel" 
+    (ngModelChange)="inputModelChange.emit(inputModel)" 
+    (change)="change.emit($event)"
+    (focus)="focus.emit($event)"
+    (blur)="blur.emit($event)">
+</label>
\ No newline at end of file
diff --git a/client/src/app/shared/text-input/text-input.component.scss b/client/src/app/shared/text-input/text-input.component.scss
index e8b11aa..00cdc2a 100644
--- a/client/src/app/shared/text-input/text-input.component.scss
+++ b/client/src/app/shared/text-input/text-input.component.scss
@@ -1,3 +1,3 @@
-#textField{
+input{
     padding: 5px;
 }
\ No newline at end of file
diff --git a/client/src/app/shared/text-input/text-input.component.ts b/client/src/app/shared/text-input/text-input.component.ts
index 57eb5e8..91d87ed 100644
--- a/client/src/app/shared/text-input/text-input.component.ts
+++ b/client/src/app/shared/text-input/text-input.component.ts
@@ -1,5 +1,4 @@
-import { Component, Input, OnInit, Output } from '@angular/core';
-import { ControlValueAccessor } from '@angular/forms';
+import { Component, EventEmitter, Input, Output } from '@angular/core';
 
 @Component({
   selector: 'app-text-input',
@@ -11,6 +10,24 @@ export class TextInputComponent {
   @Input()
   label: string = "";
 
+  @Input()
+  inputModel: string;
+
+  @Input()
+  placeholder: string = "";
+
+  @Output()
+  inputModelChange = new EventEmitter<string>();
+
+  @Output()
+  change = new EventEmitter();
+
+  @Output()
+  focus = new EventEmitter();
+
+  @Output()
+  blur = new EventEmitter();
+
   constructor() { }
 
 }
-- 
GitLab