Problem/Motivation

The module currently lacks (a widget and) standardized mechanisms for Dynamic Options and Dependent Fields.

  • Widget: Make it available to the masses. :)
  • Static Options: Users are currently limited to hardcoding enum values in the schema or using simple Taxonomy terms without filtering capabilities.
  • No Interdependency: There is no built-in way to filter one field's options based on the value of another (e.g., "Car Model" depends on "Brand"), which is a critical requirement for complex forms.

Proposed resolution

Implement a modular "Option Source" plugin system and refactor the main widget structure.

  • Option Source Plugins: Introduce a plugin manager to allow options to be fetched from various backends.
    • Views Source: Fetch options from any Drupal View, enabling advanced filtering and display logic.
    • Taxonomy Source: (Enhanced) Fetch terms from a vocabulary with robust validation.
  • Dependent Fields: Implement lightweight Client-side JSON API triggers to reload dependent Options.
    • Frontend: Uses fetch() to get filtered options from a custom controller when a trigger field changes.
    • Backend: Dedicated JsonOptionsController that returns a simple JSON array (avoiding full form rebuilds).
  • Widget Split: Create two distinct plugins:
    • JSON Schema Form (Static): Simple text area for raw schema input.
    • JSON Schema Form (From Reference): Dynamic AJAX-driven configuration to select "Schema Entity Reference" and "Schema Source Field".

Configuration Reference

This patch introduces advanced configuration via ui:options for dynamic sources.

1. Views-Based Options (Dynamic)

You can now populate a dropdown using a View. The source object now accepts a view parameter (format: view_id:display_id).

"product_type": {
  "type": "string",
  "ui:options": {
    "widget": "tagify",
    "source": {
      "plugin": "views",
      "config": {
        "view": "my_products_view:entity_reference_1"
      }
    }
  }
}

2. Dependent Fields (Filtering)

To filter options based on another field's value, add the array arguments key to the source config. This allows to watch a specified field name or use the @ prefix for a config value and pass their values as Contextual Filters to the View.

"brand": {
  "type": "string",
  "title": "Brand"
},
"model": {
  "type": "string",
  "title": "Model Name/Number",
  "ui:options": {
    "widget": "tagify",
    "allowCreate": true,
    "placeholder": "Select or type new...",
    "source": {
        "plugin": "taxonomy",
        "config": {
            "vocabulary": "car_models",
            "view": "my_view:car_models_filtered",
            "arguments": [
                "@vocabulary",  // Resolves to "car_models" from config
                "brand"               // Resolves to the value of the "brand" field
            ]
        }
    },
  }
},

Remaining tasks

  • [ ] Fix failing tests (Note: Testing environment currently unavailable).
  • [ ] Rewrite documentation.
  • [ ] Final functional testing of complex View arguments.

User interface changes

  • Widget Selection: "Manage Form Display" now offers two distinct widgets: Static and From Reference.
  • Configuration Form: The "From Reference" widget features a responsive AJAX form where selecting a Reference field dynamically loads available Source fields (Text or JSON) from the target entity.
  • Frontend: Forms now support real-time updates for dependent fields using a client-side JSON API. Changing a "Trigger" field (e.g., Brand) fetches new options for the "Target" field (e.g., Model) without reloading the page.
  • Almost forgot... tested and working with Inline Entity Form too :)

API changes

  • New Plugin Manager: JsonFormOptionSourceManager to handle option sources (views, taxonomy).
  • New Base Class: JsonSchemaWidgetBase abstracts common logic (libraries, value handling) for both Static and Reference widgets.
  • Added: json_form_widget.get_options route and controller for AJAX option fetching.

Data model changes

None. The schema storage format remains the same, only the widget configuration and option fetching logic have changed.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

viappidu created an issue. See original summary.

viappidu’s picture

Issue summary: View changes
viappidu’s picture

StatusFileSize
new16.04 KB
new120.84 KB
viappidu’s picture

StatusFileSize
new15.83 KB
new120.62 KB

fixed an regression introduc with last commit, and some code cleanup

viappidu’s picture

StatusFileSize
new21.77 KB
new131.51 KB

Realized I had most of the work done in different modules. Ready to be tested thoroughly :)

Remaining tasks

  • [ ] Write tests.
viappidu’s picture

Status: Active » Needs review
dafeder’s picture

Status: Needs review » Needs work

Hi @viappidu, I appreciate your ambition here but I think this is too much change to review or safely merge in a single MR. The scope has really expanded here and it introduces way too many things. I'm going to focus on reviewing the two earlier MRs that are included in this, and I'd encourage you to work on splitting the work here into more focused issues/MRs.

