Skip to content

Commit 156d34a

Browse files
author
Maxime Lafarie
committed
first commit 🎉
1 parent 1c87274 commit 156d34a

29 files changed

+553
-38
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<div [formGroup]="form">
2+
<label [attr.for]="question.key">{{ question.label }}</label>
3+
4+
<div [ngSwitch]="question.controlType">
5+
6+
<input *ngSwitchCase="'textbox'"
7+
[class]="isValid ? config.validClass : config.invalidClass"
8+
[formControlName]="question.key"
9+
[placeholder]="question.placeholder"
10+
[id]="question.key"
11+
[type]="question['type']">
12+
13+
<select [id]="question.key"
14+
*ngSwitchCase="'dropdown'"
15+
[class]="isValid ? config.validClass : config.invalidClass"
16+
[formControlName]="question.key">
17+
<option value=""
18+
disabled
19+
*ngIf="!!question.placeholder"
20+
selected>{{ question.placeholder }}</option>
21+
<option *ngFor="let opt of question['options']"
22+
[value]="opt.key">{{ opt.value }}</option>
23+
</select>
24+
25+
<textarea *ngSwitchCase="'textarea'"
26+
[formControlName]="question.key"
27+
[id]="question.key"
28+
[class]="isValid ? config.validClass : config.invalidClass"
29+
[cols]="question['cols']"
30+
[rows]="question['rows']"
31+
[maxlength]="question['maxlength']"
32+
[minlength]="question['minlength']"
33+
[placeholder]="question.placeholder"></textarea>
34+
35+
<button *ngIf="question.iterable"
36+
type="button"
37+
(click)="addItem(question)">+</button>
38+
</div>
39+
40+
<div class="errorMessage"
41+
*ngIf="!isValid">{{ question.label }} is required</div>
42+
</div>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.errorMessage{
2+
color:red;
3+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2+
3+
import { DynamicFormQuestionComponent } from './dynamic-form-question.component';
4+
5+
describe('DynamicFormQuestionComponent', () => {
6+
let component: DynamicFormQuestionComponent;
7+
let fixture: ComponentFixture<DynamicFormQuestionComponent>;
8+
9+
beforeEach(async(() => {
10+
TestBed.configureTestingModule({
11+
declarations: [ DynamicFormQuestionComponent ]
12+
})
13+
.compileComponents();
14+
}));
15+
16+
beforeEach(() => {
17+
fixture = TestBed.createComponent(DynamicFormQuestionComponent);
18+
component = fixture.componentInstance;
19+
fixture.detectChanges();
20+
});
21+
22+
it('should create', () => {
23+
expect(component).toBeTruthy();
24+
});
25+
});
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Component, OnInit, Input } from '@angular/core';
2+
import { FormGroup, FormArray, FormControl } from '@angular/forms';
3+
4+
import { QuestionBase, QuestionConfig } from '@app/models';
5+
6+
@Component({
7+
selector: 'app-question',
8+
templateUrl: './dynamic-form-question.component.html',
9+
styleUrls: ['./dynamic-form-question.component.scss']
10+
})
11+
export class DynamicFormQuestionComponent implements OnInit {
12+
13+
@Input() question: QuestionBase<any>;
14+
@Input() form: FormGroup;
15+
@Input() config: QuestionConfig;
16+
get isValid() { return this.form.controls[this.question.key].valid; }
17+
18+
constructor() {
19+
}
20+
21+
ngOnInit() {
22+
23+
if (this.question.iterable) {
24+
console.log(this.question);
25+
}
26+
}
27+
28+
public addItem(question: QuestionBase<any>): void {
29+
(<FormArray> this.form.get(question.key)).push(new FormControl(''));
30+
console.log(question);
31+
}
32+
33+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { NgModule } from '@angular/core';
2+
import { CommonModule } from '@angular/common';
3+
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
4+
5+
import { DynamicFormQuestionComponent } from './dynamic-form-question.component';
6+
7+
@NgModule({
8+
imports: [
9+
CommonModule,
10+
FormsModule,
11+
ReactiveFormsModule
12+
],
13+
declarations: [DynamicFormQuestionComponent],
14+
exports: [DynamicFormQuestionComponent]
15+
})
16+
export class DynamicFormQuestionModule { }
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<div>
2+
<form (ngSubmit)="onSubmit()"
3+
[formGroup]="form">
4+
5+
<div *ngFor="let question of questions"
6+
class="form-row">
7+
<app-question [question]="question"
8+
[config]="config"
9+
[form]="form"></app-question>
10+
</div>
11+
12+
<div class="form-row">
13+
<button type="submit"
14+
[disabled]="!form.valid">Save</button>
15+
</div>
16+
</form>
17+
18+
<div *ngIf="payLoad"
19+
class="form-row">
20+
<strong>Saved the following values</strong><br>
21+
<pre><code>{{ payLoad | json }}</code></pre>
22+
</div>
23+
</div>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// /* pre {
2+
// white-space: pre-wrap; /* css-3 */
3+
// white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
4+
// white-space: -pre-wrap; /* Opera 4-6 */
5+
// white-space: -o-pre-wrap; /* Opera 7 */
6+
// word-wrap: break-word; /* Internet Explorer 5.5+ */
7+
// display: block;
8+
// padding: 9.5px;
9+
// margin: 0 0 10px;
10+
// font-size: 13px;
11+
// line-height: 1.428571429;
12+
// color: #333;
13+
// word-break: break-all;
14+
// word-wrap: break-word;
15+
// background-color: #f5f5f5;
16+
// border: 1px solid #ccc;
17+
// border-radius: 4px;
18+
// }
19+
20+
// .form-row{
21+
// margin-top: 10px;
22+
// }
23+
// */
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2+
3+
import { DynamicFormComponent } from './dynamic-form.component';
4+
5+
describe('DynamicFormComponent', () => {
6+
let component: DynamicFormComponent;
7+
let fixture: ComponentFixture<DynamicFormComponent>;
8+
9+
beforeEach(async(() => {
10+
TestBed.configureTestingModule({
11+
declarations: [ DynamicFormComponent ]
12+
})
13+
.compileComponents();
14+
}));
15+
16+
beforeEach(() => {
17+
fixture = TestBed.createComponent(DynamicFormComponent);
18+
component = fixture.componentInstance;
19+
fixture.detectChanges();
20+
});
21+
22+
it('should create', () => {
23+
expect(component).toBeTruthy();
24+
});
25+
});
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Component, OnInit, Input, Inject } from '@angular/core';
2+
import { FormGroup } from '@angular/forms';
3+
4+
import { QuestionBase, QuestionConfig } from '@app/models';
5+
import { QuestionControlService } from '@app/services';
6+
7+
@Component({
8+
selector: 'app-dynamic-form',
9+
templateUrl: './dynamic-form.component.html',
10+
styleUrls: ['./dynamic-form.component.scss']
11+
})
12+
export class DynamicFormComponent implements OnInit {
13+
14+
@Input() questions: QuestionBase<any>[] = [];
15+
form: FormGroup;
16+
payLoad = '';
17+
18+
constructor(
19+
@Inject('questionConfig') public config: QuestionConfig,
20+
private qcs: QuestionControlService
21+
) { }
22+
23+
ngOnInit() {
24+
this.form = this.qcs.toFormGroup(this.questions);
25+
}
26+
27+
onSubmit() {
28+
this.payLoad = this.form.value;
29+
}
30+
31+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { NgModule, ModuleWithProviders } from '@angular/core';
2+
import { CommonModule } from '@angular/common';
3+
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
4+
5+
import { DynamicFormComponent } from './dynamic-form.component';
6+
import { DynamicFormQuestionModule } from '../dynamic-form-question/dynamic-form-question.module';
7+
8+
import { QuestionConfig } from '@app/models';
9+
import { QuestionControlService } from '@app/services';
10+
11+
@NgModule({
12+
imports: [
13+
CommonModule,
14+
FormsModule,
15+
ReactiveFormsModule,
16+
DynamicFormQuestionModule
17+
],
18+
providers: [QuestionControlService],
19+
declarations: [DynamicFormComponent],
20+
exports: [DynamicFormComponent]
21+
})
22+
export class DynamicFormModule {
23+
24+
/**
25+
* Use in AppModule: new instance of NgxSmartModal.
26+
*/
27+
public static forRoot(config?: QuestionConfig): ModuleWithProviders {
28+
if (!config) {
29+
config = { validClass: 'valid', invalidClass: 'invalid' };
30+
}
31+
32+
return {
33+
ngModule: DynamicFormModule,
34+
providers: [QuestionControlService, { provide: 'questionConfig', useValue: config }]
35+
};
36+
}
37+
38+
/**
39+
* Use in features modules with lazy loading: new instance of NgxSmartModal.
40+
*/
41+
public static forChild(): ModuleWithProviders {
42+
return {
43+
ngModule: DynamicFormModule,
44+
providers: [QuestionControlService]
45+
};
46+
}
47+
48+
}

0 commit comments

Comments
 (0)