views:

19

answers:

1

I have a page form, where i want the user to add nested forms by clicking on a remote link ('add photo', f. ex). Upon clicking the button I inject the nested forms with RJS. The injected forms are remote forms, but after injection the forms have no javascript events attached so they just submit with http to the controller of the nested object. Beside that, everything works fine.

My question is:

Is it possible to trigger revalidation of javascript of remote forms via RJS, after injection??

That way my nested forms would get the proper javascript event handling and submit with AJAX.

My page form (_form.html.erb):

<% javascript 'ckeditor/ckeditor' %>

<%= form_for @page, :html => { :multipart => true } do |f| %>
  <%= f.error_messages %>
  <p>
    <%= f.label :active %><br />
    <%= f.check_box :active %>
  </p>
  <p>
    <%= f.label :homepage %><br />
    <%= f.check_box :homepage %>
  </p>
  <p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </p>
  <p>
    <%= f.label :description %><br />
    <%= f.text_area :description, :rows => 5, :cols => 80 %>
  </p>
  <p>
    <%= f.label :text %><br />
    <%= f.text_area :text, :class => 'html' %>
  </p>
  <p>
    <%= f.label :picture_class %><br />
    <%= f.select :picture_class, ['left','right','full'] %>
  </p>

 <% unless @page.new_record? %>
  <h2>Photos</h2>
  <%= link_to 'Add photo', add_photo_page_url(@page), :remote => true %>
  <div id="photos">
  <%= render :partial => 'shared/forms/photo', :collection => @page.photos %>
  </div>
  <h2>Snippets</h2>
  <%= link_to 'Add snippet', add_snippet_page_url(@page), :remote => true %>
  <div id="snippets">
  <%= render :partial => 'shared/forms/photo', :collection => @page.snippets %>
  </div>
  <h2>Downloads</h2>
  <%= link_to 'Add download', add_download_page_url(@page), :remote => true %>
  <div id="downloads">
  <%= render :partial => 'shared/forms/download', :collection => @page.downloads %>
  </div>
  <h2>Paragraphs</h2>
  <%= link_to 'Add paragraph', add_paragraph_page_url(@page), :remote => true %>
  <div id="paragraphs">
  <%= render :partial => 'shared/forms/paragraph', :collection => @page.paragraphs %>
  </div>
 <% end %>

  <p><%= f.submit %></p>
<% end %>

<%= javascript_tag 'CKEDITOR.replaceAll("html");' %>

Controller code to build the nested photo object: (page_controller.rb):

def add_photo
  @page = Page.find(params[:id])
  @photo = @page.photos.build
end

RJS code that gets executed by clicking 'add photo' (add_photo.js.rjs):

page.insert_html :bottom, :photos, :partial => 'shared/forms/photo', :object => @photo
page.visual_effect :highlight, :photos, :duration => 2

The partial/form that gets injected with RJS (_photo.html.erb):

<%= form_for [@page, photo], :remote => true do |f| %>
<p>
  <%= f.check_box :active %>
  <%= f.text_field :name %>
  <%= f.file_field :photo %>
  <%= f.submit 'Save' %>
</p>
<% end %>

Any help would be appreciated. I would like to solve this with nested forms (not nested attributes) and RJS, but was unable to google my way to documentation on this.

Thanks!!

-- Jakob

A: 

If you want to stick with RJS, you'll need to look into the built-in javascript to see how they're registering everything. They probably just do it on DOM ready and bind to the submit() event. It's most likely encapsulated in a method which looks for anything marked :remote => true and binds to the submit() event so it will submit via AJAX. You can execute the same logic but isolate it to your new form. So maybe your partial could have a JavaScript tag which executes that logic for that form, based on the id, or based on the classname, ignoring everything but the most recently added form.

Samo