Active Admin - 根据第一个下拉列表Ruby on Rails刷新第二个下拉列表

Ast*_*tha 14 ruby sqlite ruby-on-rails activeadmin drop-down-menu

我在Ruby on Rails上使用Active Admin Gem.我有一个表格,其中我选择了类别和子类别,然后我必须填写数据.所以我在sqlite中创建了两个在活动管理资源中添加的表.

每件事情都运行良好,但子类别的下拉不会根据选择的类别进行过滤.

我也是Ruby和RoR的新手.我不知道如何在选择类别后刷新子类别的下拉列表.

我知道我可以从AJAX和javascript中做到这一点,但我不知道在哪里编码?

此外,Active Admin中是否有任何特定的过滤器可以在没有ajax或javascript的情况下实现.

任何想法或帮助将受到高度赞赏.

okl*_*liv 18

我不知道在Active Admin中是否有任何特定的过滤器可用,但我用这3个步骤解决了它(假设类别 - 是一个房子,子类别 - 是一个单位):

第一步:定义包含ajax请求的帮助程序

(当然,你必须path在routes.rb中预定义)

#application_helper.rb
def remote_request(type, path, params={}, target_tag_id)
  "$.#{type}('#{path}',
             {#{params.collect { |p| "#{p[0]}: #{p[1]}" }.join(", ")}},
             function(data) {$('##{target_tag_id}').html(data);}
   );"
end
Run Code Online (Sandbox Code Playgroud)

第二步:添加此方法以:onchange采取行动

#admin/inhabitants.rb (DSL with formtastic)

form do |f|
  f.inputs do
  #...
    f.input :house, :input_html => {
        :onchange => remote_request(:post, :change_flats, {:house_id=>"$('#house_id').val()"}, :flat_id)
    }
    f.input :flat
  #...
  end
end
Run Code Online (Sandbox Code Playgroud)

第3步:渲染过滤结果

(你可以渲染部分而不是:text,我决定把它留在一个activeadmin资源文件中)

controller do
  def change_flats
    @flats = House.find_by_id(params[:house_id]).try(:flats)
    render :text=>view_context.options_from_collection_for_select(@flats, :id, :flat_number)
  end
end
Run Code Online (Sandbox Code Playgroud)


Who*_*hoa 12

我完成了这个任务,因为任何在rails项目上工作的非rails开发人员都会 - 快速而肮脏.这是如何做:

#...
f.input :user, :input_html => {
  :onchange => "
    var user = $(this).val();

    $('#order_location_id').val(0).find('option').each(function(){
      var $option = $(this),
        isCorrectUser = ($option.attr('data-user') === user);  

        $option.prop('disabled',!isCorrectUser);
    });
  "
}
f.input :location, collection: Location.all.map{ |loc|
  [loc.name,loc.id, {"data-user" => loc.user_id}]
}
#...
Run Code Online (Sandbox Code Playgroud)

不需要AJAX.请注意,这不会删除不需要的选项,它只是禁用它们(足够我的方案).这可以通过帮助器轻松实现模块化,但我实际上只需要一次功能.


Rya*_*lay 6

对于其他遇到同样问题的人,请看看这个railscast

我在这里遇到了同样的问题

这是我在activeadmin中实现多个动态选择菜单的方法:

配置/初始化/ active_admin.rb

  config.register_javascript 'exam_registrations.js.coffee'
Run Code Online (Sandbox Code Playgroud)

应用程序/管理/ exam_registrations.rb

  form do |f|
    f.inputs "Exam Registration Details" do
      f.input :user_id, :label => 'Teacher', :as => :select, :collection => User.where(:admin => 'false', :active => true).order(:name), :include_blank => true
      f.input :student_id, :hint => 'Students grouped by teacher names', :as => :select, :collection => option_groups_from_collection_for_select(User.where(:admin => false, :active => true).order(:name), :students, :name, :id, :name)
      f.input :lesson_id, :hint => 'Lessons grouped by student names', :as => :select, :collection => option_groups_from_collection_for_select(Student.where(:active => true).order(:name), :lessons, :name, :id, :name)
    end
    f.buttons
  end
Run Code Online (Sandbox Code Playgroud)

应用程序/资产/ JavaScript的/ exam_registrations.js.coffee

#first menu    
jQuery ->
      $('#exam_registration_student_id').parent().hide()
      students = $('#exam_registration_student_id').html()
      $('#exam_registration_user_id').change ->
        user = $('#exam_registration_user_id :selected').text()
        escaped_user = user.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1')
        options = $(students).filter("optgroup[label='#{escaped_user}']").html()
        if options
          $('#exam_registration_student_id').html(options)
          $('#exam_registration_student_id').parent().show()
        else
          $('#exam_registration_student_id').empty()
          $('#exam_registration_lesson_id').empty()

# second menu
  $('#exam_registration_lesson_id').parent().hide()
  lessons = $('#exam_registration_lesson_id').html()
  $('#exam_registration_student_id').click ->
    student = $('#exam_registration_student_id :selected').text()
    escaped_student = student.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1')
    options = $(lessons).filter("optgroup[label='#{escaped_student}']").html()
    if options
      $('#exam_registration_lesson_id').html(options)
      $('#exam_registration_lesson_id').parent().show()
    else
      $('#exam_registration_lesson_id').empty()
Run Code Online (Sandbox Code Playgroud)

重启服务器,菜单工作!