ExiRe
ExiRe

Reputation: 4767

Rails 2 and ajax - few select lists

I can't figure what i do wrong. I have few select lists:

How it should works:

  1. User selects region.
  2. List of towns loads.
  3. User selects town.
  4. List of organizations loads.
  5. User chooses organization.

I use ajax for that and i realized only auto-loading for list of towns and i can't do same thing for organization. Second select list DOESN'T POST at all!

Here is my code:

View

%div
  %br/
  = select 'ajax', :region_id, [['Choose your region...', -1]] + Region.all.map{|region| [region.name, region.id]}.sort
  = image_tag('ajax-loader.gif', :id => 'ajax-progress', :style => 'display: none;')
  = observe_field :ajax_region_id, :url => { :controller => :organizations, :action => :list_towns, :preselect => (defined?(preselect) && !preselect.nil?) }, :with => 'region_id', :update => 'select_organization_idd', :loading => '$("ajax-progress").show();', :complete => 'if (Ajax.activeRequestCount == 1) $("ajax-progress").hide();'
  %br/
  = select 'ajax2', :o_id, [], {}, {:id => 'select_organization_idd', :style => 'width: 60em;'}
  = image_tag('ajax-loader.gif', :id => 'ajax-progress', :style => 'display: none;')
  = observe_field :ajax_region2_id, :url => { :controller => :organizations, :action => :list_region, :preselect => (defined?(preselect) && !preselect.nil?) }, :with => 'o_id', :update => 'select_organization_idd2', :loading => '$("ajax-progress").show();', :complete => 'if (Ajax.activeRequestCount == 1) $("ajax-progress").hide();'

  = f.select :organization_id, [], {}, {:id => 'select_organization_idd2', :style => 'width: 60em;'}

Controller

  def list_region
    render :text => ActionController::Base.helpers.options_for_select((params[:preselect] ? [['Choose organization', -1]] : []) + Organization.map{|org| [ActionController::Base.helpers.truncate(org.name, :length => 155), org.id]})
  end

  def list_towns
    region = Region.find(params[:region_id])
    towns = Kladr.find(:all, :conditions => ['code LIKE ?', "#{region.code}%"])
    render :text => ActionController::Base.helpers.options_for_select([['Choose town', -1]] + towns.map{ |t| ["#{t.socr}. #{t.name}", t.id] })
  end

What do i do wrong? Also i use Rails 2, that why observe_field is not deprecated.

Upvotes: 0

Views: 247

Answers (1)

Dougui
Dougui

Reputation: 7230

Do you use rails 3? The method observe_field is deprecated.

With rails 3 you must do something like this :

view

%div
  %br/
  = select 'ajax', :region_id, [['Choose your region...', -1]] + Region.all.map{|region| [region.name, region.id]}.sort, {}, {:id => 'ajax1'}
  = image_tag('ajax-loader.gif', :id => 'ajax-progress', :style => 'display: none;')
  %br/
  = select 'ajax2', :o_id, [], {}, {:id => 'select_organization_idd', :style => 'width: 60em;'}, {}, {:id => 'ajax2'}
  = image_tag('ajax-loader.gif', :id => 'ajax-progress', :style => 'display: none;')

  = f.select :organization_id, [], {}, {:id => 'select_organization_idd2', :style => 'width: 60em;'}

javascript.js.coffee

$('#ajax1').change = () ->
  $.post(
    url: '/organizations/list_towns'
    data: {value: $('#ajax1').val()}
    success: () ->
      if (Ajax.activeRequestCount == 1) 
        $("ajax-progress").hide()
  )

$('#ajax2').change = () ->
  $.post(
    url: '/organizations/list_regions'
    data: {value: $('#ajax2').val()}
    success: () ->
      if (Ajax.activeRequestCount == 1) 
        $("ajax-progress").hide()
  )

The implementation is probably wrong and could be refactored. I didn't test it. But you've got the idea.

Upvotes: 1

Related Questions