Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Super-select: update on dependent field #45

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

pascallaliberte
Copy link
Member

@pascallaliberte pascallaliberte commented Dec 1, 2022

Fixes #42

Co-dependent PRs:

This PR gives the ability for a super-select to update its options (by updating its searchUrl) based on some other field on whose value it depends on.

It introduces a dependable_controller.js, which allows for direct dispatching of events to a dependent field without the need for a wrapper controller to coordinate events.

The new outlets feature of Stimulus 3.2 was considered, but it's the wrong pattern because it requires tight coupling of the dispatching and the dependent fields (ie. knowledge from the dispatcher of the inner-workings of the receiver controller). Since the dependable_controller could be used to also update dependent turbo_frames or other arbitrary fields, the outlets pattern no longer fits the bill.

Example:

Let's hook up a :region super-select field to update itself with new options when the :country field changes (in this case, it's a super-select also, but doesn't have to be):

<%= render 'shared/fields/super_select',
  method: :country,
  choices: @team.countries.all.map {|c| [c.name, c.id] },
  wrapper_options: {
    data: {
      'controller': "dependable",
      'action': '$change->dependable#updateDependents',
      'dependable-dependents-selector-value': "##{form.field_id(:region)}_wrapper"
    }
  }
%>
<%= render 'shared/fields/super_select',
  method: :region,
  choices: [],
  html_options: { 
    disabled: true
  },
  wrapper_options: {
    id: "#{form.field_id(:region)}_wrapper",
    data: {
      action: "dependable:updated->fields--super-select#updateSearchValue"
    }
  }
%>

Tasks:

  • add a way for a field to tell its dependent fields that it's been updated
  • add the ability to super-select to catch the new value and update its searchUrl

Updating the searchUrl from a pattern and mappings

For the searchUrl to be able to update itself in a number of ways, I'd like to introduce the ability to define required and optional params for the searchUrl.

Given a url pattern like /account/countries/${headquarter[country]}/regions.json, the headquarter[country] field would be deemed required (can't be empty or null).

Additionally, a set of query string mappings could be provided for optional query string parameters.

e.g. given this queryStringMapping

{
  "headquarter[continental_only]": "continental_only",
}

If a dependent field named headquarter[continental_only] were to tell the super-select that its value is now set to true, then the searchUrl would be changed to /account/countries/1/regions.json?continental_only=true.

The url pattern could also require the continental_only query string by specifying it in the pattern directly:

/account/countries/${headquarter[country]}/regions.json?continental_only=${headquarter[continental_only]}

And to make these url params persist a back operation, they would all be saved in a urlParams value. An urlParamChanged() callback would catch the changes to the urlParams value, assemble the new searchValue if all required params are gathered, and thereby updating the super-select's options via that json request.

This work into updating the searchUrl from this pattern and mappings could be made into a Stimulus mixin, re-usable into other controllers (e.g. for updating a turbo_frame's src).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Selection in one super select affects options of another.
1 participant