Vitalyp
Vitalyp

Reputation: 1089

Markup or Trick? Nested forms

There are interesting task: my active record 'Event' entity can contain one 'Attachment' PDF file. On the Create Event page, user can Upload this attachment BEFORE Submits that Event. Attachment uploads to Amazon via Ajax, progress-bar displays etc blablabla. It should be displayed in_a_way:

= form_for @event do |e|
  = e.text_field :name

  = form_for @attach, :remote=>true, html=>{:multipart=>true} do |at|
    = at.file_field :pdf, :accept=>"pdf", :size=>"1"
    = at.submit

  = e.submit

Yes, this is just pseudo-code, and I don't mind how it can work, but the main idea is presents: [Submit Attachment] button should be placed inside the Event form. How I can implement it? Maybe, just make some offset to nested Attachment form so it will be displayed inside Event form, or there are any others solutions?

......................................................php_vs_rails....................................................

Upvotes: 0

Views: 156

Answers (1)

Vitalyp
Vitalyp

Reputation: 1089

Solution: override form headers This is a form for creating new event. Inside this form, we need ajax file uploading. There is a solution: mixing single form between two different types of submits: ajax(js) and html:

= form_for @event, html=>{:multipart=>true} do |e|
  = e.text_field :name

  = file_field_tag "attach[pdf]", :id=>"attach_pdf", :accept => "pdf", :maxlength => "200"
  = submit_tag "", :id => "ajax_submit", :style=>"display:none"

  = e.submit    <!-- id = "new_event_submit" -->

////////////////////////////
// before 'submits' call override functions:

$("#ajax_submit").click(function(){
    prepeareFormForAjax();
    return true;
});

$("#new_event_submit").click(function(){
  prepeareFormForHtml();
  return true;
});

//////////////////////////////
// to store original (previous, html) form data
var html_form_action = "";
var html_form_method = "";
///////////////////////////////

/* 
 * To ajax file upload:
 **/
function prepeareFormForAjax() {
  $("form").attr("data-remote", "true");
  $("form").attr("enctype", "multipart/form-data");  

  html_form_action = $("form").attr("action");  // save old action
  $("form").attr("action", "/attach");            // I need /nors action

  //_method field is a hidden form field, maybe you have it too on the page:
  if ($('input[name="_method"]').length != 0) {
    html_form_method = $('input[name="_method"]').val();
    $('input[name="_method"]').val("post");
  }

}

function prepeareFormForHtml() {
  $("form").removeAttr("data-remote");
  $("form").removeAttr("enctype");
  if (html_form_action != "") {
    $("form").attr("action", html_form_action);
    html_form_action = "";
  }
  if (html_form_method != "") {
    $('input[name="_method"]').val(html_form_method);
    html_form_method = "";
  }
}

///////////////////////

Now, to upload file via AJAX use:

$("#ajax_submit").click();

any questions?

Upvotes: 1

Related Questions