stig Garet
stig Garet

Reputation: 564

Using AJAX to insert a partial form

I'm doing a complex and heavy form in my app. So to increase the performance, I would like to inject some part of this form with an AJAX method. But I cannot succeed it.

To illustrate it, I made this simple example =

new_event (view) :

<%= simple_form_for event, remote: true do |f| %>
    <%= f.input_field :start_at %>
    <div class="">

    </div>
    <a href="/event_add_user?form=<%=f%>" class="btn" data-method="patch" data-remote="true">
        Add user to event
    </a>
    <div class="form_area"></div>
<% end %>

event_controller (controller) :

def add_user
    @form = params[:form]
    respond_to do |format|
       format.js {render 'add_user'}
    end
end

add_user.js.erb (js file) :

$('#event_form_area').append('<%=  j render partial: "events/user", locals: {f: @form} %>');

user (partial) :

<%= f.input_field :user_name %>

Currently, I have this error :

ActionView::Template::Error (undefined method `input' for "":String)

Upvotes: 1

Views: 879

Answers (2)

neume
neume

Reputation: 186

You are passing @form as f in your partial view. Most likely, params[:form] is a string. Here are some of the ways to approach this problem.

1. Recreate form object

Since you don't have f object from your previous request, you can recreate it to generate an html snippet. Instead of retrieving form object from params which I think is impossible, you can create a new form object using a new Event object. I haven't tested this in rails but this should give you the idea.

def add_user
  @event = Event.new
  respond_to do |format|
    format.js {render 'add_user'}
  end
end

Set @user as locals

$('#event_form_area').append('<%=  j render partial: "events/user", locals: {event: @event} %>');

Then recreate the form object

# partial
<% form_for event do |f| %>
  <%= f.input_field :user_name %>
<% end %>

Notice the usage of <% instead of <%= on the first line. We don't want to have another <form> element.

Then, you're done. This code should generate html snippets

or 2. Use plain html

In your partial, rewrite your code to a plain html element. For example

<input class="form-control" type="text" name="event[user_name]" id="event_user_name">

Upvotes: 2

Getu
Getu

Reputation: 179

you're trying to pass the entire form builder f through params, which I don't think it's possible.

Since f.input_field is just a helper method to output some HTML, an idea would be to implement directly that HTML into the partial.

so, the "events/user" partial would be:

<input class="string required" id="event_user" maxlength="100" name="event[user]" type="text" value="" />

if this works, you can remove @form = params[:form] from the controller, the locals hash from the view and the ?form=<%=f%> from the AJAX call since aren't needed anymore.

input_field reference at rubydoc

You can also use form_tag helpers too:

<%= text_field_tag(:event,:user) %>

Upvotes: 2

Related Questions