diff --git a/projects/common/models/page.ts b/projects/common/models/page.ts
index a4321c6f82129896741eb66843f417937401746c..b7c3345fa07fddce5d2db1c8e7f19339c20c8b23 100644
--- a/projects/common/models/page.ts
+++ b/projects/common/models/page.ts
@@ -1,7 +1,7 @@
 import { Section } from './section';
 import { moveArrayItem } from '../util/array';
 import { UIElement } from './uI-element';
-import { IdService } from '../id.service';
+import { IdService } from '../../editor/src/app/services/id.service';
 
 export class Page {
   [index: string]: string | number | boolean | Section[] | undefined | ((...args: any) => any);
@@ -41,15 +41,6 @@ export class Page {
     );
   }
 
-  /** Create new section with old section elements are overwrite the ids. */
-  duplicateSection(section: Section, sectionIndex: number): void {
-    const newSection = new Section(section);
-    newSection.elements.forEach((element: UIElement) => {
-      element.id = IdService.getInstance().getNewID(element.type);
-    });
-    this.sections.splice(sectionIndex + 1, 0, newSection);
-  }
-
   moveSection(section: Section, direction: 'up' | 'down'): void {
     moveArrayItem(section, this.sections, direction);
   }
diff --git a/projects/common/models/uI-element.ts b/projects/common/models/uI-element.ts
index 302257af0a299f430a29d97fe33c223871c77cd3..5a05bfbf6d95a3d349c05894aa322360c79ef23a 100644
--- a/projects/common/models/uI-element.ts
+++ b/projects/common/models/uI-element.ts
@@ -1,6 +1,4 @@
 // eslint-disable-next-line max-classes-per-file
-import { IdService } from '../id.service';
-
 export type UIElementType = 'text' | 'button' | 'text-field' | 'text-area' | 'checkbox'
 | 'dropdown' | 'radio' | 'image' | 'audio' | 'video' | 'likert' | 'likert_row' | 'radio-group-images'
 | 'drop-list' | 'cloze' | 'spell-correct' | 'slider' | 'frame' | 'toggle-button';
