How to implement conditional fields and requirements in Volto based on dropdown selection?

I'm looking to handle conditional fields in Volto and Dexterity, ideally it should be possible to both hide fields and ensure that they are conditionally required based on a dropdown selection.

A good example might be a book catalog system in Volto where different types of publications require different metadata fields. I need both the visibility and required status of fields to change based on a "Publication Type" dropdown selection.

For example, when "Book" is selected, the ISBN field should be both visible and required, but ISSN should be hidden. When "Journal" is selected, ISSN should be visible and required, but ISBN should be hidden.

Currently, my Dexterity XML schema looks like this:

<field name="publication_type" type="zope.schema.Choice">
    <title>Publication Type</title>
    <values>
        <element>Book</element>
        <element>Journal</element>
        <element>Conference Proceedings</element>
    </values>
</field>

<!-- Book-specific fields -->
<field name="isbn" type="zope.schema.TextLine">
    <title>ISBN</title>
    <required>False</required>  <!-- Should be required only for Books -->
</field>

<!-- Journal-specific fields -->
<field name="issn" type="zope.schema.TextLine">
    <title>ISSN</title>
    <required>False</required>  <!-- Should be required only for Journals -->
</field>

<!-- Conference-specific fields -->
<field name="conference_date" type="zope.schema.Date">
    <title>Conference Date</title>
    <required>False</required>  <!-- Should be required only for Conference Proceedings -->
</field>

Required behavior should be:

  • For Books:
    • ISBN is required
    • ISSN and Conference Date are hidden
  • For Journals:
    • ISSN is required
    • ISBN and Conference Date are hidden
  • For Conference Proceedings:
    • Conference Date is required
    • ISBN and ISSN are hidden

What's the recommended approach for implementing both conditional display AND conditional requirements in Volto? Does this need to be handled on both frontend and backend? Should I just abandon Dexterity totally for this (I have a need to provide an api for rest-based clients so I suspect that will mean keeping dexterity)?

Using my book catalog as a proof of concept, what I plan to do:

1. Backend (Dexterity) Layer

  • Implement as a behavior rather than directly in content type
  • Use Zope schema for field definitions
  • Implement custom validators for conditional requirements
  • Ensure REST API compatibility

Key components:

  • Marker interface for behavior identification
  • Schema interface defining fields
  • Behavior adapter implementation
  • Field validators for conditional requirements

2. Frontend (Volto) Layer

(the part I'm least comfortable with)

  • Custom schema component for conditional rendering <----- especially fuzzy with this part
  • Form validation for required fields <---- also fuzzy
  • Immediate user feedback
  • Integration with Volto's block configuration

3. REST API Considerations

  • Maintain consistent validation between frontend and backend
  • Support programmatic access to content
  • Ensure proper serialization/deserialization of field data

Backend Structure

# behaviors.py
@provider(IFormFieldProvider)
class IPublicationFields(model.Schema):
    """Publication fields behavior"""
    publication_type = schema.Choice(...)
    isbn = schema.TextLine(...)
    issn = schema.TextLine(...)