Skip to content
Snippets Groups Projects
Commit 77a896f5 authored by rhenck's avatar rhenck
Browse files

Add alternative radio button group with images

This works similarly to the standard radio group, but has a fixed 
horizontal layout with images above the options.
parent 52983df6
No related branches found
No related tags found
No related merge requests found
import { Component } from '@angular/core';
import { RadioGroupImagesElement } from '../../models/compound-elements/radio-group-images';
import { FormElementComponent } from '../../form-element-component.directive';
@Component({
selector: 'app-radio-group-images',
template: `
<div class="mat-form-field"
[style.width.%]="100"
[style.height.%]="100"
[style.background-color]="elementModel.backgroundColor"
[style.color]="elementModel.fontColor"
[style.font-family]="elementModel.font"
[style.font-size.px]="elementModel.fontSize"
[style.font-weight]="elementModel.bold ? 'bold' : ''"
[style.font-style]="elementModel.italic ? 'italic' : ''"
[style.text-decoration]="elementModel.underline ? 'underline' : ''">
<label id="radio-group-label" class="white-space-break"
[innerHTML]="elementModel.label">
</label>
<mat-radio-group aria-labelledby="radio-group-label" [formControl]="elementFormControl"
class="grid-layout" [style.display]="'grid'"
[style.grid-template-columns]="'1fr '.repeat(elementModel.columns.length)">
<div *ngFor="let option of elementModel.columns; let i = index" class="columns"
fxLayout="column"
[style.grid-column-start]="1 + i"
[style.grid-column-end]="2 + i"
[style.grid-row-start]="1"
[style.grid-row-end]="2">
<img *ngIf="option.imgSrc && option.position === 'above'"
[src]="option.imgSrc | safeResourceUrl" alt="Image Placeholder">
<div>{{option.text}}</div>
<img *ngIf="option.imgSrc && option.position === 'below'"
[src]="option.imgSrc | safeResourceUrl" alt="Image Placeholder">
</div>
<mat-radio-button *ngFor="let option of elementModel.columns; let i = index"
[style.pointer-events]="elementModel.readOnly ? 'none' : 'unset'"
[value]="i"
[style.grid-column-start]="1 + i"
[style.grid-column-end]="2 + i"
[style.grid-row-start]="2"
[style.grid-row-end]="3">
</mat-radio-button>
</mat-radio-group>
</div>
`,
styles: [
'.grid-layout .columns {text-align: center;}',
'.grid-layout .columns img {height: 100%; object-fit: none;}',
'::ng-deep app-radio-group-images .grid-layout mat-radio-button span.mat-radio-container {left: calc(50% - 10px)}',
'mat-radio-group {margin-top: 10px}',
'.grid-layout mat-radio-button {margin-top: 15px}'
]
})
export class RadioGroupImagesComponent extends FormElementComponent {
elementModel!: RadioGroupImagesElement;
}
...@@ -15,7 +15,8 @@ export class IdService { ...@@ -15,7 +15,8 @@ export class IdService {
audio: 0, audio: 0,
video: 0, video: 0,
likert: 0, likert: 0,
likert_row: 0 likert_row: 0,
'radio-group-images': 0
}; };
static getInstance(): IdService { static getInstance(): IdService {
......
import { InputElement, UIElement } from '../uI-element';
import { LikertColumn, FontElement, SurfaceUIElement } from '../../interfaces/UIElementInterfaces';
import { initFontElement, initSurfaceElement } from '../../util/unit-interface-initializer';
export class RadioGroupImagesElement extends InputElement implements FontElement, SurfaceUIElement {
columns: LikertColumn[] = [];
fontColor: string = 'black';
font: string = 'Roboto';
fontSize: number = 18;
lineHeight: number = 120;
bold: boolean = false;
italic: boolean = false;
underline: boolean = false;
backgroundColor: string = 'transparent';
constructor(serializedElement: UIElement) {
super(serializedElement);
Object.assign(this, serializedElement);
Object.assign(this, initFontElement(serializedElement));
Object.assign(this, initSurfaceElement(serializedElement));
this.height = serializedElement.height || 100;
this.backgroundColor = serializedElement.backgroundColor as string || 'transparent';
}
}
...@@ -3,7 +3,7 @@ import { IdService } from '../id.service'; ...@@ -3,7 +3,7 @@ import { IdService } from '../id.service';
import { LikertColumn, LikertRow } from '../interfaces/UIElementInterfaces'; import { LikertColumn, LikertRow } from '../interfaces/UIElementInterfaces';
export type UIElementType = 'text' | 'button' | 'text-field' | 'text-area' | 'checkbox' export type UIElementType = 'text' | 'button' | 'text-field' | 'text-area' | 'checkbox'
| 'dropdown' | 'radio' | 'image' | 'audio' | 'video' | 'likert' | 'likert_row'; | 'dropdown' | 'radio' | 'image' | 'audio' | 'video' | 'likert' | 'likert_row' | 'radio-group-images';
export type InputElementValue = string | number | boolean | null; export type InputElementValue = string | number | boolean | null;
export interface ValueChangeElement { export interface ValueChangeElement {
......
...@@ -41,6 +41,7 @@ import { PlayerTimeFormatPipe } from './element-components/control-bar/player-ti ...@@ -41,6 +41,7 @@ import { PlayerTimeFormatPipe } from './element-components/control-bar/player-ti
import { LikertComponent } from './element-components/compound-elements/likert.component'; import { LikertComponent } from './element-components/compound-elements/likert.component';
import { LikertRadioButtonGroupComponent } from './element-components/compound-elements/likert-radio-button-group.component'; import { LikertRadioButtonGroupComponent } from './element-components/compound-elements/likert-radio-button-group.component';
import { Magnifier } from './element-components/magnifier.component'; import { Magnifier } from './element-components/magnifier.component';
import { RadioGroupImagesComponent } from './element-components/compound-elements/radio-group-images.component';
@NgModule({ @NgModule({
imports: [ imports: [
...@@ -79,7 +80,8 @@ import { Magnifier } from './element-components/magnifier.component'; ...@@ -79,7 +80,8 @@ import { Magnifier } from './element-components/magnifier.component';
PlayerTimeFormatPipe, PlayerTimeFormatPipe,
LikertComponent, LikertComponent,
LikertRadioButtonGroupComponent, LikertRadioButtonGroupComponent,
Magnifier Magnifier,
RadioGroupImagesComponent
], ],
exports: [ exports: [
CommonModule, CommonModule,
......
...@@ -23,6 +23,8 @@ import { AudioComponent } from '../element-components/audio.component'; ...@@ -23,6 +23,8 @@ import { AudioComponent } from '../element-components/audio.component';
import { VideoComponent } from '../element-components/video.component'; import { VideoComponent } from '../element-components/video.component';
import { LikertElement } from '../models/compound-elements/likert-element'; import { LikertElement } from '../models/compound-elements/likert-element';
import { LikertComponent } from '../element-components/compound-elements/likert.component'; import { LikertComponent } from '../element-components/compound-elements/likert.component';
import { RadioGroupImagesComponent } from '../element-components/compound-elements/radio-group-images.component';
import { RadioGroupImagesElement } from '../models/compound-elements/radio-group-images';
export function createElement(elementModel: UIElement): UIElement { export function createElement(elementModel: UIElement): UIElement {
let newElement: UIElement; let newElement: UIElement;
...@@ -60,6 +62,9 @@ export function createElement(elementModel: UIElement): UIElement { ...@@ -60,6 +62,9 @@ export function createElement(elementModel: UIElement): UIElement {
case 'likert': case 'likert':
newElement = new LikertElement(elementModel); newElement = new LikertElement(elementModel);
break; break;
case 'radio-group-images':
newElement = new RadioGroupImagesElement(elementModel);
break;
default: default:
throw new Error(`ElementType ${elementModel.type} not found!`); throw new Error(`ElementType ${elementModel.type} not found!`);
} }
...@@ -94,6 +99,8 @@ export function getComponentFactory( ...@@ -94,6 +99,8 @@ export function getComponentFactory(
return componentFactoryResolver.resolveComponentFactory(VideoComponent); return componentFactoryResolver.resolveComponentFactory(VideoComponent);
case 'likert': case 'likert':
return componentFactoryResolver.resolveComponentFactory(LikertComponent); return componentFactoryResolver.resolveComponentFactory(LikertComponent);
case 'radio-group-images':
return componentFactoryResolver.resolveComponentFactory(RadioGroupImagesComponent);
default: default:
throw new Error('unknown element'); throw new Error('unknown element');
} }
......
...@@ -60,6 +60,11 @@ ...@@ -60,6 +60,11 @@
<ng-template mat-tab-label> <ng-template mat-tab-label>
<mat-icon class="example-tab-icon">widgets</mat-icon> <mat-icon class="example-tab-icon">widgets</mat-icon>
</ng-template> </ng-template>
<button mat-raised-button (click)="addUIElement('radio-group-images')"
draggable="true" (dragstart)="$event.dataTransfer?.setData('elementType','radio-group-images')">
<mat-icon>radio_button_checked</mat-icon>
Optionsfelder (Bild)
</button>
<button mat-raised-button (click)="addUIElement('likert')" <button mat-raised-button (click)="addUIElement('likert')"
draggable="true" (dragstart)="$event.dataTransfer?.setData('elementType','likert')"> draggable="true" (dragstart)="$event.dataTransfer?.setData('elementType','likert')">
<mat-icon>toc</mat-icon> <mat-icon>toc</mat-icon>
......
...@@ -12,7 +12,7 @@ import { Unit } from '../../../../common/models/unit'; ...@@ -12,7 +12,7 @@ import { Unit } from '../../../../common/models/unit';
selector: 'app-unit-view', selector: 'app-unit-view',
templateUrl: './unit-view.component.html', templateUrl: './unit-view.component.html',
styles: [ styles: [
'.toolbox_drawer {width: 230px}', '.toolbox_drawer {width: 248px}',
'.properties_drawer {width: 320px}', '.properties_drawer {width: 320px}',
'.drawer-button {font-size: large;background-color: lightgray; min-width: 0; width: 2%;}', '.drawer-button {font-size: large;background-color: lightgray; min-width: 0; width: 2%;}',
'.drawer-button {border: none; cursor: pointer}', '.drawer-button {border: none; cursor: pointer}',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment