RJS: using select_tag watchfield

The dropdown menu (created by select_tag) in my application should trigger the action of the filter category as soon as the user changes the value in the drop-down menu and presses the "Go" button.

Now I would like to get rid of the Go button and have an observer (observe_field?), Call the action of the filter category as soon as the user changes the value in the drop-down menu.

Below you see the code that I wrote. It works using the Go'-Button, but does not work, just changing the value in the drop-down menu. What is wrong with my observ_category_select helper?

View-partial with a drop-down menu and a list of projects

    <!-- drop down menu -->
    <% form_tag(filter_category_path(:id), :method => :post, :class => 'categories') do %>
       <label>Categories</label>
       <%= select_tag(:category, options_for_select(Category.all.map {|category| [category.name, category.id]}, @category_id)) %>
       <!-- i would like to get rid of this button -->
       <%= submit_tag "Go" %>
     <% end %>

   <!-- list of projects related to categories chosen in drop down menu -->
   <ul class="projects">
     <% @projects.each do |_project| %>
       <li>
         <%= link_to(_project.name, _project) %>
       </li>
     <% end %>
   </ul>

   <%= observe_category_select -%>

Helpermethod

  def observe_category_select
    observe_field(
                  :category,
                  :url        =>  filter_category_path(:id),
                  :with       =>  'category',
                  :on         =>  'change'
    )
  end

Javascript output from HelperMethod method

<script type="text/javascript">
//<![CDATA[
   new Form.Element.EventObserver('category', function(element, value) {
     new Ajax.Request('/categories/id/filter', {asynchronous:true, evalScripts:true, parameters:'category=' + encodeURIComponent(value) + '&authenticity_token=' + encodeURIComponent('edc8b20b701f72285068290779f7ed17cfc1cf8c')})
   }, 'change')
//]]>
</script>

Category controller

class CategoriesController < ApplicationController
  def show
    @category = Category.find(params[:id])
    @category_id = @category.id
    @projects = @category.projects.find(:all)

    respond_to do |format|
      format.html # index.html.erb
    end
  end

  def index
    @projects = Category.find(params[:id]).projects.find(:all)

    respond_to do |format|
      format.html # index.html.erb
    end
  end

  def filter
    @category = Category.find(params[:category])
    @category_id = @category.id
    @projects = @category.projects.find(:all)

    respond_to do |format|
      format.html # index.html.erb
    end    
  end

end

"-" grep filter

             filter_category POST   /categories/:id/filter                   {:controller=>"categories", :action=>"filter"}
   formatted_filter_category POST   /categories/:id/filter.:format           {:controller=>"categories", :action=>"filter"}
+2
5

Javascript HTTP-.

def filter
  @category = Category.find(params[:category])
  @category_id = @category.id
  @projects = @category.projects.find(:all)

  respond_to do |format|
    format.js # filter.rjs
  end    
end

, , , :

respond_to do |format|
  format.html # filter.html.erb
  format.js # filter.rjs
end    

. filter.rjs, :

page.replace_html :id_of_element_to_replace_html, :partial => "name_of_partial"
+6

, . , filter_category_path - (: ) .

, JavaScript, _?

Firebug, - Ajax-?

- .log?

+1
  def observe_category_select
    observe_field(
                  :category,
                  :url        =>  filter_category_path(:id),
                  :with       =>  :category_id,
                  :on         =>  :onchange,
                  :update     =>  :projects
    )
  end

The: onchange is gotcha - , . EDIT: , .

reset, ​​ :

<%= link_to_function "close category", :title => 'close category' do |page| 
        page.select("#category").each do |element|
            element.value = "Choose Category"
            page << "window.fireEvent($(\"category\"), 'change');"
        end
        page.replace_html :projects, "<li></li>" 
    end-%>

, , ul li, . FireEvent , , .

, :

 def filter
  begin        
    @category = Category.find(params[:category])
    @category_id = @category.id
    @projects = @category.projects.find(:all)
  rescue
    @category = "choose"
  end
  render :layout => false
 end

, @category

<% if @category.eql?('choose') %>
  <li>choose category</li>
<% else %>
 # loop through projects returning them wrapped in li tags
<% end %>

, .

+1

. onchange select:

<%= select_tag @procuct, 
        options_for_select(
            @product.properties.map {|property| [property.name, property.id]}),
        :onchange => "HERE_A_CALL_TO_YOUR_JS_FUNCTION();" %>

UPDATE: Ajax JS-, onchange, , JS- "native Rails".

0

FWIW. - , , routes.rb( , , ).

, a: collection = > {: filter = > : get} (, map.resource: categories,: collection = > {: filter = > : get}).

, - .

0
source

Source: https://habr.com/ru/post/1703705/


All Articles