How to achieve a text field which is only required when a checkbox is checked?

I have a case where we have a field that is only required when a checkbox is checked. When the checkbox is unchecked the field becomes optional, but still editable.

The only way I could think to do this was with an “anyOf” array like so:

// data
{"enabled": true}

// schema
{"anyOf": [{
  "type": "object",
  "properties": {"enabled":{"type":"boolean"},"url":{"type":"string"}},
  "required": ["url"]
}, {
  "type": "object",
  "properties": {"enabled":{"const": false},"url":{"type":"string"}}
}]}

// uischema
{"type":"VerticalLayout", "elements": [{
  "type": "Control",
  "scope": "#/properties/enabled"
}, {
  "type": "Control",
  "scope": "#/properties/url"
}]}

In terms of AJV, it seems to validate just fine and the errors array that is produced contains an error with the keyword property set to “required” - so the correct error message is displayed; however, the required prop that is passed in will always be false because the “isRequired” function does not appear to correctly determine the nextHigherSchema object which is appropriate for the case when the enabled flag is true. So what ends up happening is the UI shows the field with the required error message, but the “*” for required is not showing up when the checkbox is checked.

I believe the related code is this one:

Is there some other better way to solve this?

I am also struggling to figure out how I might make the URL field hidden when the enabled flag is false and visible + required when enabled is true. If I simply make the control hide/show with an effect, this achieves the effect only partially, because the errors array at the root is still showing as non-empty because the hidden field is marked as required by the schema.

I feel I must be missing something here.

EDIT: Here is an example of it working : optimistic-parm-nlofmv - CodeSandbox – so the required errors are still showing up even if you uncheck the box.

@sdirix ,
Can you maybe take a look at this topic as well?

Here is another code sandbox:

This shows 2 different issues I’m having:

  1. The “*” is not showing up next to a field that is sometimes required and sometimes not required depending on the “anyOf” conditionality of the required field
  2. I’m trying to show/hide different versions of the same required/optional field based on a rule, but it seems the rules are not executed right away

To see this - you can go to the code sandbox where a “url” field is being shown as either required or optional depending on the flag in a checkbox. At first both the required and the optional version of the same field are showing up because the rules are not working. Then you can notice that when the field is required the “*” does not show up - I put another required text field to show the difference.

Hi @codefactor,

  1. The “*” is not showing up next to a field that is sometimes required and sometimes not required depending on the “anyOf” conditionality of the required field

Sadly, this is expected. For JSON Forms to support conditional “required” we would need to fully validate the data according to the JSON Schema ourselves, only then would we know when the "required’ annotation is applied to the corresponding property. The only way I ever see this feature being implemented is if that kind of functionality were exposed in AJV.

  1. I’m trying to show/hide different versions of the same required/optional field based on a rule, but it seems the rules are not executed right away

Rules are always executed right away, however their behavior is unintuitive when the scope is pointing to an undefined property. I would like to recommend raising the scope of your rule to the parent level and then specifying required for your property according to your use cases. See here for a discussion with a similar topic.