diff --git a/Documentation/Installation.rst b/Documentation/Installation.rst
index 69632be84f0ae44386d16588020503940b2745fa..1ecf8164f7b152e36613e1bb7ce678a34244225c 100644
--- a/Documentation/Installation.rst
+++ b/Documentation/Installation.rst
@@ -266,14 +266,14 @@ Setup CSS & JS
         file11 = typo3conf/ext/qfq/Resources/Public/JavaScript/jquery.tablesorter.pager.min.js
         file12 = typo3conf/ext/qfq/Resources/Public/JavaScript/widget-columnSelector.min.js
         file13 = typo3conf/ext/qfq/Resources/Public/JavaScript/widget-output.min.js
-        file14 = typo3conf/ext/qfq/Resources/Public/JavaScript/bootstrap-datetimepicker.min.js
+        file14 = typo3conf/ext/qfq/Resources/Public/JavaScript/moment.min.js
+        file15 = typo3conf/ext/qfq/Resources/Public/JavaScript/bootstrap-datetimepicker.min.js
 
         # Only needed in case FormElement 'annotate' is used.
-        file15 = typo3conf/ext/qfq/Resources/Public/JavaScript/fabric.min.js
-        file16 = typo3conf/ext/qfq/Resources/Public/JavaScript/qfq.fabric.min.js
+        file16 = typo3conf/ext/qfq/Resources/Public/JavaScript/fabric.min.js
+        file17 = typo3conf/ext/qfq/Resources/Public/JavaScript/qfq.fabric.min.js
 
         # Only needed in case FullCalendar is used.
-        file17 = typo3conf/ext/qfq/Resources/Public/JavaScript/moment.min.js
         file18 = typo3conf/ext/qfq/Resources/Public/JavaScript/fullcalendar.min.js
 
     }
diff --git a/extension/Classes/Core/QuickFormQuery.php b/extension/Classes/Core/QuickFormQuery.php
index cf12b7d0210b1dfacd08e37b1cb285ff3d270b28..a76ecc9c548393e6085cb3ec2a9153fc997ea48e 100644
--- a/extension/Classes/Core/QuickFormQuery.php
+++ b/extension/Classes/Core/QuickFormQuery.php
@@ -1670,9 +1670,10 @@ class QuickFormQuery {
         $html = '';
 
         $beUserLoggedIn = $this->store->getVar(TYPO3_BE_USER, STORE_TYPO3, SANITIZE_ALLOW_ALNUMX);
+        $pageTitle = $this->store->getVar(TYPO3_PAGE_TITLE,STORE_TYPO3,SANITIZE_ALLOW_ALNUMX);
         if ($beUserLoggedIn && $this->inlineReport) {
             $html .= $this->buildInlineReport($this->t3data[T3DATA_UID] ?? null, $this->t3data[T3DATA_REPORT_PATH_FILENAME] ?? null,
-                $this->t3data[T3DATA_BODYTEXT_RAW] ?? '', $this->t3data[T3DATA_HEADER] ?? '');
+                $this->t3data[T3DATA_BODYTEXT_RAW] ?? '', $this->t3data[T3DATA_HEADER] ?? '', $pageTitle ?? '');
         }
         $html .= $report->process($this->t3data[T3DATA_BODYTEXT]);
 
