> For the complete documentation index, see [llms.txt](https://docs.agilecase.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.agilecase.com/developer-documentation/custom-form-scripting/examples/driving-a-layout-from-several-rules.md).

# Driving a Layout From Several Rules

One hidden config label running several independent rules in a single ruleset.

A form with several conditional sections does not need several labels. One config label holds one array, and every rule in it is applied in one pass.

## The scenario

A privacy notice form has three flags, each of which reveals its own pair of retention fields. All three are independent: any combination of them can be set.

| Setting      | Value                                                                                      |
| ------------ | ------------------------------------------------------------------------------------------ |
| Config label | `6501` Retention config, hidden                                                            |
| Triggers     | `6502` Special category data, `6503` Automated decision-making, `6504` Third-party sharing |
| Targets      | `6505`/`6506`, `6507`/`6508`, `6509`/`6510`                                                |

## The script

```javascript
ThisJSLabel().HideRow();

var retentionLayout = [
    {
        "action": "hide",
        "trigger_id": 6502,
        "target_ids": [6505, 6506],
        "test_type": "NOT_EQUALS",
        "test_values": ["Yes"],
        "description": "Special-category retention fields apply only when the flag is Yes"
    },
    {
        "action": "hide",
        "trigger_id": 6503,
        "target_ids": [6507, 6508],
        "test_type": "NOT_EQUALS",
        "test_values": ["Yes"],
        "description": "Automated-processing retention fields apply only when the flag is Yes"
    },
    {
        "action": "hide",
        "trigger_id": 6504,
        "target_ids": [6509, 6510],
        "test_type": "NOT_EQUALS",
        "test_values": ["Yes"],
        "description": "Third-party retention fields apply only when the flag is Yes"
    }
];

ExecuteAllRules(retentionLayout);
```

## One ruleset, not three labels

Three rules like these could each live in their own config label, and on a form this simple the result would look the same. It stops looking the same as soon as two rules touch the same field.

`ExecuteAllRules` keeps a record of what it has hidden as it works through the array, and a field hidden by one rule stays hidden however later rules in the same array come out. So a field with two reasons to be hidden is hidden if either applies, whatever order the rules are in.

That record starts empty on each call. Split the same rules across two labels and the second call knows nothing about the first, so whichever label happens to run last decides — and the order labels run in is not something you control. Keeping rules that touch overlapping fields in one array is what makes the outcome predictable.

## Repetition is not the enemy

Three near-identical rules look like something to factor out, and there is a good case for leaving them as they are. The array is a description of the form, and its value is that someone can read down it and see every conditional section in one place, each with the fields it governs written out.

Where the repetition is genuinely mechanical — a dozen flags each revealing one field — build the array in a loop:

```javascript
var sections = [
    { flag: 6502, fields: [6505, 6506] },
    { flag: 6503, fields: [6507, 6508] },
    { flag: 6504, fields: [6509, 6510] }
];

var retentionLayout = sections.map(function (section) {
    return {
        "action": "hide",
        "trigger_id": section.flag,
        "target_ids": section.fields,
        "test_type": "NOT_EQUALS",
        "test_values": ["Yes"]
    };
});

ExecuteAllRules(retentionLayout);
```

The table at the top is then the thing to maintain, and it is harder to get one of a dozen sections subtly wrong.

## When the sections nest

These three flags are independent. If one section only makes sense inside another — a sub-question that appears when a parent answer is Yes — write a rule for each level rather than trying to express both in one. The stickiness of `hide` does the composition for you: the child is hidden if its own answer says so or if its parent is hidden.
