renderer.ts 3.44 KB
Newer Older
Daniel Bluhm's avatar
Daniel Bluhm committed
1
import {css, customElement, html, LitElement, property, TemplateResult} from 'lit-element';
2
import '@vaadin/vaadin-text-field';
Daniel Bluhm's avatar
Daniel Bluhm committed
3
import '@vaadin/vaadin-checkbox';
4
import { Person } from './Person';
Daniel Bluhm's avatar
Daniel Bluhm committed
5
import { DataElement } from './data-element';
6

Jay Jay Billings's avatar
Jay Jay Billings committed
7
/**
Daniel Bluhm's avatar
Daniel Bluhm committed
8
9
10
 * Tasks:
 * *This class should be templated or take a function call back in place of
 * updateDataElement and loadData.
Jay Jay Billings's avatar
Jay Jay Billings committed
11
12
 * *Add documentation as required.
 * *Remove console debug statements
Daniel Bluhm's avatar
Daniel Bluhm committed
13
14
 * *This is just an example so the rest doesn't matter much, (the rest being
 * changing the render() function, etc.).
Jay Jay Billings's avatar
Jay Jay Billings committed
15
 */
16
17
@customElement("renderer-template")
class Renderer extends LitElement {
Daniel Bluhm's avatar
Daniel Bluhm committed
18
19

  person: Person = new Person();
20
21
22
23
24
25

  @property({type: String})
  dataElementJSON = '';

  static styles = css`
    h1 {
26
      color: blue;
27
28
29
30
31
32
33
34
      text-transform: uppercase;
    }
  `;

  constructor() {
    super();
  }

Daniel Bluhm's avatar
Daniel Bluhm committed
35
36
  loadData() {
    this.person = <Person> JSON.parse(this.dataElementJSON);
37
  }
Daniel Bluhm's avatar
Daniel Bluhm committed
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

  /**
   * Create an updater method for updating the objects field on form events.
   * @param obj holding object of field
   * @param field field for which an updater is generated
   * @returns updater method
   */
  fieldUpdater(obj: object, field: string):
      (e: {target: HTMLInputElement}) => void
  {
    let that = this;
    return function(e: {target: HTMLInputElement}) {
      if (typeof Reflect.get(obj, field) === 'number') {
        Reflect.set(obj, field, Number(e.target.value))
      } else if (typeof Reflect.get(obj, field) === 'string') {
        Reflect.set(obj, field, e.target.value);
      } else if (typeof Reflect.get(obj, field) === 'boolean') {
        Reflect.set(obj, field, e.target.checked);
      }
      that.dataElementJSON = JSON.stringify(that.person);
      that.dispatchEvent(new CustomEvent(
        'data-changed',
        {bubbles: true, composed: true, detail: e.target.value}
      ));
    };
63
64
  }

Daniel Bluhm's avatar
Daniel Bluhm committed
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  /**
   * Create input form element for the given field.
   * @param obj holding object of field
   * @param field field for which input is generated
   * @returns html template result
   */
  fieldInput(obj: object, field: string): TemplateResult {
    if (typeof Reflect.get(obj, field) === 'boolean') {
      return html`
        <vaadin-checkbox
          value="${field}"
          ?checked=${Reflect.get(obj, field)}
          @change=${this.fieldUpdater(obj, field)}
        >${field}</vaadin-checkbox>
      `;
    } else {
      return html`
        <vaadin-text-field
          label="${field}"
          .value=${Reflect.get(obj, field)}
          @input=${this.fieldUpdater(obj, field)}
        ></vaadin-text-field>
      `;
    }
89
90
  }

Daniel Bluhm's avatar
Daniel Bluhm committed
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  /**
   * Create a form for the passed DataElement.
   *
   * In this experiment, forms are generated by inspecting the data element.
   * In the future, we hope to generate these forms directly from the DataElement
   * Spec classes during Annotation Processing.
   * @param element element for which a form will be generated
   * @returns form html
   */
  dataElementForm(element: DataElement): TemplateResult {
    let form = html``;
    for (let field in element) {
      form = html`${form}${this.fieldInput(element, field)}`;
    }
   return form;
  }
Jay Jay Billings's avatar
Jay Jay Billings committed
107

Daniel Bluhm's avatar
Daniel Bluhm committed
108
109
110
111
  /**
   * Render this LitElement.
   */
  render() {
112
113
    return html`
      <script>${this.loadData()}</script>
Daniel Bluhm's avatar
Daniel Bluhm committed
114
115
      <h1>Greetings ${this.person.age} year old ${this.person.firstName}!</h1>

116
      <div>
Daniel Bluhm's avatar
Daniel Bluhm committed
117
        ${this.dataElementForm(this.person)}
118
      </div>
Jay Jay Billings's avatar
Jay Jay Billings committed
119

120
      <pre>${JSON.stringify(this.person, null, 2)}</pre>
121
122
123
    `;
  }
}