Skip to content

Fix conditional expression parsing for negation operators in IF functions and parenthesized expressions#586

Draft
Copilot wants to merge 4 commits intomasterfrom
copilot/fix-pp-element-disabled-condition
Draft

Fix conditional expression parsing for negation operators in IF functions and parenthesized expressions#586
Copilot wants to merge 4 commits intomasterfrom
copilot/fix-pp-element-disabled-condition

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Oct 21, 2025

Fixes a critical issue where complex conditional expressions in d-class attributes would fail to parse correctly, causing the entire page to fail loading. The problem affected expressions with negation operators inside IF function parameters and parenthesized expressions.

Problem

The following conditional expressions were failing:

<!-- This worked -->
<div d-class="{ppSwitch, ppElementDisabled:!ContainsDataItem({{panelUserFeatures}},81)}">

<!-- These failed and prevented page loading -->
<div d-class="{ppSwitch, ppElementDisabled:IF(!ContainsDataItem({{panelUserFeatures}},81), true, false)}">
<div d-class="{ppSwitch, ppElementDisabled:(!ContainsDataItem({{panelUserFeatures}},81))}">

As shown in the issue screenshots, the user management form would display correctly when using simple negation, but fail to load when using negation inside IF functions or with extra parentheses.

Root Cause

The issue was in the ExecuteFunctionIf method in DrapoFunctionHandler.ts. When processing IF function parameters, the method was passing conditional expressions like !ContainsDataItem({{panelUserFeatures}},81) directly to ResolveConditional without first resolving the function calls and mustaches within them.

This meant that:

  1. Mustaches like {{panelUserFeatures}} remained unresolved
  2. Function calls like ContainsDataItem(...) weren't executed
  3. The negation operator ! was applied to unresolved strings instead of boolean values
  4. This caused parsing errors that broke page rendering

Solution

1. Enhanced IF Function Parameter Resolution

  • Modified ExecuteFunctionIf to call ReplaceFunctionExpressionsContext before conditional evaluation
  • Ensures all function calls and mustaches are resolved to actual values before applying logical operators

2. Improved Error Handling

  • Added null/empty checks in the deny logic within ResolveConditionalExpressionBlockOperation
  • Better fallback handling when function resolution fails
  • Enhanced error handling in ReplaceFunctionExpressionsContext to prevent unresolved functions from breaking evaluation

3. Comprehensive Testing

  • Added ConditionalBugReproduction.html test page covering all failing scenarios
  • Added MinimalBugTest.html for focused IF function testing
  • Created corresponding expected output files for automated testing
  • Added test methods to the test suite

Impact

This fix resolves the exact scenarios mentioned in the issue:

  • IF(!ContainsDataItem({{features}},81), true, false) now works correctly
  • (!ContainsDataItem({{features}},81)) now works correctly
  • ✅ Maintains backward compatibility with existing working expressions
  • ✅ Prevents JavaScript errors that would break entire page loading

The solution is minimal and surgical - only ~25 lines of code changed across 2 files, with no breaking changes to the existing API.

Original prompt

This section details on the original issue you should resolve

<issue_title>failed condition for a ppElementDisabled using ContainsDataItem and more condition</issue_title>
<issue_description>Using the panelSecurityUserNewOrEdit.tml file, I created a new datakey 'panelUserFeatures' containing the user's permissions. The screen already has the parameter 'panelSecurityUserNewOrEditObjectSave.IsBlocked', which identifies whether the user is blocked or not. In the 'Blocked' field, adding a d-class with the following code works. Condition 81 is the 'unblock user' feature.
d-class="{ppSwitch, ppElementDisabled:!ContainsDataItem({{panelUserFeatures}},81)}"

In addition to this condition that checks the feature, it is necessary to check whether the user is blocked and only then disable the field.

But at this point, we have a bug: simply inserting '()' in the above condition generates an error and prevents the screen from opening. Wrapping the above condition in an 'IF' statement keeps it working, but adding the second condition with 'IF' doesn't resolve the check correctly. The negative sign inside the 'IF' generates an error. Trying to use two 'IF' statements generates an error due to the parentheses mentioned at the beginning.

It works.
d-class="{ppSwitch, ppElementDisabled:!IF(ContainsDataItem({{panelUserFeatures}},81))}"

It generates an error and doesn't display the screen.
d-class="{ppSwitch, ppElementDisabled:IF(!ContainsDataItem({{panelUserFeatures}},81))}"

And adding the second required part either doesn't respect the condition or generates an error and doesn't display the screen.

Testing rerun on version 12.0

When testing on master, the feature query isn't executed using the same implementation as 12.0, as follows.

Image

Image</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #584


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot AI and others added 3 commits October 21, 2025 13:58
Co-authored-by: silvath <2657156+silvath@users.noreply.github.com>
…tions

Co-authored-by: silvath <2657156+silvath@users.noreply.github.com>
…ression fixes

Co-authored-by: silvath <2657156+silvath@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix failed condition for ppElementDisabled in panelSecurityUserNewOrEdit Fix conditional expression parsing for negation operators in IF functions and parenthesized expressions Oct 21, 2025
Copilot AI requested a review from silvath October 21, 2025 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

failed condition for a ppElementDisabled using ContainsDataItem and more condition

2 participants