The following all deserve their own issues IMO:
- Enhanced Taxonomy source plugin
- Views source plugin
- Dependent fields feature
- Static JSON Schema form - this is next on my own list of things to do, I might "steal" some of your work from this MR (with credit of course!) if I get to it before you can make a focused MR
- JSON Schema references - I don't exactly understand the concept here, but it seems big enough to warrant its own issue/MR. I don't think it's dependent on any of the other work here?

dafeder’s picture

Status: Needs work » Postponed (maintainer needs more info)
dafeder’s picture

3565788 test

viappidu’s picture

Status: Postponed (maintainer needs more info) » Needs review
StatusFileSize
new129.04 KB
new210.08 KB

@dafeder, I don't really see the point of splitting the issue in all the sub issues you created. Or at least I do not have the conditions to do so.
- Replace select2 (critical) I completely removed select2 from my systems. NOT going to reinstall it.
- As I explained before working on the (major) array nesting issue solution I needed to implement the number/boolean (critical) changes.
- the external reference (taxonomy/view), does not make sense (my opinion) to keep them separated

As per your question. at #9, I will try to simplify how I approached the 2 widgets
the static one: the same schema is valid/applied to all entities making use of the schema
the reference one: the schema is coming from an "external source" eg. a taxonomy vocabulary where each term has a different schema. when the entity reference changes the form is loaded from it's source field and recreated. This gives the option to have unlimited schemas availability

Your other question in #3565448-13: Drupal 11 and CMS Compatibility: Replace Select2 and Select_or_Other with Tagify regarding the creation of a "new item" in a list, the entity is saved with the new value but the enum list is not updated, by choice, that is why I introduced the use of taaxonomies.

Honestly I think this module has great potential and for the moment very little use. I do not see the point in delaying major issues at this stage.
(added tests)

dafeder’s picture

I'll respond to the other points in a bit but regarding:

Your other question in #3565448-13: Drupal 11 and CMS Compatibility: Replace Select2 and Select_or_Other with Tagify regarding the creation of a "new item" in a list, the entity is saved with the new value but the enum list is not updated, by choice, that is why I introduced the use of taaxonomies.

You're right, there's a bit of code involved in my use-case that is specific to DKAN and its implementation of the option source plugin. I think that using taxonomy for this is the better option but I'll need to think a bit on how to reconcile with some existing implementations.

dafeder’s picture

Status: Needs review » Postponed (maintainer needs more info)

Anyway @viappidu thanks again for your enthusiasm for this module. I think you'll find in most Drupal modules or open source projects in general, it's vital to keep both MRs and issue threads focused and tightly scoped, and you'll find very few examples of multi-issue MRs like this begin accepted, even if the work on each issue is of high quality on its own (as seems to be the case here). Even just on the side of issue threads, you can see discussion is already getting difficult, when the subject of the thread moves from one focused on the specifics of moving to tagify to "all the things @viappidu wants to see changed in this module".

Finally, I'd ask you to be sensitive to the fact that the low adoption statistics for this module are a bit misleading. JSON Form Widget was only recently released as a standalone module on Drupal.org but has been in production for years on several government websites as part of the DKAN package. We need to balance our desire to make it useful for people beyond the DKAN user base with our responsibilities to existing users. I understand that contributing to MRs is time-consuming; if you're not willing or able to split this one up our team will likely incorporate the relevant code from your MR (with full credit of course) into MRs that meet our requirements and on our own timeline.

I'll keep this open until we have specific issues to represent all its pieces. Thanks for your understanding.

viappidu’s picture

@dafeder ,lol, "all the things @viappidu wants to see changed in this module", lol.
Don't get me wrong, I was in a rush commenting back so I might have been lost in translation. I do agree with you, that is why I did open the other issues/MR though I currently have very little time to spare for reviewing each one separately.
And I do understand that your user base is government via civicactions (kudos) hence the problematics of aligning any change here with the slow cogs there. I am Italian, you honestly cannot have a fraction of an idea of how hard it would be here... So let me correct your statement with: "All the things @viappidu WISH to see changed in this module".

Glad if you have a team that can manage the multiple @viappidu wishes :)
PS If you are looking to hire I am available :)

dafeder’s picture

Heh well we do have a great team but this module is unfortunately not our top priority most of the time, so I don't want to give the wrong impression about our capacity. And glad to hear we're on the same page! It sounds like you did get the module to the place you need it with this fork so hopefully that can tide you over till we're able to incorporate some of this into an official release.

dafeder’s picture

I have started trying to isolate the static widget in the branch for #3572908: Include default working widget, hope to get that in in not too long.