From cb0d4629d8c45539ee1d0fee25905a501532a0ea Mon Sep 17 00:00:00 2001
From: Andreas Fernandez <a.fernandez@scripting-base.de>
Date: Sun, 10 May 2020 15:36:54 +0200
Subject: [PATCH] [BUGFIX] Set changed state of FormEngine when null
 placeholder fields are changed

When a null placeholder checkbox is changed, the linked form field is
now marked as "changed", which triggers the confirmation when leaving
the form while being unsaved.

Resolves: #91351
Releases: master, 9.5
Change-Id: I1b3ac08223a4a4c588a980abe70f22ff9814b13f
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/64444
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Josef Glatz <josefglatz@gmail.com>
Tested-by: Xavier Perseguers <xavier@typo3.org>
Tested-by: Susanne Moog <look@susi.dev>
Reviewed-by: Josef Glatz <josefglatz@gmail.com>
Reviewed-by: Xavier Perseguers <xavier@typo3.org>
Reviewed-by: Susanne Moog <look@susi.dev>
---
 .../Resources/Public/JavaScript/FormEngine.js |  1 +
 .../FormEngine/NullPlaceholderCest.php        | 86 +++++++++++++++++++
 2 files changed, 87 insertions(+)
 create mode 100644 typo3/sysext/core/Tests/Acceptance/Backend/FormEngine/NullPlaceholderCest.php

diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine.js b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine.js
index 0fdfcd797d40..591510480e97 100644
--- a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine.js
+++ b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine.js
@@ -586,6 +586,7 @@ define(['jquery',
       $(this).closest('.t3js-formengine-field-item').toggleClass('disabled');
     }).on('change', '.t3js-form-field-eval-null-placeholder-checkbox input[type="checkbox"]', function(e) {
       FormEngine.toggleCheckboxField($(this));
+      FormEngineValidation.markFieldAsChanged($(this));
     }).on('change', function(event) {
       $('.module-docheader-bar .btn').removeClass('disabled').prop('disabled', false);
     }).on('click', '.t3js-element-browser', function(e) {
diff --git a/typo3/sysext/core/Tests/Acceptance/Backend/FormEngine/NullPlaceholderCest.php b/typo3/sysext/core/Tests/Acceptance/Backend/FormEngine/NullPlaceholderCest.php
new file mode 100644
index 000000000000..a09d69997129
--- /dev/null
+++ b/typo3/sysext/core/Tests/Acceptance/Backend/FormEngine/NullPlaceholderCest.php
@@ -0,0 +1,86 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Core\Tests\Acceptance\Backend\FormEngine;
+
+use TYPO3\CMS\Core\Tests\Acceptance\Support\BackendTester;
+use TYPO3\CMS\Core\Tests\Acceptance\Support\Helper\PageTree;
+
+/**
+ * Tests for IRRE null placeholder fields
+ */
+class NullPlaceholderCest
+{
+    /**
+     * Call backend and open list module
+     *
+     * @param BackendTester $I
+     * @param PageTree $pageTree
+     */
+    public function _before(BackendTester $I, PageTree $pageTree)
+    {
+        $I->useExistingSession('admin');
+        $this->goToListModule($I, $pageTree);
+    }
+
+    /**
+     * This scenario tests whether activating a null placeholder checkbox marks its state as "changed"
+     *
+     * @param BackendTester $I
+     * @throws \Exception
+     */
+    public function checkIfDeactivatingNullCheckboxesMarksAsChanged(BackendTester $I): void
+    {
+        $I->amGoingTo('Check if deactivating null checkboxes marks as "changed"');
+
+        $editRecordLinkCssPath = '#recordlist-tx_styleguide_inline_fal a[data-original-title="Edit record"]';
+        $I->click($editRecordLinkCssPath);
+
+        $I->waitForElementNotVisible('#t3js-ui-block');
+        $I->waitForText('Edit Form engine - inline fal "1" on page "inline fal"');
+        $I->click('typical fal');
+        $I->click('.form-irre-header');
+        $I->waitForElementNotVisible('.nprogress-custom-parent');
+
+        $I->amGoingTo('enable checkboxes and see whether the fields get marked as changed');
+        foreach (['title', 'alternative', 'description'] as $fieldName) {
+            $currentCheckboxSelector = '//input[contains(@name, "[' . $fieldName . ']") and @type="checkbox" and contains(@name, "control[active][sys_file_reference]")]';
+            $I->checkOption($currentCheckboxSelector);
+            $I->seeElement($currentCheckboxSelector . '/./ancestor::div[contains(concat(\' \', @class, \' \'), \'has-change\')]');
+
+            // Remove focus from field, otherwise codeception can't find other checkboxes
+            $I->click('.form-irre-object .form-section');
+        }
+    }
+
+    /**
+     * Open list module
+     *
+     * @param BackendTester $I
+     * @param PageTree $pageTree
+     * @throws \Exception
+     */
+    private function goToListModule(BackendTester $I, PageTree $pageTree)
+    {
+        $I->switchToMainFrame();
+        $I->click('List');
+        $I->waitForElement('svg .nodes .node');
+        $pageTree->openPath(['styleguide TCA demo', 'inline fal']);
+        $I->switchToContentFrame();
+        $I->waitForText('inline fal');
+    }
+}
-- 
GitLab