diff --git a/projects/common/components/ui-elements/text-field-simple.component.ts b/projects/common/components/ui-elements/text-field-simple.component.ts
index 8651ec386e1c9977b1805ee1c04df9938e323cf2..6cd951dbb46b051f2a6abe7504c312c7fbbddfe7 100644
--- a/projects/common/components/ui-elements/text-field-simple.component.ts
+++ b/projects/common/components/ui-elements/text-field-simple.component.ts
@@ -1,11 +1,13 @@
-import { Component, Input } from '@angular/core';
+import {
+  Component, EventEmitter, Input, Output
+} from '@angular/core';
 import { FormElementComponent } from '../../directives/form-element-component.directive';
 import { TextFieldSimpleElement } from '../../interfaces/elements';
 
 @Component({
   selector: 'aspect-text-field-simple',
   template: `
-    <input type="text" form="parentForm"
+    <input #input type="text"
            autocomplete="off"
            autocapitalize="none"
            autocorrect="off"
@@ -21,7 +23,9 @@ import { TextFieldSimpleElement } from '../../interfaces/elements';
            [style.text-decoration]="elementModel.styling.underline ? 'underline' : ''"
            [readonly]="elementModel.readOnly"
            [formControl]="elementFormControl"
-           [value]="elementModel.value">
+           [value]="elementModel.value"
+           (focus)="elementModel.inputAssistancePreset !== 'none' ? onFocusChanged.emit(input) : null"
+           (blur)="elementModel.inputAssistancePreset !== 'none' ? onFocusChanged.emit(null): null">
   `,
   styles: [
     'input {border: 1px solid rgba(0,0,0,.12); border-radius: 5px}'
@@ -29,4 +33,5 @@ import { TextFieldSimpleElement } from '../../interfaces/elements';
 })
 export class TextFieldSimpleComponent extends FormElementComponent {
   @Input() elementModel!: TextFieldSimpleElement;
+  @Output() onFocusChanged = new EventEmitter<HTMLElement | null>();
 }
diff --git a/projects/common/directives/element-component.directive.ts b/projects/common/directives/element-component.directive.ts
index 08d18bed0718ec643122fea65cdf34d08db03a90..0993eaf1161df45f933850dabe14799dde7dc8b2 100644
--- a/projects/common/directives/element-component.directive.ts
+++ b/projects/common/directives/element-component.directive.ts
@@ -9,7 +9,7 @@ export abstract class ElementComponent implements AfterContentChecked {
   abstract elementModel: UIElement;
   project!: 'player' | 'editor';
 
-  constructor(private elementRef: ElementRef) {}
+  constructor(public elementRef: ElementRef) {}
 
   get domElement(): Element {
     return this.elementRef.nativeElement;
diff --git a/projects/common/interfaces/elements.ts b/projects/common/interfaces/elements.ts
index c5260db341ee740a2fef5e0267cc59380f319518..f706e3364e0dddf368cfe5a1b737253321626541 100644
--- a/projects/common/interfaces/elements.ts
+++ b/projects/common/interfaces/elements.ts
@@ -284,6 +284,8 @@ export interface TextAreaElement extends InputElement {
 
 export interface TextFieldSimpleElement extends InputElement {
   type: 'text-field';
+  inputAssistancePreset: InputAssistancePreset;
+  inputAssistancePosition: 'floating' | 'right';
   styling: BasicStyles; // TODO okay? bg-color?
 }
 
diff --git a/projects/common/util/element.factory.ts b/projects/common/util/element.factory.ts
index e220dd50129b6c8dbdb5f9134a99604959aab5be..762ca1cd8b1559402f29dc06e284a2fada7097a5 100644
--- a/projects/common/util/element.factory.ts
+++ b/projects/common/util/element.factory.ts
@@ -467,6 +467,9 @@ export abstract class ElementFactory {
       ...ElementFactory.initInputElement({ height: 25, ...element }),
       type: 'text-field',
       label: element.label !== undefined ? element.label : undefined,
+      inputAssistancePreset: element.inputAssistancePreset !== undefined ? element.inputAssistancePreset : 'none',
+      inputAssistancePosition: element.inputAssistancePosition !== undefined ?
+        element.inputAssistancePosition : 'floating',
       styling: ElementFactory.initBasicStyles(element.styling)
     };
   }
diff --git a/projects/player/src/app/components/element-compound-group/element-compound-group.component.html b/projects/player/src/app/components/element-compound-group/element-compound-group.component.html
index 3431f87175e9e60d8f2373ae61e3b450520fd3d4..7c8b896eba999c320f466938c472e0ad594d271f 100644
--- a/projects/player/src/app/components/element-compound-group/element-compound-group.component.html
+++ b/projects/player/src/app/components/element-compound-group/element-compound-group.component.html
@@ -1,4 +1,5 @@
-<form [formGroup]="form">
+<form class="inline-container"
+      [formGroup]="form">
   <aspect-cloze
       *ngIf="elementModel.type === 'cloze'"
       #elementComponent
@@ -14,3 +15,15 @@
       (childrenAdded)="onChildrenAdded($event)">
   </aspect-likert>
 </form>
+
+<aspect-floating-keyboard
+    *ngIf="keyboardService.preset !== 'none'"
+    [isKeyboardOpen]="isKeyboardOpen && keyboardService.position === 'floating'"
+    [overlayOrigin]="keyboardService.elementComponent"
+    [inputElement]="keyboardService.inputElement"
+    [position]="keyboardService.position"
+    [preset]="keyboardService.preset"
+    [positionOffset]="0"
+    (deleteCharacter)="keyboardService.deleterCharacters()"
+    (enterKey)="keyboardService.enterKey($event)">
+</aspect-floating-keyboard>
diff --git a/projects/player/src/app/components/element-compound-group/element-compound-group.component.ts b/projects/player/src/app/components/element-compound-group/element-compound-group.component.ts
index b5f07265c914c7654565115b2f305345d4480777..8a24bbb027ceab5b51a5e4600231ccfd29de1ca8 100644
--- a/projects/player/src/app/components/element-compound-group/element-compound-group.component.ts
+++ b/projects/player/src/app/components/element-compound-group/element-compound-group.component.ts
@@ -1,7 +1,7 @@
 import { Component, OnInit, ViewChild } from '@angular/core';
 import { TranslateService } from '@ngx-translate/core';
 import {
-  ClozeElement, InputElement, LikertElement
+  ClozeElement, InputElement, LikertElement, TextFieldElement
 } from '../../../../../common/interfaces/elements';
 import { ClozeUtils } from '../../../../../common/util/cloze';
 import { UnitStateService } from '../../services/unit-state.service';
@@ -11,6 +11,10 @@ import { ElementFormGroupDirective } from '../../directives/element-form-group.d
 import { MessageService } from '../../../../../common/services/message.service';
 import { VeronaSubscriptionService } from '../../services/verona-subscription.service';
 import { ValidatorService } from '../../services/validator.service';
+import { KeyboardService } from '../../services/keyboard.service';
+import { TextAreaComponent } from '../../../../../common/components/ui-elements/text-area.component';
+import { TextFieldComponent } from '../../../../../common/components/ui-elements/text-field.component';
+import { TextFieldSimpleComponent } from '../../../../../common/components/ui-elements/text-field-simple.component';
 
 @Component({
   selector: 'aspect-element-compound-group',
@@ -19,10 +23,12 @@ import { ValidatorService } from '../../services/validator.service';
 })
 export class ElementCompoundGroupComponent extends ElementFormGroupDirective implements OnInit {
   @ViewChild('elementComponent') elementComponent!: ElementComponent;
+  isKeyboardOpen!: boolean;
   ClozeElement!: ClozeElement;
   LikertElement!: LikertElement;
 
   constructor(
+    public keyboardService: KeyboardService,
     public unitStateService: UnitStateService,
     public unitStateElementMapperService: UnitStateElementMapperService,
     public translateService: TranslateService,
@@ -44,6 +50,24 @@ export class ElementCompoundGroupComponent extends ElementFormGroupDirective imp
     children.forEach(child => {
       const childModel = child.elementModel as InputElement;
       this.registerAtUnitStateService(childModel.id, childModel.value, child, this.pageIndex);
+      if (childModel.type === 'text-field') {
+        (child as TextFieldSimpleComponent)
+          .onFocusChanged.subscribe(element => this.onFocusChanged(element, child as TextFieldComponent));
+      }
     });
   }
+
+  onFocusChanged(focussedElement: HTMLElement | null, elementComponent: TextAreaComponent | TextFieldComponent): void {
+    if (focussedElement) {
+      const focussedInputElement = this.elementModel.type === 'text-area' ?
+        focussedElement as HTMLTextAreaElement :
+        focussedElement as HTMLInputElement;
+      const preset = (elementComponent.elementModel as TextFieldElement).inputAssistancePreset;
+      const position = (elementComponent.elementModel as TextFieldElement).inputAssistancePosition;
+      this.isKeyboardOpen = this.keyboardService
+        .openKeyboard(focussedInputElement, preset, position, elementComponent);
+    } else {
+      this.isKeyboardOpen = this.keyboardService.closeKeyboard();
+    }
+  }
 }
diff --git a/projects/player/src/app/components/element-text-input-group/element-text-input-group.component.html b/projects/player/src/app/components/element-text-input-group/element-text-input-group.component.html
index 8e451a2b56e06340bd5b53e88ba94e425c5fd2e9..f79fb974fdc6e56344889a819e61216d78a90b74 100644
--- a/projects/player/src/app/components/element-text-input-group/element-text-input-group.component.html
+++ b/projects/player/src/app/components/element-text-input-group/element-text-input-group.component.html
@@ -1,27 +1,25 @@
-<div class="inline-container" cdkOverlayOrigin #overlayOrigin="cdkOverlayOrigin">
-  <form [formGroup]="form">
-    <aspect-text-area
-        *ngIf="elementModel.type === 'text-area'"
-        #elementComponent
-        [parentForm]="form"
-        [elementModel]="elementModel | cast: TextAreaElement"
-        (onFocusChanged)="onFocusChanged($event, elementComponent)">
-    </aspect-text-area>
-    <aspect-text-field
-        *ngIf="elementModel.type === 'text-field'"
-        #elementComponent
-        [parentForm]="form"
-        [elementModel]="elementModel | cast: TextFieldElement"
-        (onFocusChanged)="onFocusChanged($event, elementComponent)">
-    </aspect-text-field>
-  </form>
-</div>
+<form class="inline-container"
+      [formGroup]="form">
+  <aspect-text-area
+      *ngIf="elementModel.type === 'text-area'"
+      #elementComponent
+      [parentForm]="form"
+      [elementModel]="elementModel | cast: TextAreaElement"
+      (onFocusChanged)="onFocusChanged($event, elementComponent)">
+  </aspect-text-area>
+  <aspect-text-field
+      *ngIf="elementModel.type === 'text-field'"
+      #elementComponent
+      [parentForm]="form"
+      [elementModel]="elementModel | cast: TextFieldElement"
+      (onFocusChanged)="onFocusChanged($event, elementComponent)">
+  </aspect-text-field>
+</form>
 
 <aspect-floating-keyboard
-    *ngIf="keyboardService.preset !== 'none' &&
-    (elementModel.type === 'text-area' || elementModel.type === 'text-field')"
+    *ngIf="keyboardService.preset !== 'none'"
     [isKeyboardOpen]="isKeyboardOpen && keyboardService.position === 'floating'"
-    [overlayOrigin]="overlayOrigin"
+    [overlayOrigin]="elementComponent"
     [inputElement]="keyboardService.inputElement"
     [position]="keyboardService.position"
     [preset]="keyboardService.preset"