How to give multiple rule effects on the element?

I want to give 2 different rule effects on the element. Let’s say in the following UI schema subCategory will be visible when the category length is more than 3 letters, once this condition is satisfied and subCategory is visible than I want to apply DISABLE effect on subCategory.

{
“type”: “Control”,
“scope”: “#/properties/subCategory”,
“rule”: {
“effect”: “SHOW”,
“condition”: {
“scope”: “#/properties/category”,
“schema”: {
“type”: “string”,
“minLength”: 3
}
}
}
}

[original thread by Harshita Jaiswal]

Hi @jharshita, thanks for your question! Currently you can only apply a single rule to each element. As a workaround you could wrap the control into VerticalLayout and apply the second rule to this element. Visually this should look the same.

1 Like

[shivgarg5676]

e.g.

{
    "type": "Group",
    elements: [{
        type: "Control",
        scope: "#/properties/a",
        rule: {
        }
    }],
    rule:{
    }
}

Hi, I assume this would work for AND conditions, but is there any similar solution for OR conditions?

Like, I want to show field when “#/properties/subCategory” has certain value or “#/properties/category” has certain value

Hi @nikola,

The rule support can handle arbitrary schemas, so you could for example use a oneOf construct for an or condition.

1 Like

Hi @sdirix thanks, I managed to get it working with

 "scope": "#",
 "schema": {
   "anyOf": [
     {
       "type": "object",
       "properties": {
         "hasPromoCode": {
           "const": "yes"
          }
        },
        "required": ["hasPromoCode"]
       },
       ...[second element condition]

But I’m having problems with nested structures, where 2 relevant elements don’t have same parent, like for example #/properties/firstContainer/properties/hasPromoCode and #/properties/secondContainer/properties/hasSomethingElse. I tried to get it working with

          "scope": "#",
          "schema": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "type": "object",
                  "firstContainer": {
                    "type": "object",
                    "properties": {
                      "hasPromoCode": {
                        "const": "yes"
                      }
                    },
                    "required": ["hasPromoCode"]
                  }
                }
              }
            ]

but I keep getting Error: strict mode: unknown keyword: "0" in the console

Hi @nikola,

Glad that you managed to get it working!

I’m not sure where this is coming from. We use the same AJV instance form-wide and there we disable strict mode. Do you hand in a custom AJV instance?

Note that your schema seems to be malformed as there is one "type": "object" too many. As "object" is not a valid schema for the property type maybe the error stems from that.

1 Like

Hi @sdirix thanks! It was indeed my instance of ajv which was causing issues. It was set to

Ajv({ allErrors: true, strictSchema: true, strict: true })

By removing strict: true , everything works as it should and some other weird schema-structure related errors are gone.
This is my final working solution:

      "rule": {
        "effect": "SHOW",
        "condition": {
          "scope": "#",
          "schema": {
            "anyOf": [
              {
                "properties": {
                  "firstContainer": {
                    "properties": {
                      "hasPromoCode": {
                        "const": "yes"
                      }
                    },
                    "required": [
                      "hasPromoCode"
                    ]
                  }
                }
              },
              {
                "properties": {
                  "secondContainer": {
                    "properties": {
                      "hasSomethingElse": {
                        "const": "yes"
                      }
                    },
                    "required": [
                      "hasSomethingElse"
                    ]
                  }
                }
              }
            ]
          }
        }
      }
1 Like

When you create a custom AJV instance you might want to use createAjv exported from @jsonforms/core as it already sets the AJV options as we need them in JSON Forms. The method also takes in a parameter to set additional options if you need them.

1 Like