Skip to content

Commit 4714b00

Browse files
authored
Merge pull request #97 from systopia/ensure-calculated-values-on-initial-load
Ensure calculated values are set on initial load
2 parents 300f0ae + 2748cc0 commit 4714b00

File tree

5 files changed

+72
-3
lines changed

5 files changed

+72
-3
lines changed

js/initial-calculation.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (C) 2025 SYSTOPIA GmbH
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
/**
19+
* Performs a calculation when a form is initially loaded.
20+
*/
21+
(function (Drupal, once) {
22+
Drupal.behaviors.json_forms_initial_calculation = {
23+
attach: function (context, settings) {
24+
once('json-forms-initial-calculation', '[data-json-forms-init-calculation="1"]', context).forEach((element) => {
25+
// Trigger a "change" event which results in an AJAX call that performs the calculations.
26+
element.dispatchEvent(new Event('change'));
27+
});
28+
}
29+
};
30+
31+
})(Drupal, once);

json_forms.libraries.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ disable_buttons_on_ajax:
1616
dependencies:
1717
- core/jquery
1818

19+
initial_calculation:
20+
version: 0.1.0
21+
js:
22+
js/initial-calculation.js: {}
23+
dependencies:
24+
- core/drupal
25+
- core/once
26+
1927
number_input:
2028
version: 0.1.0
2129
js:

src/Form/AbstractJsonFormsForm.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,17 @@ protected function buildJsonFormsForm(
130130
$form['#attached']['library'][] = 'json_forms/disable_buttons_on_ajax';
131131
$form['#attached']['library'][] = 'json_forms/vertical_tabs';
132132

133+
if (!$formState->isCached()) {
134+
if (TRUE === $formState->get('$calculateUsed')) {
135+
$form['#attached']['library'][] = 'json_forms/initial_calculation';
136+
}
137+
138+
// Drupal prevents caching on safe methods.
139+
if (!$this->getRequest()->isMethodSafe()) {
140+
$formState->setCached();
141+
}
142+
}
143+
133144
return $form;
134145
}
135146

src/Form/Control/SubmitButtonArrayFactory.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,9 @@ public function createFormArray(
6363
// Override value set in BasicFormPropertiesFactory.
6464
'#limit_validation_errors' => NULL,
6565
'#_data' => $definition->getOptionsValue('data'),
66-
'#attributes' => ['class' => ['json-forms-submit']],
6766
] + BasicFormPropertiesFactory::createFieldProperties($definition, $formState);
67+
// @phpstan-ignore-next-line
68+
$form['#attributes']['class'][] = 'json-forms-submit';
6869

6970
if (NULL !== $definition->getOptionsValue('confirm')) {
7071
// @phpstan-ignore-next-line

src/Form/Control/Util/BasicFormPropertiesFactory.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,27 @@ public static function createBasicProperties(ControlDefinition $definition): arr
7474
* Creates attributes for properties in Drupal FormElement for a Control.
7575
*
7676
* @phpstan-return array<string, mixed>
77+
*
78+
* phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
7779
*/
7880
public static function createFieldProperties(ControlDefinition $definition, FormStateInterface $formState): array {
81+
// phpcs:enable
7982
$form = [
8083
'#disabled' => $definition->isReadOnly(),
8184
'#required' => $definition->isRequired(),
8285
'#limit_validation_errors' => [],
8386
'#_nullable' => $definition->isNullable(),
8487
];
8588

89+
$calcInitField = FALSE;
90+
if ($definition->isCalculated()) {
91+
$formState->set('$calculateUsed', TRUE);
92+
}
93+
elseif (!$formState->has('$hasCalcInitField')) {
94+
$formState->set('$hasCalcInitField', TRUE);
95+
$calcInitField = TRUE;
96+
}
97+
8698
$readOnlyValuePath = array_merge(['readOnlyValues'], $definition->getPropertyPath());
8799
if ((!$formState->isCached() || $definition->isReadOnly())
88100
&& $formState->hasTemporaryValue($definition->getPropertyPath())
@@ -112,7 +124,7 @@ public static function createFieldProperties(ControlDefinition $definition, Form
112124
$form['#value'] = $definition->getConst();
113125
}
114126

115-
if (!$form['#disabled'] && TRUE === $formState->get('recalculateOnChange')) {
127+
if ((!$form['#disabled'] && TRUE === $formState->get('recalculateOnChange')) || $calcInitField) {
116128
$form['#ajax'] = [
117129
'callback' => RecalculateCallback::class . '::onChange',
118130
'event' => 'change',
@@ -121,7 +133,13 @@ public static function createFieldProperties(ControlDefinition $definition, Form
121133
];
122134
}
123135

124-
return array_merge(static::createBasicProperties($definition), $form);
136+
$form += static::createBasicProperties($definition);
137+
if ($calcInitField) {
138+
// @phpstan-ignore offsetAccess.nonOffsetAccessible
139+
$form['#attributes']['data-json-forms-init-calculation'] = '1';
140+
}
141+
142+
return $form;
125143
}
126144

127145
}

0 commit comments

Comments
 (0)