@@ -1690,13 +1691,19 @@ class QuickFormQuery {
      * @throws \CodeException
      * @throws \UserFormException
      */
-    public static function buildInlineReport(?int $uid, ?string $reportPathFileNameFull, string $bodytext, string $header): string {
+    public static function buildInlineReport(?int $uid, ?string $reportPathFileNameFull, string $bodytext, string $header, string $pageTitle = ''): string {
         if ($uid === null) {
             return '';
         }
-        $icon = Support::renderGlyphIcon(GLYPH_ICON_TASKS);
+        $icon = Support::renderGlyphIcon(GLYPH_ICON_EDIT);
         $showFormJs = '$("#tt-content-edit-' . $uid . '").toggleClass("hidden")';
-        $toggleBtn = Support::wrapTag("<a href='#' onclick='$showFormJs' style='float:right;'>", $icon);
+        $toggleBtn = Support::wrapTag("<a href='#' class='targetEditReport btn-xs btn-info' onclick='$showFormJs' style='float:right;'>", $icon);
+
+        if($reportPathFileNameFull !== '' && $reportPathFileNameFull !== null){
+            $reportPathFileNameFullHtml = "<small>File: '$reportPathFileNameFull'</small>";
+        }else{
+            $reportPathFileNameFullHtml = '&nbsp;';
+        }
 
         $saveBtnAttributes = Support::doAttribute('class', 'btn btn-default') .
             Support::doAttribute('id', "tt-content-save-$uid") .
@@ -1705,14 +1712,17 @@ class QuickFormQuery {
             Support::doAttribute('title', 'Save & Reload');
         $saveBtnIcon = Support::renderGlyphIcon(GLYPH_ICON_CHECK);
         $saveBtn = Support::wrapTag("<button $saveBtnAttributes>", $saveBtnIcon);
-        $header = "QFQ Page Content '$header'.<br><small>File: '$reportPathFileNameFull'</small>";
-        $headerBar = Support::wrapTag("<div class='col-md-12 qfq-form-title'>", $header . $saveBtn);
+        $header = "Page: '$pageTitle' &nbsp; Content (ID): '$header ($uid)'<br>$reportPathFileNameFullHtml";
+        $headerBar = Support::wrapTag("<div class='col-md-12 qfq-form-title' style='position: sticky;top: 0;z-index: 1000;'>", $header . $saveBtn);
 
         $ttContentCode = Support::htmlEntityEncodeDecode(MODE_ENCODE, $bodytext);
-        $codeBoxAttributes = Support::doAttribute('style', "width:100%;") .
+
+        $json = json_encode(array('mode'=>'text/x-sql','lineNumbers'=>true,'lineWrapping'=>true), JSON_UNESCAPED_SLASHES);
+        $codeBoxAttributes =  Support::doAttribute('style', "width:100%;") .
             Support::doAttribute('id', "tt-content-code-$uid") .
-            Support::doAttribute('rows', 20) .
-            Support::doAttribute('name', REPORT_INLINE_BODYTEXT);
+            Support::doAttribute('name', REPORT_INLINE_BODYTEXT) .
+            Support::doAttribute('class', 'qfq-codemirror') .
+            Support::doAttribute('data-config', $json, true);
         $codeBox = Support::wrapTag("<textarea $codeBoxAttributes>", $ttContentCode);
 
         $form = join(' ', [$headerBar, $codeBox]);
diff --git a/extension/Classes/Core/Report/Link.php b/extension/Classes/Core/Report/Link.php
index f7085404819da19b0b3b703a031ab444c3d81207..46a3623e542544435cda91f0ae0092e9902bac07 100644
--- a/extension/Classes/Core/Report/Link.php
+++ b/extension/Classes/Core/Report/Link.php
@@ -82,7 +82,7 @@ use IMATHUZH\Qfq\Core\Store\Store;
  * x:Delete
  * X:
  * y:Copy to clipboard
- * Y:
+ * Y:   (Geplant in #11892 fuer 'order via tablesorter')
  * z:DropDown Menu
  * Z:
  *
diff --git a/extension/Classes/Core/Store/Config.php b/extension/Classes/Core/Store/Config.php
index 5bcf797f84eac085139ec1079883b311c08d3571..fce48c6b1062b220b2ab2968841ee9357ea7e11b 100644
--- a/extension/Classes/Core/Store/Config.php
+++ b/extension/Classes/Core/Store/Config.php
@@ -166,6 +166,7 @@ class Config {
         $absoluteConf = Path::absoluteConf();
         HelperFile::createPathRecursive($absoluteConf);
         HelperFile::file_put_contents(Path::join($absoluteConf, CONFIG_QFQ_JSON), json_encode($config, JSON_PRETTY_PRINT));
+        chmod(Path::join($absoluteConf, CONFIG_QFQ_JSON), 0640);
     }
 
     /**
diff --git a/javascript/src/Helper/codemirror.js b/javascript/src/Helper/codemirror.js
index bdbd068648305e475aa4dd2224c29a32f4bf60bf..eb7bec348d11ee778b9b2c716417a7b21bbe7471 100644
--- a/javascript/src/Helper/codemirror.js
+++ b/javascript/src/Helper/codemirror.js
@@ -64,4 +64,93 @@ QfqNS.Helper = QfqNS.Helper || {};
     n.codemirror = codemirror;
 
 
-})(QfqNS.Helper);
\ No newline at end of file
+})(QfqNS.Helper);
+
+// Seperate js to force codemirror for reports in frontend. No Form needed with this.
+$(document).ready(function(){
+    var externWindow = $(".externWindow");
+    var targetEditReportButton = $(".targetEditReport");
+    var htmlContent = $('');
+
+    // select all edit buttons from content records and remove onclick attribute to prevent showing content in primary window if clicked. onclick attribute is not removed in php to have the opportunity for old way of editing in front end.
+    if(targetEditReportButton !== undefined) {
+        for(var i = 0; targetEditReportButton.length > i; i++) {
+            var currentTarget = targetEditReportButton[i];
+            $(currentTarget).removeAttr("onclick");
+        }
+    }
+
+    // We prepare the content for extern window and show it. Only if onclick doesn't exist. Compatibility for old way is given this way.
+    $(targetEditReportButton).click(function() {
+        if(!$(this).is("[onclick]")){
+            var formContent = $($(this).next()[0].outerHTML);
+            showHtmlEditor(formContent);
+        }
+    });
+
+    //function to show editor window
+    function showHtmlEditor(formContent) {
+        $(formContent[0]).removeAttr("class");
+        $(formContent[0]).addClass("externWindow");
+        var idNameForWindow = $(formContent[0]).attr('id');
+        htmlContent = '<!DOCTYPE html>'+$("head").html() + $(formContent)[0].outerHTML;
+        newWindow(idNameForWindow);
+    }
+
+    // function to create new window with given content for editing
+    function newWindow(windowName) {
+        var w = window.open('//' + location.host + location.pathname + '?tt-content=' + windowName,windowName, 'width=900,height=700');
+        w.document.write(htmlContent);
+        w.document.close();
+    }
+
+    // Show same content editor with refreshed data again after save. Control it with the given get parameter. First fetch only needed html content again (form) and open it in same window.
+    var urlParams = new URLSearchParams(window.location.search);
+    var ttContentParam = urlParams.get('tt-content');
+
+    if(ttContentParam !== null && $(targetEditReportButton).next("#"+ttContentParam)[0] !== undefined){
+        var formContent = $($(targetEditReportButton).next("#"+ttContentParam)[0].outerHTML);
+       showHtmlEditor(formContent);
+    }
+
+    // execute changes(post) and reload page with id of tt-content as get parameter. Staying in same window with new content.
+    $(externWindow).submit(function() {
+        $.post($(externWindow).attr('action'),$(externWindow).serializeArray());
+        $('<span style="position:absolute; top:5px; right:5px; background-color: green;" class="badge badge-success">Saved</span>')
+            .insertBefore('.qfq-form-title>br')
+            .delay(3000)
+            .fadeOut(function() {
+                $(this).remove();
+            });
+        return false;
+    });
+
+    // enable CodeMirror for extern window
+    $(externWindow).children("[class=qfq-codemirror]").each(
+        function () {
+            var config = {};
+            var $this = $(this);
+            var configData = $this.data('config');
+            if (configData) {
+                if (configData instanceof Object) {
+                    // jQuery takes care of decoding data-config to JavaScript object.
+                    config = configData;
+                } else {
+                    QfqNS.Log.warning("'data-config' is invalid: " + configData);
+                }
+            }
+            var cm = CodeMirror.fromTextArea(this, configData);
+            cm.on('change', (function ($form, $textArea) {
+                return function (instance, changeObj) {
+                    $textArea.val(instance.getValue());
+                    $form.change();
+                };
+            })($(this).closest('form'), $this));
+            // This added class is needed to not fire the script more than once
+            $(this).addClass("cm-done");
+            // For the extern window we use the whole place to show CodeMirror
+            $(externWindow).css('height', '100%');
+            $(this).next().css('height','100%');
+        }
+    );
+});
\ No newline at end of file
diff --git a/javascript/src/QfqForm.js b/javascript/src/QfqForm.js
index 6f0a7e7384532700fb985fe2fdc07edc701f7ec0..9c523b77c66570f7c0782eb5a31235b539d5a252 100644
--- a/javascript/src/QfqForm.js
+++ b/javascript/src/QfqForm.js
@@ -1230,6 +1230,7 @@ var QfqNS = QfqNS || {};
      */
     n.QfqForm.prototype.applyFormConfiguration = function (configuration) {
         var arrayLength = configuration.length;
+        var countElementArray = 0;
         for (var i = 0; i < arrayLength; i++) {
             var configurationItem = configuration[i];
             var formElementName = configurationItem["form-element"];
@@ -1238,47 +1239,63 @@ var QfqNS = QfqNS || {};
                 continue;
             }
             try {
-                var element = n.Element.getElement(formElementName);
-
-                // Cleaner way to set states for tinymce
-                // This triggers the event on the unaccesable textarea
-                // The tinymce registers a listener on the textarea
-                // See helper/tinyMCE.js for details
-                if(element.$element.hasClass('qfq-tinymce')) {
-                    element.$element.trigger("blur", [configurationItem]);
-                }
+                var element = $('[name="' + QfqNS.escapeJqueryIdSelector(formElementName) + '"]:not([type="hidden"])');
+                // checkboxes without being in form groups aren't triggered over dynamic update, we need to handle them separately.
+                // for checkboxes with itemList (multiple) we need the countElementArray to trigger the right box
+                if($(element).attr('type') !== undefined){
+                    if($(element).attr('type').toLowerCase() ==='checkbox'){
+                        if(element.length > 1 && element.length !== countElementArray){
+                            element = element[countElementArray];
+                            countElementArray++;
+                        }
+                        if (configurationItem.value !== undefined) {
+                            $(element).prop('checked',configurationItem.value);
+                        }
+                    }
+                }else {
+                    // For all other form-elements the general script is used.
+                    element = n.Element.getElement(formElementName);
+                    // Cleaner way to set states for tinymce
+                    // This triggers the event on the unaccesable textarea
+                    // The tinymce registers a listener on the textarea
+                    // See helper/tinyMCE.js for details
+                    if (element.$element.hasClass('qfq-tinymce')) {
+                        element.$element.trigger("blur", [configurationItem]);
+                    }
 
-                if (configurationItem.value !== undefined) {
-                    element.setValue(configurationItem.value);
-                }
+                    if (configurationItem.value !== undefined) {
+                        element.setValue(configurationItem.value);
+                    }
 
-                if (configurationItem.readonly !== undefined) {
-                    // Readonly and disabled is the same in our domain
-                    element.setEnabled(!configurationItem.readonly);
-                }
+                    if (configurationItem.readonly !== undefined) {
+                        // Readonly and disabled is the same in our domain
+                        element.setEnabled(!configurationItem.readonly);
+                    }
 
-                if (configurationItem.disabled !== undefined) {
-                    // Readonly and disabled is the same in our domain
-                    element.setEnabled(!configurationItem.disabled);
-                }
+                    if (configurationItem.disabled !== undefined) {
+                        // Readonly and disabled is the same in our domain
+                        element.setEnabled(!configurationItem.disabled);
+                    }
 
-                if (configurationItem.hidden !== undefined) {
-                    element.setHidden(configurationItem.hidden);
-                }
+                    if (configurationItem.hidden !== undefined) {
+                        element.setHidden(configurationItem.hidden);
+                    }
 
-                if (configurationItem.required !== undefined) {
-                    element.setRequired(configuration.required);
-                    if(element.$element) {
-                        if(element.$element.is("select")) {
-                            element.$element.prop('required', configurationItem.required);
-                            element.$element.attr('data-required', 'yes');
-                        }
-                        if(element.$element.is("input[type=hidden]")) {
-                            console.log("Update Hidden");
-                            element.$element.prop("required", configurationItem.required);
-                        }
+                    if (configurationItem.required !== undefined) {
+                        element.setRequired(configuration.required);
+                        if (element.$element) {
+                            if (element.$element.is("select")) {
+                                element.$element.prop('required', configurationItem.required);
+                                element.$element.attr('data-required', 'yes');
+                            }
+                            if (element.$element.is("input[type=hidden]")) {
+                                console.log("Update Hidden");
+                                element.$element.prop("required", configurationItem.required);
+                            }
 
+                        }
                     }
+                    countElementArray = 0;
                 }
             } catch (e) {
                 n.Log.error(e.message);
diff --git a/less/qfq-bs.css.less b/less/qfq-bs.css.less
index 8b68d78db99f420a71dd9bdd644151d568ba92c1..6f75567dc2074810fde7a15e1065067dccdf41ba 100644
--- a/less/qfq-bs.css.less
+++ b/less/qfq-bs.css.less
@@ -271,8 +271,8 @@ i.@{spinner_class} {
   transition: opacity 1s linear, max-height 0.25s ease-out; */
 }
 
-
-.form-group.has-error .btn {
+/* all anchors in form-group divs can only be created by users using #!report in forms. These anchors without a target href (#) like some elements which use js functions (example datetimepicker) dont need to be marked as required.*/
+.form-group.has-error .btn:not(a[href="#"]) {
   background-color: #f0ad4e;
   background-image: linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);
   background-repeat: repeat-x;
@@ -1355,4 +1355,9 @@ thead.qfq-sticky td {
 
 input.qfq-password {
   font-family: 'password';
+}
+
+/* bootstrap correction for better looking arrows in datetimepicker */
+[data-action="decrementHours"]>span.glyphicon-chevron-down, [data-action="incrementHours"]>span.glyphicon-chevron-up, [data-action="incrementMinutes"]>span.glyphicon-chevron-up, [data-action="decrementMinutes"]>span.glyphicon-chevron-down {
+  top: -19px;
 }
\ No newline at end of file