Support for rule condition based on presence of errors

Hi @sdirix

I do have a custom renderer that renderer a button that needs to be enabled only when there are no errors and I’m using the schema based rule condition to achieve that but the thing is that this will run the AJV validation on the whole data set (and depends on the size) this could be expensive, the other issue with that approach is that if there are any additional errors added manually External validation errors then the element will be enabled even when there are those manually added errors.

Could we have a new Rule condition to cover that case?
First we won’t execute the AJV validation again and again for all UI elements that depends on errors being present or not and also it could solve the issue where there are manually injected errors, like in a case where a custom renderer - for example a renderer that wraps UIs elements that have its own validation ( Stripe credit card component ) - reports those errors via manually added errors.

Any other approach that you can think of to accomplish the above (enable/disable/hide/show UI elements based on presence of errors including the manually added errors) ?

Krasimir

Hi Krasimir,

I’m not sure I understand this issue completely.

I do have a custom renderer that renderer a button that needs to be enabled only when there are no errors and I’m using the schema based rule condition to achieve that but the thing is that this will run the AJV validation on the whole data set (and depends on the size) this could be expensive, the other issue with that approach is that if there are any additional errors added manually External validation errors then the element will be enabled even when there are those manually added errors.

With schema based rule condition you mean the UI Schema rules, e.g.

type: 'Control',
scope: '#/properties/age,
rule: {
  effect: 'DISABLE',
  condition: {
    scope: '#/properties/isHuman',
    schema: {
      const: false
    }
  }
}

The UI Schema rules:

  • don’t run against the whole data set. The rule.condition.schema will run against the data pointed to by rule.condition.scope
  • they don’t contribute any error within JSON Forms, neither to the form-wide storage, nor to the control itself. They only have an effect on the enabled and visible props. Therefore they are completely independent from the errors prop given to renderers.

If you want to disable the button when the UI Schema rule applies and/or an error from the regular validation or an additionalError is relevant to the control, you can check both props, e.g.

const disableMyButton = !enabled || errors
  • !enabled will be true if the UI Schema rule applies
  • errors will be truethy when an JSON Forms error and/or additionalError was determined for the control

Does this cover the question?

Yes I mean UI schema rules but the button itself is renderer by JSON forms (using custom renderer) and I want to enable / disable the button when there are errors. I managed that by using the schema based condition which points (having schema) the complete JSON forms schema that is set and run against all data which actually accomplish what I need but that means that the validation for the whole data is performed multiple times. also when there are custom errors those are not going to be considerer.
For example I have the following

          "rule": {
            "effect": "ENABLE",
            "condition": {
              "scope": "#/",
              "schema": { "$ref": "/#" }
            }
          }

To simplify what I need I guess instead of using button and there might be confusion if the button is rendered by JSON forms or some other way - lets say that I would like to have a Label that is visible when there are any errors (including additional manually added errors ) and hide that when there are no errors.

Basically I do not want to have a code that have disableMyButton since I do not control the button it is part of the renderer JSON form and I want to utilize the JSON forms way of enable/disable UI elements.

Ah I see,

Hmm at the moment there is no support for this. Generically speaking what you’re missing is an own props-transformator between the framework and the renderers. Within such a transformator you could do any modification including switching enabled to false when there are any errors (which includes additionalErrors).

In the React renderers this is relatively easy (although tedious) to implement as React HOCs can be used as such transformators. So there are users which just “implement” an own renderer set by wrapping all renderers with their own HOCs.

In the Vue renderers it’s not that nice as we directly use the bindings within the renderers. So bringing in another layer requires copying all of the renderers.

If your use case is not that generic you could just support another UI Schema option in your custom renderers, e.g. options.disableIfErrors: true or options.hideIfErrors: true or options.ifErrors: 'none' | 'hide' | 'disable'.

The question here I guess is if the JSON forms core team consider this to be possible included in the JSON forms core functionality. E.g. if there is a pull request against the JSON forms core then would that even be considered to be merged or most likely it won’t be included ? Talking about specifically about new Rule Condition with new type for that specific case.

Hmm generally speaking this specific kind of rule which somehow checks all AJV errors and additional errors of the form does not really fit the existing rule concept.

However what would be interesting is:

  • a way for users to customize their own rule support, and/or
  • a way for users to inject middleware, and/or
  • a way for users to inject prop transformators (like described above), and/or
  • any other generic way to customize JSON Forms for functionality like this.

If you, we or someone else can come up with a generic (and performant) concept which you could then use to implement the behavior but would also be useful for the community at large then this would have good chances to be integrated into the core.