0

I have form that has a section that displays a series of checkboxes for what groups a user manages. I want to add a search box at the top of the checkboxes that allows them to search a name and have it filter the results. From there they can check whatever ones they need to and submit the main form.

The only way I have ever done this is by triggering a from submission. It is not working (not doing anything) I assume because it is within another form. Is there a way to get this to work like I have it below, or is there a better way to set up this filter?

cardrequest form:

<%= form_with(model: cardrequest, id: dom_id(cardrequest), class: "contents") do |form| %>

form fields for cardrequest ...

<div class="mb-4 space-y-4">
    <%= form_with url: search_cardrequests_path, method: :get, data: { controller: "search-form", search_form_target: "form", turbo_frame: "cgs" } do |c| %>
        <div>
            <label for="add-guests">Select Cardholder Groups</label>
            <div class="relative">

            <%= c.search_field :search,  data: { action: "input->search-form#search" }, value: params[:search] %>

        </div>
    <% end %>    
</div>


<div data-controller="checkbox-select-all">
<label>     
    <input type="checkbox"  data-checkbox-select-all-target="checkboxAll" />
    <span class="btn_primary_small">Select All / Deselect All</span>
</label>
<%= turbo_frame_tag "cgs" do %>
    <div class="space-y-3">
        <%= form.collection_check_boxes :cardholdergroup_ids, current_user.cardholdergroups, :id, :friendlyname do |g| %>
        <div class="flex items-center mr-4">
            <%= g.check_box data: { checkbox_select_all_target: 'checkbox' } %>
            <%= g.label %>
        </div>
        <% end %>
    </div>
<% end %>
</div>

<% end %>

Stimulus controller:

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
static targets = [ "form" ]

search() {
  clearTimeout(this.timeout)
  this.timeout = setTimeout(() => {

    this.formTarget.requestSubmit()
  
  }, 200)
  
  
 }
}

cardrequests controller search method:

def search
    cardholdergroups = current_user.cardholdergroups
    @cardholdergroups = cardholdergroups.where("friendlyname LIKE ?", "%#{search}%") if params[:search].present?   
    render(partial: 'cgs', locals: { cardholdergroups: @cardholdergroups })
end

routes:

resources :cardrequests do
  collection do
    get 'search'
  end
end
spacerobot
  • 265
  • 1
  • 5
  • 23
  • I think you have figured this one out yourself. Nested forms are not valid HTML and will result in non-standard behavior. There are many potential solutions - for example you could have two forms (that are not nested) and submitting one updates the other or you can just attach an event handler directly to the select element. – max Jan 07 '23 at 10:05
  • Thanks. Yeah I kind of know what the issue is, just not that great with stimulus enough to know what I should be doing on an input change. Every example I have seen of hotwire filtering involves submitting a form. If you know of any examples of a non form submit hotwire filter let me know! – spacerobot Jan 07 '23 at 14:07
  • The example on https://stimulus.hotwired.dev/ shows attaching an event handler to a button. Switch out the button for a select and `data-action="click->hello#greet"` for `data-action="hello#greet"` (change is the default action for a select). – max Jan 07 '23 at 14:26
  • Thanks. I will take a look at this. Just as I wrote my last reply I stumbled on to this stimulus solution which was exactly what I was looking to do and go tit working: https://onrails.blog/2018/03/15/stimulus-js-tutorial-how-do-i-filter-data-in-a-list-or-table/ – spacerobot Jan 07 '23 at 14:29

0 Answers0