Skip to content
Snippets Groups Projects
cloze.component.ts 5.55 KiB
Newer Older
import {
  Component, EventEmitter, Output, QueryList, ViewChildren
} from '@angular/core';
rhenck's avatar
rhenck committed
import { ClozeElement } from './cloze-element';
import { CompoundElementComponent } from '../../directives/compound-element.directive';
rhenck's avatar
rhenck committed
import { InputElement, ClozePart } from '../../models/uI-element';
import { FormElementComponent } from '../../directives/form-element-component.directive';
rhenck's avatar
rhenck committed

@Component({
  selector: 'app-cloze',
  template: `
    <div [class.center-content]="elementModel.positionProps.dynamicPositioning &&
                                 elementModel.positionProps.fixedSize"
         [style.width]="elementModel.positionProps.fixedSize ? elementModel.width + 'px' : '100%'"
         [style.height]="elementModel.positionProps.fixedSize ? elementModel.height + 'px' : 'auto'">
      <p *ngFor="let paragraph of elementModel.parts; let i = index"
         [style.line-height.%]="elementModel.fontProps.lineHeight"
         [style.color]="elementModel.fontProps.fontColor"
         [style.font-family]="elementModel.fontProps.font"
         [style.font-size.px]="elementModel.fontProps.fontSize"
         [style.font-weight]="elementModel.fontProps.bold ? 'bold' : ''"
         [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''"
         [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''">
        <ng-container *ngFor="let part of paragraph; let j = index">
rhenck's avatar
rhenck committed

          <span *ngIf="part.type === 'p'"
               [innerHTML]="part.value"
               [style]="part.style">
          </span>
rhenck's avatar
rhenck committed

          <h1 *ngIf="part.type === 'h1'"
              [innerHTML]="part.value"
              [style.display]="'inline'"
              [style]="part.style">
          </h1>
          <h2 *ngIf="part.type === 'h2'"
              [innerHTML]="part.value"
              [style.display]="'inline'"
              [style]="part.style">
          </h2>
          <h3 *ngIf="part.type === 'h3'"
              [innerHTML]="part.value"
              [style.display]="'inline'"
              [style]="part.style">
          </h3>
          <h4 *ngIf="part.type === 'h4'"
              [innerHTML]="part.value"
              [style.display]="'inline'"
              [style]="part.style">
          </h4>
          <span (click)="allowClickThrough || selectElement($any(part.value), $event)">
            <app-dropdown *ngIf="part.type === 'dropdown'" #drowdownComponent
                          [parentForm]="parentForm"
rhenck's avatar
rhenck committed
                          [style.display]="'inline-block'"
                          [style.pointerEvents]="allowClickThrough ? 'auto' : 'none'"
                          [elementModel]="$any(part.value)"
                          (elementValueChanged)="elementValueChanged.emit($event)">
            </app-dropdown>
            <app-text-field-simple *ngIf="part.type === 'text-field'" #textfieldComponent
                            [parentForm]="parentForm"
                            [style.display]="'inline-block'"
                            [style.pointerEvents]="allowClickThrough ? 'auto' : 'none'"
                            [elementModel]="$any(part.value)"
                            (elementValueChanged)="elementValueChanged.emit($event)">
            </app-text-field-simple>
            <app-toggle-button *ngIf="part.type === 'toggle-button'" #radioComponent
                            [parentForm]="parentForm"
                            [style.display]="'inline-block'"
                            [style.pointerEvents]="allowClickThrough ? 'auto' : 'none'"
                            [elementModel]="$any(part.value)"
                            (elementValueChanged)="elementValueChanged.emit($event)">
            </app-toggle-button>
            <div *ngIf="part.type === 'drop-list'"
                 [style.display]="'inline-block'"
                 [style.pointerEvents]="allowClickThrough ? 'auto' : 'none'"
                 [style.vertical-align]="'middle'"
                 [style.width.px]="$any(part.value).width"
                 [style.height.px]="$any(part.value).height">
              <app-drop-list-simple #droplistComponent
                             [parentForm]="parentForm"
                             (elementValueChanged)="elementValueChanged.emit($event)"
                             [elementModel]="$any(part.value)">
              </app-drop-list-simple>
            </div>
          </span>
        </ng-container>
      </p>
    </div>
    ':host ::ng-deep app-text-field {vertical-align: middle}',
    ':host ::ng-deep app-text-field .mat-form-field-wrapper {height: 100%; padding-bottom: 0; margin: 0}',
    ':host ::ng-deep app-text-field .mat-form-field {height: 100%}',
    ':host ::ng-deep app-text-field .mat-form-field-flex {height: 100%}',
rhenck's avatar
rhenck committed
    'p {margin: 0}',
rhenck's avatar
rhenck committed
    'p span {font-size: inherit}'
rhenck's avatar
rhenck committed
})
export class ClozeComponent extends CompoundElementComponent {
  elementModel!: ClozeElement;
  @Output() elementSelected = new EventEmitter<{ element: ClozeElement, event: MouseEvent }>();
rhenck's avatar
rhenck committed
  @ViewChildren('drowdownComponent, textfieldComponent, droplistComponent, radioComponent')
  compoundChildren!: QueryList<FormElementComponent>;
rhenck's avatar
rhenck committed

  getFormElementModelChildren(): InputElement[] {
rhenck's avatar
rhenck committed
    const uiElements: InputElement[] = [];
    this.elementModel.parts.forEach((subParts: ClozePart[]) => {
      subParts.forEach((part: ClozePart) => {
        if (part.value instanceof InputElement) {
          uiElements.push(part.value);
        }
      });
    });
    return uiElements;
rhenck's avatar
rhenck committed
  }

  selectElement(element: ClozeElement, event: MouseEvent): void {
    this.elementSelected.emit({ element: element, event: event });
rhenck's avatar
rhenck committed
  }
}