Ads Area

STUDENT ZONE

The panel-level validation is still incorrect. I tested the latest change and found a specific inconsistent case.


IMPORTANT: Before changing anything, inspect the CURRENT implementation and understand exactly why the panel-level validation behaves differently between panels.


==================================================

SCOPE — VERY IMPORTANT

==================================================


This is NOT specific to one Audit, one Audit workflow, or one Audit type.


We are building a GENERIC solution that must work across ALL audit types, all audit templates/configurations, and all generic Panel / PanelDynamic structures in the application.


The panels mentioned below are ONLY examples from my current test audit:


- Past Medical History and Review of Systems (ROS)

- Physical Examination and Diagnostic Assessments

- Medication Reconciliation and Plan of Care


DO NOT hardcode or create special logic for these panels.


The same implementation must automatically work for:


- Every Audit type

- Every audit configuration/template

- Every generic Panel

- Every PanelDynamic

- Nested panels

- Any number of required questions

- Any supported question type

- Any panel hierarchy


Do NOT create separate logic for different Audit types.


Do NOT add Audit-specific conditions.


Do NOT hardcode panel names, question names, question IDs, or Audit IDs.


The solution must be based only on the generic relationship between a Panel/PanelDynamic and its descendant questions.


==================================================

EXPECTED BEHAVIOR

==================================================


For EVERY generic Panel / PanelDynamic, the panel must show its own

"Response required." whenever AT LEAST ONE required descendant question

inside that panel remains unanswered.


Example:


Panel:

"Past Medical History and Review of Systems (ROS)"


Suppose it contains 5 required questions:


Q1 = answered

Q2 = answered

Q3 = unanswered

Q4 = unanswered

Q5 = unanswered


Expected UI:


Panel

"Past Medical History and Review of Systems (ROS)"


Response required.

<-- PANEL-LEVEL message MUST remain visible


Q1

(answered)


Q2

(answered)


Q3

Response required.

<-- QUESTION-LEVEL validation


Q4

Response required.

<-- QUESTION-LEVEL validation


Q5

Response required.

<-- QUESTION-LEVEL validation



The important rule is:


Panel-level validation means:


"Does this panel contain ANY unanswered required descendant question?"


It does NOT mean:


"Are all questions in the panel unanswered?"


==================================================

GENERIC VALIDATION LOGIC

==================================================


Conceptually the logic should be:


const hasUnansweredRequiredQuestion =

    getAllDescendantQuestions(panel).some(question =>

        question.isRequired &&

        question.value is unanswered

    );


if (hasUnansweredRequiredQuestion) {

    showPanelResponseRequired();

} else {

    hidePanelResponseRequired();

}


Therefore:


0 unanswered required questions

→ NO panel-level "Response required."


1 unanswered required question

→ SHOW panel-level "Response required."


2 unanswered required questions

→ SHOW panel-level "Response required."


10 unanswered required questions

→ SHOW panel-level "Response required."


The panel-level message must disappear ONLY when the LAST unanswered

required descendant question is answered.


==================================================

CURRENT BUG

==================================================


After answering some questions inside a panel, the panel-level

"Response required." disappears even though other required questions

inside the SAME panel are still unanswered.


For example:


Initial state:


Q1 = unanswered

Q2 = unanswered

Q3 = unanswered


Panel:

Response required.


Q1:

Response required.


Q2:

Response required.


Q3:

Response required.



After answering Q1:


Panel:

Response required.

<-- MUST STILL BE VISIBLE


Q2:

Response required.


Q3:

Response required.



After answering Q2:


Panel:

Response required.

<-- MUST STILL BE VISIBLE


Q3:

Response required.



After answering Q3:


Panel:

NO panel-level Response required.


This is the required behavior.


==================================================

IMPORTANT: DO NOT USE DOM VISIBILITY

==================================================


Do NOT determine the panel aggregate validation state using:


- Currently visible DOM elements

- Currently rendered questions

- Open/closed state

- Expanded/collapsed state

- Focus state

- Navigation state

- Scroll position

- Currently visible children

- Which question is currently focused


The aggregate state must come from the SurveyJS model/question hierarchy,

not from what happens to be visible in the DOM.


==================================================

NESTED PANELS

==================================================


Nested panels MUST also work generically.


Example:


Panel A

  Panel B

    Q1 = unanswered


Expected:


Panel B

  Response required.


Panel A

  Response required.



If Q1 is answered:


Panel B

  No Response required.


Panel A

  No Response required.


If Panel B contains another unanswered required question, both Panel B

and all relevant ancestor Panels must continue showing their own

"Response required."


This must work for arbitrary nesting depth.


==================================================

QUESTION-LEVEL VALIDATION

==================================================


Do NOT change the existing question-level validation behavior.


Individual questions must continue to show their own:


"Response required."


The panel-level validation is an ADDITIONAL aggregate state.


For example:


Panel

  Response required.


Q1

  Response required.


Q2

  Response required.


Q3

  Response required.


After answering Q1:


Panel

  Response required.

  <-- STILL PRESENT


Q2

  Response required.


Q3

  Response required.


The panel-level message must NOT disappear just because one child question

was answered.


==================================================

DEBUG THE ROOT CAUSE FIRST

==================================================


