1

Mon environnement de travail actuel est Rails 2.3.8 (diverses raisons pour lesquelles mon entreprise n'a pas déménagé à Rails 3). J'essaie de mettre à jour des éléments d'un formulaire multi-modèle via des appels AJAX - l'idée étant de remplacer certaines listes déroulantes en fonction de la façon dont l'utilisateur sélectionne ou remplit d'autres champs. J'ai déjà réussi à faire fonctionner cela en utilisant des partiels non formels - le problème que j'ai maintenant est de reproduire la mise à jour AJAX des listes déroulantes select lorsque les partiels sont basés sur form_for et fields_for.Ajax mise à jour de accept_nested_attributes_for partials

Désolé pour le mur de texte suivant - J'ai essayé de le réduire autant que possible (le code lui-même fonctionne sur mon site de test).

Comment puis-je générer les éléments du générateur de formulaires dans le contrôleur d'épidémies, puis le transmettre à la catégorie partielle pour remplacer event_form?

Tous les pointeurs serait génial: D

modèles

class Outbreak < ActiveRecord::Base 
     has_many :incidents, :dependent => :destroy 
     has_many :locations, :through => :incidents 

    accepts_nested_attributes_for :locations, :allow_destroy => true, :reject_if => :all_blank 
    accepts_nested_attributes_for :incidents, :allow_destroy => true, :reject_if => :all_blank 
end 

class Incident < ActiveRecord::Base 
    belongs_to :outbreak 
    belongs_to :location 
    belongs_to :category 
    belongs_to :subcategory 
    belongs_to :subtype 

end 

class Location < ActiveRecord::Base 
    has_many :incidents, :dependent => :destroy 
    has_many :outbreaks, :thorugh => incidents 
end 

Vues

_form

<% form_for(@outbreak, :html => {:multipart => true}) do |form| %> 

    <%= render :partial => 'outbreak_type_select', :locals => {:outbreak_types => @outbreak_types, :f => form } %> 
    <% form.fields_for :incidents do |incident_form| %> 
     <%= render :partial => 'category_select', :locals => {:categories => @categories, :incident_form => incident_form} %> 
     <%= render :partial => 'subcategory_select', :locals => { :subcategories => @subcategories, :incident_form => incident_form } %> 

    <% end %> 
<% end %> 

_outbreak_type_select

<% with_str = "'outbreak_type=' + value " %> 
<% if @outbreak.id %> 
<% with_str << "+ '&id=' + #{outbreak.id}" %> 
<% end %> 
<%= f.collection_select(:outbreak_type, @outbreak_types, :property_value, :property_value, {}, {:onchange => "#{remote_function(:url => { :action => "update_select_menus"}, :with => with_str)}"} ) %> 

_category_select

Après avoir appelé update_select_menus comment générer le incident_form

<%= incident_form.collection_select(:category_id, @categories, :id, :name, {:prompt => "Select a category"}, {:onchange => "#{remote_function(:url => { :action => "update_subcategory"}, :with => "'category_id='+value")}"}) %> 

RJS

begin 
    page.replace_html 'outbreak_transmission_div', :partial => 'outbreaks/transmission_mode_select', :locals => {:transmission_modes => @transmission_modes } 
    rescue 
    page.insert_html :bottom, 'ajax_error', '<p>Error :: transmission modes update select</p>' 
    page.show 'ajax_error' 
    end 
    begin 
    page.replace_html 'incident_category_select', :partial => 'outbreaks/category_select', :locals => { :categories => @categories } 
    rescue 
    page.insert_html :bottom, 'ajax_error', '<p>Error :: incident category update select</p>' 
    page.show 'ajax_error' 
    end 

Contrôleurs

Flambée

def new 
     @outbreak = Outbreak.new 

     @outbreak.incidents.build 
     @outbreak.locations.build 

     #just the contents for the dropdowns 
     @categories = Category.find(:all, :conditions => {:outbreak_type => "FOODBORNE"}, :order => "outbreak_type ASC") 
     @subcategories = Subcategory.find(:all, :order => "category_id ASC") 

    end 

    def update_select_menus 
     @outbreak_type = params[:outbreak_type].strip 
     if params[:id] 
     @outbreak = Outbreak.find(params[:id]) 
     else 
     @outbreak = Outbreak.new 
     @outbreak.incidents.build 
       @outbreak.locations.build  
     end 

     if @outbreak_type == "FOODBORNE" 
      ob_type_query = "OUTBREAKS:TRANSMISSION_MODE:" << @outbreak_type 
      @transmission_modes = Property.find(:all, :conditions => {:field => ob_type_query}) 

      ob_type_query = "INVESTIGATIONS:CATEGORY:" << @outbreak_type 
      @sample_types = Property.find(:all, :conditions => {:field => ob_type_query}) 
      @categories = Category.find(:all, :conditions => { :outbreak_type => "FOODBORNE"}) 
      @subcategories = Subcategory.find(:all, :conditions => { :category_id => @categories.first.id}) 
      @subtypes = Subtype.find(:all, :conditions => { :subcategory_id => @subcategories.first.id}) 
     elsif @outbreak_type == "NON-FOODBORNE" 
      ob_type_query = "OUTBREAKS:TRANSMISSION_MODE:" << @outbreak_type 
      @transmission_modes = Property.find(:all, :conditions => {:field => ob_type_query}) 

      ob_type_query = "INVESTIGATIONS:CATEGORY:" << @outbreak_type 
      @sample_types = Property.find(:all, :conditions => {:field => ob_type_query}) 
      @categories = Category.find(:all, :conditions => { :outbreak_type => "NON-FOODBORNE"}) 
      @subcategories = Subcategory.find(:all, :conditions => { :category_id => @categories.first.id}) 
      @subtypes = Subtype.find(:all, :conditions => { :subcategory_id => @subcategories.first.id}) 
    end 

    respond_to do |format| 
      format.html 
      format.js 
     end 

    end 

Répondre

1

trouvé un travail autour basé sur http://www.treibstofff.de/2009/07/12/ruby-on-rails-23-nested-attributes-with-ajax-support/

Cela devrait probablement aller dans aide Outbreak (dans le contrôleur Éclosion atm)

def update_select_menus 
     @outbreak_type = params[:outbreak_type].strip 
     #next_child_index will only be used if 
     @next_child_index ? params[:next_child_index] : 0 
     if params[:id] 
     @outbreak = Outbreak.find(params[:id]) 
     else 
     @outbreak = Outbreak.new 
     @outbreak.risks.build 
     @outbreak.incidents.build 
     @outbreak.locations.build 

     end 

     if @outbreak_type == "FOODBORNE" 
      ob_type_query = "OUTBREAKS:TRANSMISSION_MODE:" << @outbreak_type 
      @transmission_modes = Property.find(:all, :conditions => {:field => ob_type_query}) 

      ob_type_query = "INVESTIGATIONS:CATEGORY:" << @outbreak_type 

      @sample_types = Property.find(:all, :conditions => {:field => ob_type_query}) 
      @categories = Category.find(:all, :conditions => { :outbreak_type => "FOODBORNE"}) 
      @subcategories = Subcategory.find(:all, :conditions => { :category_id => @categories.first.id}) 
      @subtypes = Subtype.find(:all, :conditions => { :subcategory_id => @subcategories.first.id}) 


     elsif @outbreak_type == "NON-FOODBORNE" 
      ob_type_query = "OUTBREAKS:TRANSMISSION_MODE:" << @outbreak_type 
      @transmission_modes = Property.find(:all, :conditions => {:field => ob_type_query}) 

      ob_type_query = "INVESTIGATIONS:CATEGORY:" << @outbreak_type 

      @sample_types = Property.find(:all, :conditions => {:field => ob_type_query}) 
      @categories = Category.find(:all, :conditions => { :outbreak_type => "NON-FOODBORNE"}) 
      @subcategories = Subcategory.find(:all, :conditions => { :category_id => @categories.first.id}) 
      @subtypes = Subtype.find(:all, :conditions => { :subcategory_id => @subcategories.first.id}) 
    end 

    @pathogen_types = Property.find(:all, :conditions => {:field => "PATHOGENS:CATEGORY"}) 
    @outbreak_types = Property.find(:all, :conditions => {:field => "OUTBREAKS:OUTBREAK_TYPE"}) 


    render :update do |page| 
     page.replace 'outbreak_transmission_div', :partial => 'transmission_mode_select_update' 
     page.replace 'incident_category_select', :partial => 'incident_category_select_update' 
     page.replace 'incident_subcategory_select', :partial => 'incident_subcategory_select_update' 
     page.replace 'incident_subtype_select', :partial => 'incident_subtype_select_update' 
    end  

    end 

Dans la vue Outbreak (bien que depuis cette partie est liée à un incident, il devrait probablement aller dans cette vue à la place)

<% ActionView::Helpers::FormBuilder.new(:outbreak, @outbreak, @template, {}, proc{}).fields_for :incidents,{:child_index => @next_child_index} do |this_form| %> 
<div id="incident_category_select"> 
<%= render :partial => 'category_select', :locals => {:incident_form => this_form } %> 
</div> 
<% end %> 

ActionView :: Helpers :: FormBuilder est utilisé pour produire le Champs obligatoires_forformulaire - L'article du site Web passe en revue ces informations plus en détail.

L'indice résultant est réglé par la variable d'@next_child_index qui peut être transmis au dispositif de commande par l'appel AJAX original (par exemple @next_child_index = 1, la forme résultante nom de l'élément sera foyer [incidents_attributes] [1] [category_id]) - Je ne l'ai pas utilisé dans cet exemple car, bien qu'à l'avenir, je souhaite que le formulaire prenne en charge plus d'un emplacement par flambée, il n'acceptera qu'un seul emplacement - Incident par flambée.

