Использование response_to ... format.json и jQuery Form Plugin от malsup - PullRequest
5 голосов
/ 09 февраля 2010

У меня возникли небольшие проблемы с настройкой jQuery Form Plugin для правильной работы с полем загрузки файла. Когда я использую плагин для отправки формы без поля загрузки файла, часть format.json блока respond_to do |format| вызывается правильно. Однако, добавив поле загрузки файла, он выполняет только часть format.html, которая заставляет мой код JavaScript думать, что произошла ошибка.

Кто-нибудь сталкивался с этим раньше или знает способ заставить плагин всегда использовать json? В качестве альтернативы, можно ли изменить URL-адрес, который использует плагин, чтобы заставить Rails визуализировать json?

Большое спасибо за любую помощь! Код ниже:

# app/controllers/details_controller.rb
def create
  @detail = Detail.new(params[:detail])

  style = params[:detail_style].to_sym || :thumb
  data = { :id => '5', :url => 'test.rails' }

  respond_to do |format|
    if @detail.save
      flash[:notice] = 'Your image has been saved.'
      data = { :id => @detail.id, :url => @detail.data.url(style) }

      format.html { redirect_to :action => 'index' }
      format.json { render :json => "<textarea>#{data.to_json}</textarea>", :status => :created }
    else
      format.html { render :action => 'new' }
      format.json { render :json => @detail.errors, :status => :unprocessable_entity }
    end
  end
end

/* app/views/sidebar/_details.html.erb (excerpt) */

<% form_for(Detail.new, :html => { :multipart => true } ) do |f| %>
  <%= hidden_field_tag 'detail_style', 'thumb' %>

  <%= f.label :image, "Recent Images" %>
  <%= f.file_field :image%>

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

<script>
$(document).ready(function() {
  var options = {
    dataType: 'json',

    success: function(json, statusText) {
      console.log("success: " + json);
    },

    error: function(xhr, statusText, errorThrown) {
      console.log("error: " + xhr.responseText);
    }
  };

  $('#new_detail').ajaxForm(options);
});

Ответы [ 5 ]

7 голосов
/ 17 сентября 2010

Для того, чтобы плагин jQuery Form работал для загрузки файлов с ответом JSON, требуется несколько вещей. В javascript параметры для .ajaxForm должны иметь:

dataType: 'json', // evaluate return as JSON

Браузер должен указать действию Rails, чтобы оно возвращало контент в формате JSON, Один из способов сделать это - добавить скрытое поле ввода формата в шаблон формы загрузки файла:

<%= hidden_field_tag 'format', 'json' %>

Затем действие Rails запустит метод format.json внутри блока response_to.

В действии сервера

  • инкапсулирует JSON в тег, .ajaxForm правильно развернет строку и вернет JSON
  • установить тип возвращаемого содержимого «text / html», в противном случае некоторые браузеры (Firefox) попытается загрузить возврат в файл.

, например

  respond_to do |format|
    format.json {
          render :json => "<textarea>#{data.to_json}</textarea>", :content_type => "text/html"
    }
  }
2 голосов
/ 26 января 2011

Я сделал обходной путь для этой проблемы. Я тестировал это решение только с Rails 3, но, возможно, оно работает и для 2.3.x

Решение очень простое:

!#javascript

$('form#my_form').live('submit',function(){ 
 $(this).ajaxForm({ dataType: "script", success: processJson})
 return false;
})

//data arrive as a string but we can parse it correctly

function processJson(data, statusText, xhr, $form){
 my_data_parsed = JSON.parse(data); 

  }

!#ruby 
def create
....   
render :js =>  { :status => false,:messages => @myobject.errors.full_messages}.to_json 

end 
1 голос
/ 11 февраля 2010

Я до сих пор не уверен, почему это не работает, но я попробовал много вещей и, наконец, нашел решение.

Я попытался изменить URL, добавив .json в конец, что заставило Rails отрендерить блок format.json, но это сбило с толку мой браузер, заставив его подумать, что я хочу скачать файл.

Итак, я попытался изменить URL-адрес, передав параметр ?format=json, который, к сожалению, сделал то же самое.

В конце концов, я попытался изменить format.json на format.js (Javascript) и добавить .js к URL-адресу, но все еще используя тот же render :json => ..., который был у меня ранее, вместе с установкой параметра dataType мой вызов jQuery на json. Похоже, это работает, хотя это не самое оптимальное решение.

Я надеюсь, что кто-то еще найдет это полезным. Я отправлю еще раз, если найду правильный ответ. А пока, если у кого-то еще есть правильный ответ, дайте мне знать, и я приму ваш!

1 голос
/ 30 мая 2010

Очевидно, что настройка заголовка Accept невозможна, когда используется ajaxSubmit и файл загружен.

Смотрите ответ malsup в этой теме здесь .

Он говорит:

При загрузке файлов не используется ajax, плагин формы только создает впечатление, что путь. Истинная отправка в браузере происходит при загрузке файла.

1 голос
/ 09 февраля 2010

Можете ли вы просмотреть сообщение на сервере с firebug и вставить сюда заголовки запроса. Мы смотрим, что заголовок Accept установлен в json. Кроме того, какую версию рельсов вы используете?

...