@@ -27,10 +25,6 @@ export abstract class UIElement {
 
   protected constructor(serializedElement: Partial<UIElement>) {
     Object.assign(this, serializedElement);
-    if (!serializedElement.id) {
-      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      this.id = IdService.getInstance().getNewID(serializedElement.type!);
-    }
   }
 
   getProperty(property: string): any {
@@ -51,7 +45,8 @@ export abstract class UIElement {
 
   // This can be overwritten by elements if they need to handle some property specifics. Likert does.
   setProperty(property: string,
-              value: InputElementValue | LikertColumn[] | LikertRow[] | DragNDropValueObject[]): void {
+              value: InputElementValue | LikertColumn[] | LikertRow[] |
+              DragNDropValueObject[] | ClozePart[][]): void {
     if (this.fontProps && property in this.fontProps) {
       this.fontProps[property] = value as string | number | boolean;
     } else if (this.surfaceProps && property in this.surfaceProps) {
@@ -176,3 +171,9 @@ export interface LikertRow {
   text: string;
   columnCount: number;
 }
+
+export type ClozePart = {
+  type: string;
+  value: string | UIElement;
+  style?: string;
+};
diff --git a/projects/common/ui-elements/cloze/cloze-element.ts b/projects/common/ui-elements/cloze/cloze-element.ts
index c005d215555e790545fc27e288bfc4a6fec8ccf2..a60430429769e2feaeeac56ee046cb2ed2ed84c1 100644
--- a/projects/common/ui-elements/cloze/cloze-element.ts
+++ b/projects/common/ui-elements/cloze/cloze-element.ts
@@ -1,33 +1,17 @@
 import {
+  ClozePart,
   CompoundElement,
   FontElement,
   FontProperties,
-  InputElement,
-  InputElementValue,
-  LikertColumn,
-  LikertRow,
   PositionedElement, PositionProperties,
   UIElement
 } from '../../models/uI-element';
-import { TextFieldElement } from '../text-field/text-field-element';
-import { TextAreaElement } from '../text-area/text-area-element';
-import { CheckboxElement } from '../checkbox/checkbox-element';
-import { DropdownElement } from '../dropdown/dropdown-element';
 import { initFontElement, initPositionedElement } from '../../util/unit-interface-initializer';
-import { TextFieldSimpleElement } from '../textfield-simple/text-field-simple-element';
-import { DropListSimpleElement } from '../drop-list-simple/drop-list-simple';
-import { ToggleButtonElement } from '../toggle-button/toggle-button';
 
 // TODO styles like em dont continue after inserted components
 
-export type ClozePart = {
-  type: string;
-  value: string | UIElement;
-  style?: string;
-};
-
 export class ClozeElement extends CompoundElement implements PositionedElement, FontElement {
-  text: string = '<p>Lorem ipsum dolor \\r sdfsdf \\i sdfsdf</p>';
+  text: string = 'Lorem ipsum dolor \\r sdfsdf \\i sdfsdf';
   parts: ClozePart[][] = [];
 
   positionProps: PositionProperties;
@@ -43,7 +27,7 @@ export class ClozeElement extends CompoundElement implements PositionedElement,
       serializedElement?.parts.forEach((subParts: ClozePart[]) => {
         subParts.forEach((part: ClozePart) => {
           if (!['p', 'h1', 'h2', 'h3', 'h4'].includes(part.type)) {
-            part.value = ClozeElement.createElement(part.value as UIElement);
+            part.value = this.createElement(part.value as UIElement);
           }
         });
       });
@@ -52,112 +36,4 @@ export class ClozeElement extends CompoundElement implements PositionedElement,
     this.width = serializedElement.width || 450;
     this.height = serializedElement.height || 200;
   }
-
-  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 elementList = ClozeElement.readElementArray(htmlText);
-
-    this.parts = [];
-    elementList.forEach((element: HTMLParagraphElement | HTMLHeadingElement, i: number) => {
-      this.parseParagraphs(element, i);
-    });
-    // console.log('PARTS:', this.parts);
-  }
-
-  private static readElementArray(htmlText: string): (HTMLParagraphElement | HTMLHeadingElement)[] {
-    const el = document.createElement('html');
-    el.innerHTML = htmlText;
-    return Array.from(el.children[1].children) as (HTMLParagraphElement | HTMLHeadingElement)[];
-  }
-
-  private parseParagraphs(element: HTMLParagraphElement | HTMLHeadingElement, partIndex: number): void {
-    this.parts[partIndex] = []; // init array to be able to push
-    let [nextSpecialElementIndex, nextElementType] = ClozeElement.getNextSpecialElement(element.innerHTML);
-    let indexOffset = 0;
-
-    while (nextSpecialElementIndex !== -1) {
-      nextSpecialElementIndex += indexOffset;
-      this.parts[partIndex].push({
-        type: element.localName,
-        value: element.innerHTML.substring(indexOffset, nextSpecialElementIndex),
-        style: element.style.cssText
-      });
-
-      const newElement = ClozeElement.createElement({ type: nextElementType } as UIElement);
-      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(element.innerHTML.substring(indexOffset));
-    }
-    this.parts[partIndex].push({
-      type: element.localName,
-      value: element.innerHTML.substring(indexOffset),
-      style: element.style.cssText
-    });
-  }
-
-  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'));
-    }
-    if (p.indexOf('\\r') > 0) {
-      x.push(p.indexOf('\\r'));
-    }
-
-    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;
-      case 'r': nextElementType = 'toggle-button'; break;
-      default: return [-1, 'unknown'];
-    }
-    return [y, nextElementType];
-  }
-
-  private static createElement(elementModel: UIElement): InputElement {
-    let newElement: InputElement;
-    switch (elementModel.type) {
-      case 'text-field':
-        newElement = new TextFieldSimpleElement(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 DropListSimpleElement(elementModel);
-        newElement.height = 25;
-        newElement.width = 100;
-        break;
-      case 'toggle-button':
-        newElement = new ToggleButtonElement(elementModel);
-        break;
-      default:
-        throw new Error(`ElementType ${elementModel.type} not found!`);
-    }
-    return newElement;
-  }
 }
diff --git a/projects/common/ui-elements/cloze/cloze.component.ts b/projects/common/ui-elements/cloze/cloze.component.ts
index 6268dbdd0aeb55717886aa498314555534ccff3f..427cc4d94326fe87d3778aac7abdc6477e837023 100644
--- a/projects/common/ui-elements/cloze/cloze.component.ts
+++ b/projects/common/ui-elements/cloze/cloze.component.ts
@@ -1,9 +1,9 @@
 import {
   Component, EventEmitter, Output, QueryList, ViewChildren
 } from '@angular/core';
-import { ClozeElement, ClozePart } from './cloze-element';
+import { ClozeElement } from './cloze-element';
 import { CompoundElementComponent } from '../../directives/compound-element.directive';
-import { InputElement } from '../../models/uI-element';
+import { InputElement, ClozePart } from '../../models/uI-element';
 import { FormElementComponent } from '../../directives/form-element-component.directive';
 
 @Component({
diff --git a/projects/common/ui-elements/drop-list/drop-list.ts b/projects/common/ui-elements/drop-list/drop-list.ts
index 02ced635fe4124d2136ef4e76ef9523c06203c77..8096efeeb35958f49a719cd18b651be295b6bb8e 100644
--- a/projects/common/ui-elements/drop-list/drop-list.ts
+++ b/projects/common/ui-elements/drop-list/drop-list.ts
@@ -9,7 +9,6 @@ import {
   UIElement
 } from '../../models/uI-element';
 import { initFontElement, initPositionedElement, initSurfaceElement } from '../../util/unit-interface-initializer';
-import { IdService } from '../../id.service';
 
 export class DropListElement extends InputElement implements PositionedElement, FontElement, SurfaceElement {
   onlyOneItem: boolean = false;
@@ -54,9 +53,9 @@ export class DropListElement extends InputElement implements PositionedElement,
     }
     if (oldValues.length > 0) {
       this.value = [];
-      oldValues.forEach((stringValue: string) => {
+      oldValues.forEach((stringValue: string, i: number) => {
         (this.value as DragNDropValueObject[]).push({
-          id: IdService.getInstance().getNewID('value'),
+          id: `${this.id}_value_${i}`,
           stringValue: stringValue
         });
       });
diff --git a/projects/common/id.service.ts b/projects/editor/src/app/services/id.service.ts
similarity index 100%
rename from projects/common/id.service.ts
rename to projects/editor/src/app/services/id.service.ts
diff --git a/projects/editor/src/app/services/unit.service.ts b/projects/editor/src/app/services/unit.service.ts
index 334a599a435454a24d3efe684f16fe14e575942e..2cc4b24323e549b9c1e9add10efd9785d3b2e8cf 100644
--- a/projects/editor/src/app/services/unit.service.ts
+++ b/projects/editor/src/app/services/unit.service.ts
@@ -4,7 +4,7 @@ import { BehaviorSubject, Observable, Subject } from 'rxjs';
 import { TranslateService } from '@ngx-translate/core';
 import { FileService } from './file.service';
 import { MessageService } from '../../../../common/services/message.service';
-import { IdService } from '../../../../common/id.service';
+import { IdService } from './id.service';
 import { DialogService } from './dialog.service';
 import { VeronaAPIService } from './verona-api.service';
 import { Unit } from '../../../../common/models/unit';
@@ -24,6 +24,7 @@ import { LikertElement } from '../../../../common/ui-elements/likert/likert-elem
 import { LikertElementRow } from '../../../../common/ui-elements/likert/likert-element-row';
 import { SelectionService } from './selection.service';
 import * as ElementFactory from '../../../../common/util/element.factory';
+import { ClozeParser } from '../util/cloze-parser';
 
 @Injectable({
   providedIn: 'root'
@@ -122,7 +123,12 @@ export class UnitService {
   }
 
   duplicateSection(section: Section, page: Page, sectionIndex: number): void {
-    page.duplicateSection(section, sectionIndex);
+    const newSection = new Section(section);
+    newSection.elements.forEach((element: UIElement) => {
+      element.id = IdService.getInstance().getNewID(element.type);
+    });
+    page.sections.splice(sectionIndex + 1, 0, newSection);
+
     this._unit.next(this._unit.value);
     this.veronaApiService.sendVoeDefinitionChangedNotification();
   }
@@ -159,6 +165,7 @@ export class UnitService {
       }
       newElement = ElementFactory.createElement({
         type: elementType,
+        id: IdService.getInstance().getNewID(elementType),
         src: mediaSrc,
         positionProps: {
           dynamicPositioning: section.dynamicPositioning
@@ -167,6 +174,7 @@ export class UnitService {
     } else {
       newElement = ElementFactory.createElement({
         type: elementType,
+        id: IdService.getInstance().getNewID(elementType),
         positionProps: {
           dynamicPositioning: section.dynamicPositioning
         }
@@ -245,8 +253,11 @@ export class UnitService {
         }
         IdService.getInstance().removeId(element.id);
         IdService.getInstance().addId(<string>value);
+      } else if (property === 'text' && element.type === 'cloze') {
+        element.setProperty('parts', ClozeParser.parse(value as string, IdService.getInstance()));
+      } else {
+        element.setProperty(property, value);
       }
-      element.setProperty(property, value);
     }
     this.elementPropertyUpdated.next();
     this.veronaApiService.sendVoeDefinitionChangedNotification();
@@ -334,6 +345,7 @@ export class UnitService {
     return new LikertElementRow(
       {
         type: 'likert_row',
+        id: IdService.getInstance().getNewID('likert_row'),
         text: question,
         columnCount: columnCount
       } as LikertElementRow
diff --git a/projects/editor/src/app/util/cloze-parser.ts b/projects/editor/src/app/util/cloze-parser.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3899137fdaf765a7931a90079de0ece3823d0df1
--- /dev/null
+++ b/projects/editor/src/app/util/cloze-parser.ts
@@ -0,0 +1,120 @@
+import { InputElement, UIElement, ClozePart } from '../../../../common/models/uI-element';
+import { TextFieldSimpleElement } from '../../../../common/ui-elements/textfield-simple/text-field-simple-element';
+import { TextFieldElement } from '../../../../common/ui-elements/text-field/text-field-element';
+import { TextAreaElement } from '../../../../common/ui-elements/text-area/text-area-element';
+import { CheckboxElement } from '../../../../common/ui-elements/checkbox/checkbox-element';
+import { DropdownElement } from '../../../../common/ui-elements/dropdown/dropdown-element';
+import { DropListSimpleElement } from '../../../../common/ui-elements/drop-list-simple/drop-list-simple';
+import { ToggleButtonElement } from '../../../../common/ui-elements/toggle-button/toggle-button';
+import { IdService } from '../services/id.service';
+
+export abstract class ClozeParser {
+  static parse(text: string, idService: IdService): ClozePart[][] {
+    return ClozeParser.createParts(text, idService);
+  }
+
+  private static createParts(htmlText: string, idService: IdService): ClozePart[][] {
+    const elementList = ClozeParser.readElementArray(htmlText);
+
+    const parts: ClozePart[][] = [];
+    elementList.forEach((element: HTMLParagraphElement | HTMLHeadingElement, i: number) => {
+      ClozeParser.parseParagraphs(element, i, parts, idService);
+    });
+    return parts;
+  }
+
+  private static readElementArray(htmlText: string): (HTMLParagraphElement | HTMLHeadingElement)[] {
+    const el = document.createElement('html');
+    el.innerHTML = htmlText;
+    return Array.from(el.children[1].children) as (HTMLParagraphElement | HTMLHeadingElement)[];
+  }
+
+  // TODO refactor passed parts, so the Part is returned instead if manipulating the param array
+  private static parseParagraphs(
+    element: HTMLParagraphElement | HTMLHeadingElement, partIndex: number, parts: ClozePart[][], idService: IdService
+  ): ClozePart[][] {
+    parts[partIndex] = [];
+    let [nextSpecialElementIndex, nextElementType] = ClozeParser.getNextSpecialElement(element.innerHTML);
+    let indexOffset = 0;
+
+    while (nextSpecialElementIndex !== -1) {
+      nextSpecialElementIndex += indexOffset;
+      parts[partIndex].push({
+        type: element.localName,
+        value: element.innerHTML.substring(indexOffset, nextSpecialElementIndex),
+        style: element.style.cssText
+      });
+
+      const newElement = ClozeParser.createElement({ type: nextElementType } as UIElement, idService);
+      parts[partIndex].push({ type: nextElementType, value: newElement });
+
+      indexOffset = nextSpecialElementIndex + 2; // + 2 to get rid of the marker, i.e. '\b'
+      [nextSpecialElementIndex, nextElementType] =
+        ClozeParser.getNextSpecialElement(element.innerHTML.substring(indexOffset));
+    }
+    parts[partIndex].push({
+      type: element.localName,
+      value: element.innerHTML.substring(indexOffset),
+      style: element.style.cssText
+    });
+    return parts;
+  }
+
+  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'));
+    }
+    if (p.indexOf('\\r') > 0) {
+      x.push(p.indexOf('\\r'));
+    }
+
+    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;
+      case 'r': nextElementType = 'toggle-button'; break;
+      default: return [-1, 'unknown'];
+    }
+    return [y, nextElementType];
+  }
+
+  private static createElement(elementModel: Partial<UIElement>, idService: IdService): InputElement {
+    let newElement: InputElement;
+    elementModel.id = idService.getNewID(elementModel.type as string);
+    switch (elementModel.type) {
+      case 'text-field':
+        newElement = new TextFieldSimpleElement(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 DropListSimpleElement(elementModel);
+        newElement.height = 25;
+        newElement.width = 100;
+        break;
+      case 'toggle-button':
+        newElement = new ToggleButtonElement(elementModel);
+        break;
+      default:
+        throw new Error(`ElementType ${elementModel.type} not found!`);
+    }
+    return newElement;
+  }
+}