_category_select.erb partielle (en vue Foyer atm)

<% with_str = "'category_id=' + value " %> 
<% if @outbreak.id %> 
<% with_str << "+ '&id=' + #{@outbreak.id}" %> 
<% end %> 
<%= incident_form.collection_select(:category_id, @categories, :id, :name, {:prompt => "Select a category"}, {:onchange => "#{remote_function(:url => { :action => "update_subcategory"}, :with => with_str)}"}) %> 

Le with_str est juste de passer éventuellement l'identifiant du foyer si elle existe à l'unité de commande pour trouver l'enregistrement sur ce foyer pour produire la forme et sinon créer une nouvelle épidémie et les attributs imbriqués associés, tels que Incidents et Emplacements.

Les manières doivent être plus nettes de faire ceci - en particulier le FormHelper et en passant l'id d'épidémie par l'option avec la chaîne.

+0

D'où avez-vous obtenu la variable @template? Im essayant d'implémenter ceci mais ai un problème avec le modèle [consultez mon article pour plus d'informations] (http://stackoverflow.com/questions/7272814/passing-actionviewhelpersformbuilder-to-a-partial) – jalagrange

+0

Think '@template 'est une variable par défaut générée par l'application Rails 2.3. Si vous utilisez Rails 3> alors @template sera nul et vous devrez peut-être jeter un oeil à view_context http://stackoverflow.com/questions/3300582/rails-3-template-variable-inside-controllers-is- néant – Pasted

Questions connexes