开发者

Ruby on Rails nested dynamic fields

开发者 https://www.devze.com 2022-12-20 21:47 出处:网络
I have a problem to find the right way to program dynamic fields. For example: I have two radio buttons and depending on how the user selects one radio button, it extends the form with different field

I have a problem to find the right way to program dynamic fields. For example: I have two radio buttons and depending on how the user selects one radio button, it extends the form with different fields.

Start form: - Radio button: car - Radio button: ship - Text field: name

If the user clicks on the radio button "car" the form gets extended with text fields like eg. "engine", "color" and if the user selects the radio button "ship" the form gets extended with text fields like "length", "weight". The attributes engine, color, length, weight are fields in the DB on table machine.

My problem is, what happens if the validation returns errors. How can i use partials to solve my problem. I have tried remote_function (to replace html parts), partials and rjs but rails returns me NameErrors!

My form looks like this:

<% form_for(@komplex_object, :url => some_url) do |f| %>
    <%= f.error_messages %> 
    <% f.fields_for :machine do |machine_f| %>
        <%= machine_f.radio_button :kind, 'car', :onclick => some_request_or_javascript, :checked => true -%> Car
        <%= machine_f.radio_button :kind, 'ship', :onclick => some_request_or_javascript -%> Ship       
        <div id="dynamic_fields">
            <% render :partial => 'car', :locals => { :f => machine_f } %>
        </div>
    <% end %>

    <p><%= f.label :name %>
    <%= f.text_field :name %></p>
    ...
<% end %>

Attention: the machine attributes are nested within the komplex_object form!

And here the partials:

# _car.html.erb
<p><%= f.label :engine %>
<%= f.text_field :engine %></p>
<p><%= f.label :color %>
<%= f.text_field :color %></p>

# _ship.html.erb
<p><%= f.label :length %>
<%= f.text_field :length %></p>
<p><%= f.label :weight %>
<%= f.text_field :weight %></p>

In the form i have write "some_request_or_javascript" and here I have test different solutions like javascript thats hides and shows two different div's that contains the car or ship fields. This solution runs but on submit sends all hash fields and not only these fields that the user have selected with the radio button. Second problem: how to recognise the right fields if submit returns validation errors?

Another solution is to use remote_function (that calls eg. check_fields) and part开发者_JS百科ials (CODE POSTED ABOVE)! With this solutions i get NameErros on the rjs because the page.replace_html function

# controller function that remote function calls
# Ajax update for the right fields
def check_fields
  respond_to do |format|
          format.js { render :action => params[:kind] }
  end
end 

# ship.js.rjs
page.replace 'dynamic_fields', :partial => 'ship'

don't understand the "f" in the partial _ship.html.erb!

Any idea? thx in advance


To start with. 'f' is the name of the form. In the case of your partials, the first form is the overall form for a "komplex_object".

Then, you have a sub-form that is your "machine_f" form. In the partial, you then pass that secondary form to the partial as a new local-variable that is also called "f" (in the sub-partial) by using:

:locals => { :f => machine_f }

The, the partial just has a variable called "f" which is what you add all the fields to.


Secondly. All your form opening/closing woes should be solvable with javascript only.

The best way to solve this is to start with all the forms present and visible on the page (ie both what should be displayed if the user clicks "car" and what should be displayed if the user clicks "ship".

Then use a javascript function to hide the one that is not currently relevant. eg it will look at the radio buttons - if the "radio-ship" button is clicked, then the js hides the "car partial" and vice versa.

This also has the added benefit that, if somebody doesn't have javascript (or it breaks) then at least it will fail-useful instead of failing-useless.

Let me know if that's enough for you to go o with - but that is the overall basis of your solution.


Thirdly, the reason why you have a problem with errors is that you are displaying them all in one big chunk at the top of the page - getting all the errors for the "komplex_object" as well as the associated objects all in one big blob.

You can actually put error messages for a specific sub-model (eg the car or the ship) in the sub-form.

Have a look into "error_messages_for" instead of "f.error_messages"

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号