Before modifying the code, inspect the current implementation and explain

exactly why this inconsistency occurs.


Specifically investigate:


1. How panel-level validation is currently calculated.

2. Whether the implementation depends on panel.errors.

3. Whether answering one child question clears the parent panel's error

   state.

4. Whether only currently invalid/rendered child elements are being checked.

5. Whether the current implementation checks ALL descendant questions.

6. Whether nested Panels / PanelDynamic are traversed correctly.

7. Whether SurveyJS validation state is being used incorrectly for

   aggregate panel validation.

8. Whether panel validation is being derived from the first/last child

   instead of the complete descendant question set.

9. Why "Past Medical History and Review of Systems (ROS)" loses the

   panel-level error after some questions are answered while other panels

   may still display it.


Do not assume the existing logic is correct.


Identify the actual root cause from the current code first.


==================================================

MINIMAL FIX ONLY

==================================================


After understanding the current implementation, make the MINIMAL GENERIC

fix required to correctly calculate the panel-level aggregate validation.


Prefer a reusable generic helper/function such as:


hasUnansweredRequiredDescendant(panel)


or an equivalent approach that fits the existing architecture.


The helper should:


- Work with Panel and PanelDynamic.

- Traverse all descendant questions.

- Include questions nested inside child Panels/PanelDynamic.

- Check required questions.

- Determine whether each required question is actually unanswered.

- Return TRUE if at least one required descendant is unanswered.

- Return FALSE only when all required descendants are answered.

- Not depend on DOM visibility.

- Not depend on open/closed state.

- Not depend on focus/navigation.

- Not depend on panel names.

- Not depend on question IDs.

- Not depend on Audit type.

- Not depend on the current audit configuration.


Reuse the existing validation/rendering mechanism where possible.


Do not rewrite unrelated validation code.


==================================================

DO NOT TOUCH THESE AREAS

==================================================


Do NOT modify:


- getExactQuestionElement()

- scroll/focus behavior

- navigation behavior

- findFirstInvalidQuestion()

- pendingTargetQuestion

- Audit/IP/Attestation validation separation

- existing question-level validation

- existing question-level "Response required." rendering

- scroll/focus callbacks

- navigation/debug logic unless absolutely required for compilation


This task is ONLY about the generic PANEL-LEVEL aggregate validation.


==================================================

INITIAL LOAD / SUBMIT BEHAVIOR

==================================================


Do not introduce validation on initial Audit load if the existing behavior

does not already do that.


Panel-level "Response required." should reflect the existing validation

lifecycle.


Do not change when validation is triggered.


Only fix HOW the panel-level state is calculated after validation occurs.


==================================================

IMPORTANT EDGE CASE

==================================================


If a panel has:


Q1 = answered

Q2 = unanswered

Q3 = answered

Q4 = unanswered


The panel MUST show:


Response required.


Even though most questions are answered.


If Q2 is answered but Q4 is still unanswered:


The panel MUST STILL show:


Response required.


Only after Q4 is answered should the panel-level message disappear.


==================================================

CROSS-AUDIT REQUIREMENT

==================================================


This solution must work across ALL audit types.


Do not test only the current audit.


If multiple Audit types/configurations are available, test at least

2–3 different audit structures.


The expected behavior must remain identical for every audit:


ANY unanswered required descendant

→ Panel shows "Response required."


ALL required descendants answered

→ Panel hides "Response required."


No additional configuration should be required for individual audits.


==================================================

VERIFICATION

==================================================


After making the change:


1. Build the application.

2. Confirm the build succeeds without new TypeScript/template errors.

3. Open an audit containing multiple generic Panels.

4. Submit with multiple unanswered required questions.

5. Confirm every affected Panel shows its own panel-level

   "Response required."

6. In "Past Medical History and Review of Systems (ROS)", answer only

   1 question.

7. Confirm the panel-level "Response required." STILL remains if other

   required questions are unanswered.

8. Answer another question.

9. Confirm the panel-level message STILL remains while at least one

   required descendant is unanswered.

10. Answer the final unanswered required question.

11. Confirm the panel-level "Response required." disappears.

12. Confirm each individual unanswered question continues showing its own

    question-level "Response required."

13. Test a PanelDynamic.

14. Test nested Panels.

15. Test another Audit type/configuration.

16. Confirm no navigation/focus behavior was changed.


==================================================

FINAL RESPONSE REQUIRED

==================================================


Do NOT simply say "fixed".


After implementation, report:


1. The exact existing validation logic that caused the inconsistency.

2. Why the panel-level error was disappearing after answering one child.

3. Which function/file was changed.

4. The minimal code change made.

5. How the new logic determines the aggregate panel state.

6. Confirmation that PanelDynamic and nested Panels are supported.

7. Confirmation that the implementation is generic across ALL Audit types.

8. Confirmation that navigation/focus/getExactQuestionElement() was not

   modified.

9. Build result.

10. Test results for:

    - multiple unanswered questions

    - answering one child

    - answering all children

    - nested panels

    - PanelDynamic

    - another Audit type


IMPORTANT:


Do not modify unrelated code.


Do not create audit-specific or panel-specific conditions.


Do not hardcode any names or IDs.


Make the smallest generic change that fixes the actual root cause.