Newer
Older
import {
CompoundElement, InputElement, InputElementValue, UIElement
} from '../uI-element';
import {
ClozePart, FontElement, LikertColumn, LikertRow
} from '../../interfaces/UIElementInterfaces';
import { TextFieldElement } from '../text-field-element';
import { TextAreaElement } from '../text-area-element';
import { CheckboxElement } from '../checkbox-element';
import { DropdownElement } from '../dropdown-element';
import { DropListElement } from './drop-list';
import { initFontElement } from '../../util/unit-interface-initializer';
export class ClozeElement extends CompoundElement implements FontElement {
text: string = '<p>Lorem ipsum dolor \\z sit amet \\i\n' +
'\n' +
'Lorem ipsum dolor \\z sit amet \\i\n' +
'\n' +
'Lorem ipsum dolor \\z sit amet \\i</p>';
childElements: InputElement[] = [];
fontColor: string = 'black';
font: string = 'Roboto';
fontSize: number = 20;
lineHeight: number = 120;
bold: boolean = false;
italic: boolean = false;
underline: boolean = false;
constructor(serializedElement: UIElement) {
super(serializedElement);
Object.assign(this, serializedElement);
Object.assign(this, initFontElement(serializedElement));
36
37
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
this.createParts(this.text as string);
this.height = 200;
this.width = 500;
}
setProperty(property: string, value: InputElementValue | string[] | LikertColumn[] | LikertRow[]): void {
super.setProperty(property, value);
if (property === 'text') {
this.createParts(value as string);
}
}
private createParts(htmlText: string): void {
const paragraphList = ClozeElement.readElementArray(htmlText);
this.parts = [];
paragraphList.forEach((p, i) => {
this.parseParagraphs(p.innerText, i);
});
// console.log('PARTS:', this.parts);
}
private static readElementArray(htmlText: string): HTMLParagraphElement[] {
const el = document.createElement('html');
el.innerHTML = htmlText;
return Array.from(el.getElementsByTagName('p'));
}
parseParagraphs(p: string, partIndex: number): void {
this.parts[partIndex] = []; // init array to be able to push
let [nextSpecialElementIndex, nextElementType] = ClozeElement.getNextSpecialElement(p);
let indexOffset = 0;
while (nextSpecialElementIndex !== -1) {
nextSpecialElementIndex += indexOffset;
this.parts[partIndex].push({ type: 'text', value: p.substring(indexOffset, nextSpecialElementIndex) });
const newElement = ClozeElement.createElement(nextElementType);
this.childElements.push(newElement);
this.parts[partIndex].push({ type: nextElementType, value: newElement });
indexOffset = nextSpecialElementIndex + 2; // + 2 to get rid of the marker, i.e. '\b'
[nextSpecialElementIndex, nextElementType] =
ClozeElement.getNextSpecialElement(p.substring(indexOffset));
}
this.parts[partIndex].push({ type: 'text', value: p.substring(indexOffset) });
}
private static getNextSpecialElement(p: string): [number, string] {
const x = [];
if (p.indexOf('\\d') > 0) {
x.push(p.indexOf('\\d'));
}
if (p.indexOf('\\i') > 0) {
x.push(p.indexOf('\\i'));
}
if (p.indexOf('\\z') > 0) {
x.push(p.indexOf('\\z'));
}
const y = Math.min(...x);
let nextElementType = '';
switch (p[y + 1]) {
case 'd': nextElementType = 'dropdown'; break;
case 'i': nextElementType = 'text-field'; break;
case 'z': nextElementType = 'drop-list'; break;
default: return [-1, 'unknown'];
}
return [y, nextElementType];
}
private static createElement(elementType: string): InputElement {
const elementModel: UIElement = { type: elementType } as UIElement;
let newElement: InputElement;
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
switch (elementModel.type) {
case 'text-field':
newElement = new TextFieldElement(elementModel);
(newElement as TextFieldElement).label = '';
break;
case 'text-area':
newElement = new TextAreaElement(elementModel);
break;
case 'checkbox':
newElement = new CheckboxElement(elementModel);
break;
case 'dropdown':
newElement = new DropdownElement(elementModel);
break;
case 'drop-list':
newElement = new DropListElement(elementModel);
newElement.height = 30;
newElement.width = 100;
break;
default:
throw new Error(`ElementType ${elementModel.type} not found!`);
}
console.log('newElement', newElement);
return newElement;
}
}