Skip to content

Conversation

@coolcat-creations
Copy link
Contributor

@coolcat-creations coolcat-creations commented Nov 24, 2025

This pull request fixes an issue in Joomla’s showon implementation where dependent fields are always shown, even when the referenced source field does not exist in the DOM.
This “fail-open” behaviour can lead to incorrect form states, invalid UI logic, and unintended visibility of fields.

Problem
Currently, if a field contains something like:
showon="nonexistent_field:1"

and nonexistent_field is not present in the form:

  1. Joomla does not register any origin fields,
  2. no event listeners are attached,
  3. and the dependent field is shown by default.

This is counter-intuitive and causes issues especially in:

  1. Custom Fields, when a controlling field is deleted or renamed
  2. Complex XML forms, especially in components or modules using conditional configurations
  3. Subforms, where dynamic names change and conditions may temporarily point to a non-existing field

This behaviour is likely an oversight rather than an intentional feature.

Expected Behaviour

If the source field defined in showon does not exist, then the condition cannot be fulfilled, therefore the dependent field should be hidden by default.

Solution

This PR adds a simple and safe check in Showon (build/media_source/system/js/showon.es6.js):

After collecting all origin fields for a given showon condition:

if origin.length === 0,
→ the dependent field is immediately hidden,
→ and the joomla:showon-hide event is fired.

This changes the behaviour to Fail closed instead of fail open
(a missing condition hides a field rather than incorrectly showing it)

The fix does not modify the data structure, PHP FormHelper logic, or any API and is fully backward compatible unless someone relied on the previous incorrect behaviour (unlikely).

How to Test

Please test both Custom Fields and standard XML JForm definitions.

1. Test Using Custom Fields

A) Prepare the fields

Go to:
Content → Fields

Create a field:

Field A:

Type: List
Name: controller
Options

List values | Text* | Value |
___________ | Yes _ | 1 |
___________ | No _ | 0 |

Create another field:

Field B:

Type: Text
Name: dependent
Showon: controller:1

B) Test the normal behaviour

Edit an article.

Set “Controller” to "Yes" → Field B should appear.
Set “Controller” to "No" → Field B should hide.

C) Test the missing-source behaviour

Unpublish or Delete Field A (the controller field)

Open the article again.

Expected result after applying the PR:

“Dependent” field is hidden by default

No JS errors occur

Switching values of other fields does not accidentally reveal it

Current behaviour (before PR):

Field B is incorrectly visible.

2. Test Using XML Form Definitions

A) Create a simple XML form (administrator or component)

Example snippet: <field name="dependent" type="text" label="Dependent Field" showon="nonexistent:1" />

B) Load the form in the backend (module, component, plugin etc.)
Expected result after PR:

The “dependent” field is hidden because the source field does not exist.

Current behaviour:

The field is incorrectly shown.

  1. Test With Multiple Conditions

showon="controller:1[AND]nonexistent:2"

Expected after PR:

Even if controller exists, the missing nonexistent should invalidate the entire condition, hiding the field.

Backward Compatibility
This change should not break valid configurations.
The only difference occurs when showon references a field that:

does not exist,
was renamed,
was deleted,

or is dynamically removed in subforms.

In these cases the new behaviour is more correct and prevents accidental visibility.

This PR makes the showon behaviour more predictable, safer, and consistent by hiding dependent fields when the source field is missing — a long-standing edge case that often leads to incorrect UI states.

@joomla-cms-bot joomla-cms-bot added NPM Resource Changed This Pull Request can't be tested by Patchtester PR-5.4-dev labels Nov 24, 2025
@chmst
Copy link
Contributor

chmst commented Nov 24, 2025

Does this respect the [AND] and [OR] Operators?

@coolcat-creations
Copy link
Contributor Author

coolcat-creations commented Nov 24, 2025

Yes, when the second condition is not applicable, the field is hidden. ( I described it in the test instructions)

@HLeithner HLeithner changed the title Fix: Showon fails open when source field does not exist (hidden by default instead) [5.4] Fix: Showon fails open when source field does not exist (hidden by default instead) Nov 24, 2025
@richard67 richard67 added the bug label Nov 25, 2025
@ThomasFinnern
Copy link
Contributor

1. Test Using Custom Fields
...
Options: Yes=1, No=0
=> The option description can be improved.

Add two lines in "List Values" like blow

List values | Text* | Value |
___________ | Yes _ | 1 |
___________ | No _ | 0 |


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/46488.

@coolcat-creations
Copy link
Contributor Author

@ThomasFinnern changed, thank you - did you test it?

@ThomasFinnern
Copy link
Contributor

I tried to get there but failed due to lack of my test knowledge.
I exchanged the file in build/... and used npm ci. but the result in fileds was the same.
So i will try again
Anyhow some test cases which you may use in an *.xml file using "controller2"

<field name="controller2" type="radio" label="controller2" default="1" ><option value="0">JNO</option><option value="1">JYES</option></field>

<field name="dependent01" type="text" label="Dependent Field 01" default="!!! Should be shown always !!!"  />
<field name="dependent02" type="text" label="Dependent Field 02" default="!!! Should be shown !!!" showon="controller2:1" />
<field name="dependent03" type="text" label="Dependent Field 03" default="!!! Should not be shown !!!" showon="nonexistent:1" />
<field name="dependent04" type="text" label="Dependent Field 04" default="!!! Should not be shown !!!" showon="controller2:1[AND]nonexistent:2" />
<field name="dependent05" type="text" label="Dependent Field 05" default="!!! Should not be shown !!!" showon="controller2:1[AND]nonexistent:2" />
<field name="dependent06" type="text" label="Dependent Field 06" default="!!! Should not be shown !!!" showon="nonexistent:2[AND]controller2:1" />
<field name="dependent07" type="text" label="Dependent Field 07" default="!!! Should be shown !!!" showon="nonexistent:2[OR]controller2:1" />
<field name="dependent08" type="text" label="Dependent Field 08" default="!!! Should be shown !!!" showon="controller2:1[OR]nonexistent:2" />
<field name="dependent09" type="text" label="Dependent Field 09" default="!!! Should be shown !!!" showon="controller2:1[OR]controller2:1" />

@ThomasFinnern
Copy link
Contributor

I have tested this item ✅ successfully on 45133c8

The field was gone
I did check again with npm ci and showon.min.js was changed.
This time the field vanished as expected.

The above test cases in *.xml worked before the patch and afterwards.
I may be on the wrong path here ;-)


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/46488.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug NPM Resource Changed This Pull Request can't be tested by Patchtester PR-5.4-dev

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants