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

refactor: make controller more generic #4181

Merged
merged 2 commits into from
Mar 18, 2024

Conversation

elasticspoon
Copy link
Collaborator

@elasticspoon elasticspoon commented Mar 11, 2024

Issue #3556

I am working to replace cocoon with existing Stimulus behavior. This PR makes the behavior of the Add and Remove buttons more generic so in the future they can be used to replace cocoon behavior.

I plan to create 3 further PRs:

  • PR to replace cocoon behavior with stimulus behavior (while still keeping cocoon code) Replace cocoon behavior #4182
  • PR for removal of cocoon code Remove cocoon #4184
  • A PR to refactor the javascript that is left into more reasonable controllers. Not so sure about this one. After looking at it, I think unless the goal is specifically to remove jquery the code would get more complex by moving this behavior to stimulus.

Type of change

  • Refactor

How Has This Been Tested?

Helper Specs

@elasticspoon elasticspoon marked this pull request as ready for review March 11, 2024 02:52
@elasticspoon elasticspoon marked this pull request as draft March 11, 2024 06:52
take in generic html attributes in helper methods
@elasticspoon elasticspoon marked this pull request as ready for review March 12, 2024 06:28
Copy link
Collaborator

@dorner dorner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the approach - had some questions/suggestions.

// data-form-input-target="addContainer" to be set on the add container
addItem(event) {
const template = this.addTemplateTarget.content.firstElementChild.outerHTML;
const dest = document.querySelector(event.target.dataset.addDestSelector) ||
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're using Stimulus, we should be able to just pass this value directly into the controller via value data attributes: https://stimulus.hotwired.dev/reference/values

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I went with this approach is that I wanted to minimize the amount of coupling (maybe the wrong term? context switching?).

If we set the value with stimulus that means that for each button we create we have to additionally set all those values on controller. The controller is at times on a totally different view and you lose some of that context.

I thought the colocation of most of the behavior on the button helper itself just came out much cleaner.

Ex:

<tbody class='fields'>
    <%= render 'partners/individuals_requests/item_request', form: form %>
</tbody>

<div>
  <%= input_add_button('Add Another Item', container_selector: '.fields') do %>
    <%= render 'partners/individuals_requests/item_request' %>
  <% end %>
</div>

These two fields are right next to each other, makes total sense what is going on, where the input will get added.

Less clear. Personally, I don't even really having the controller there but I am also pretty opposed to just having it as a data attribute cause Imo those are super easy to lose track of.

# app/views/partners/profiles/edit.html.erb
<%= simple_form_for current_partner, url: partners_profile_path,
            data: { controller: "form-input", form-input-add-dest-value: "container_id" },
            html: {role: 'form', class: 'form-horizontal'} do |form| %>
            <%= form.simple_fields_for :profile, current_partner.profile do |profile_form| %>
              <div class="row">
                <div class="col-6">
# app/views/partners/profiles/edit/_area_served.html.erb
<%= input_add_button "Add Another County", container_selector: "#served_areas", id: "__add_partner_served_area" do %>
        <%= f.simple_fields_for :served_areas do |served_area| %>
          <%= render 'served_areas/served_area_fields', f: served_area %>
        <% end %>
      <% end %>

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... fair enough. I feel like there's a better way to accomplish this, but I can't think of one right now. :)

spec/helpers/ui_helper_spec.rb Outdated Show resolved Hide resolved
app/views/partners/requests/_item_request.html.erb Outdated Show resolved Hide resolved
fix: use Nokogiri in tests

Swaps from using regex matching of HTML
to using Nokogiri to be less flaky.

fix: rename helper method

Renames input_remove_button and kin
to remove_element_button to better reflect
what it is doing.

The button does more than add or remove an
input, it can add/remove any element.
// data-form-input-target="addContainer" to be set on the add container
addItem(event) {
const template = this.addTemplateTarget.content.firstElementChild.outerHTML;
const dest = document.querySelector(event.target.dataset.addDestSelector) ||
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... fair enough. I feel like there's a better way to accomplish this, but I can't think of one right now. :)

@dorner dorner merged commit 7f38cb7 into rubyforgood:main Mar 18, 2024
19 checks passed
@elasticspoon elasticspoon deleted the make-input-buttons-generic branch March 18, 2024 19:48
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.

None yet

2 participants