Project

General

Profile

1
/**
2
 * Created by stefanos on 15/5/2017.
3
 */
4
import { FormGroup } from "@angular/forms";
5
import { Component, ComponentFactoryResolver, Injector, Input, Type, ViewChild, ViewContainerRef } from "@angular/core";
6
import { MyFormDirective } from "./my-form.directive";
7
import { MyGroup } from "./my-group.interface";
8
import { MyWrapper } from "./my-wrapper.interface";
9
import { Subject } from "rxjs/Subject";
10
import { Description } from '../../../domain/oa-description';
11

    
12

    
13
@Component({
14
  selector : 'form-choice',
15
  template : `
16
<form-inline [description]="{label : 'Choose'}" [params]="null">
17
    <div class="uk-margin uk-grid-small uk-child-width-auto">
18
        <label *ngFor="let radio of radioButton">
19
            <input type="radio" name="{{uniqueId}}" class="uk-radio" [checked]="radio === radioButtonSelected"
20
            (click)="changeType(radio)">
21
            {{radio}}
22
        </label>
23
    </div>
24
</form-inline>
25
<div [formGroup]="parentGroup">
26
    <ng-template my-form></ng-template>
27
</div>
28
`,
29
  styleUrls : ['']
30

    
31
})
32
export class MyChoice extends MyGroup {
33

    
34
  @Input() public components : MyChoiceComponents[];
35

    
36
  wrapper : Type<MyWrapper> = MyChoiceWrapper;
37

    
38
  @ViewChild(MyFormDirective) protected formComponents: MyFormDirective;
39

    
40
  protected _cfr : ComponentFactoryResolver;
41

    
42
  protected viewContainerRef : ViewContainerRef;
43

    
44
  arrayData_ : Subject<any>[] = [];
45
  wrapperViews : {[key : string] : MyChoiceWrapper} = {};
46

    
47
  radioButton : string[] = [];
48

    
49
  radioButtonSelected : string;
50

    
51
  registerGroup_ : FormGroup;
52

    
53
  uniqueId : string = Math.random().toString(36).substring(2);
54

    
55
  constructor(injector : Injector) {
56
    super(injector);
57
    this._cfr = injector.get(ComponentFactoryResolver);
58
  }
59

    
60
  protected createView(component : MyChoiceComponents,index : number) : void {
61
    console.log(component);
62
    let componentFactory = this._cfr.resolveComponentFactory(component.component);
63
    let wrapperFactory = this._cfr.resolveComponentFactory(this.wrapper);
64
    let wrapperView = wrapperFactory.create(this.viewContainerRef.injector);
65
    let componentView = componentFactory.create(this.viewContainerRef.injector);
66

    
67
    (<MyGroup>componentView.instance).index = this.viewContainerRef.length;
68
    (<MyGroup>componentView.instance).required = this.required;
69
    (<MyGroup>componentView.instance).data = this.data;
70
    this.arrayData_.push((<MyGroup>componentView.instance).patchData);
71
    (<MyGroup>componentView.instance).description = component.description;
72
    let arrayGroup = (<MyGroup>componentView.instance).generate();
73

    
74
    (<MyGroup>componentView.instance).parentGroup = arrayGroup as FormGroup;
75
    (<MyChoiceWrapper>wrapperView.instance).component = componentView.hostView;
76
    (<MyChoiceWrapper>wrapperView.instance).viewRef = wrapperView.hostView;
77
    (<MyChoiceWrapper>wrapperView.instance).description = this.description;
78
    (<MyChoiceWrapper>wrapperView.instance).hidden = (index != 0);
79
    (<MyChoiceWrapper>wrapperView.instance).first = this.viewContainerRef.length == 0;
80

    
81
    let registerGroup : FormGroup = this.parentGroup as FormGroup;
82
    if(this.name) {
83
      registerGroup = this.parentGroup.get(this.name as string) as FormGroup;
84
    }
85

    
86
    this.registerGroup_.registerControl(component.name, arrayGroup);
87
    if(index != 0) {
88
      setTimeout(() => {
89
        console.log(component);
90
        registerGroup.get(component.name).disable();
91
      },500)
92
    }
93
    // (<FormArray>this.parentGroup.controls[this.name]).push(arrayGroup);
94
    this.wrapperViews[component.name] = wrapperView.instance as MyChoiceWrapper;
95
    this.viewContainerRef.insert(wrapperView.hostView);
96
  }
97

    
98
  ngOnInit(): void {
99
    // super.ngOnInit();
100
    this.components.forEach(c => this.radioButton.push(c.description.label));
101
    this.radioButtonSelected = this.radioButton[0];
102
    this.viewContainerRef = this.formComponents.viewContainerRef;
103
    //if there is no name, register with the children's control
104
    if(this.name) {
105
      (<FormGroup>this.parentGroup).addControl(this.name as string, this._fb.group({}));
106
      this.registerGroup_ = this.parentGroup.get(this.name as string) as FormGroup;
107
    } else {
108
      this.registerGroup_ = this.parentGroup as FormGroup;
109
    }
110
    this.components.forEach((item,index) => {
111
      this.createView(item,index);
112
    });
113

    
114
    this.registerGroup_.patchValue = this.patchValue();
115

    
116
  }
117

    
118
  changeType(radio : string) {
119
    let newSelected : string  = this.components[this.radioButton.indexOf(radio)].name;
120
    let currentSelected : string  = this.components[this.radioButton.indexOf(this.radioButtonSelected)].name;
121
    (this.registerGroup_.get(currentSelected) as FormGroup).disable();
122
    (this.registerGroup_.get(newSelected) as FormGroup).enable();
123
    this.wrapperViews[currentSelected].hidden = true;
124
    this.wrapperViews[newSelected].hidden = false;
125
    this.radioButtonSelected = radio;
126
  }
127

    
128
  protected patchValue() {
129
    let self = this;
130
    return (value: {[key: string]: any}, {onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}) => {
131
      Object.keys(value).forEach(v => {
132
        if (v != null) {
133
          let component = self.components.find(component => component.name == v);
134
          self.changeType(component.description.label);
135
          self.registerGroup_.get(v).patchValue(value[v]);
136
          console.log(value[v]);
137
        }
138
      });
139
    };
140
  }
141
}
142

    
143
@Component({
144
  selector : 'form-choice-wrapper',
145
  template : `
146
<div class="uk-grid uk-margin" [hidden]="hidden">
147
    <div class="uk-width-5-6">
148
        <ng-template my-form></ng-template>
149
    </div>
150
</div>
151
`,
152
  styleUrls : ['']
153

    
154
})
155
export class MyChoiceWrapper extends MyWrapper {
156
  @Input()
157
  public hidden = false;
158
}
159

    
160
export class MyChoiceComponents {
161
  public component : Type<MyGroup>;
162
  public name : string;
163
  public description : Description;
164

    
165
  constructor(name : string , component : Type<MyGroup>,description : Description) {
166
    this.component = component;
167
    this.name = name;
168
    this.description = description;
169

    
170
  }
171
}
(2-2/5)