2010-02-09 10 views
5

Sto avendo un po 'di problemi a far funzionare il jQuery Form Plugin correttamente con un campo di caricamento file. Quando utilizzo il plug-in per inviare il modulo senza un campo di caricamento file, la parte format.json del blocco respond_to do |format| viene chiamata correttamente. Tuttavia, aggiungendo il campo caricamento file, esegue solo la parte format.html che fa sì che il mio codice javascript pensi che si sia verificato un errore.Utilizzo di respond_to ... format.json e jQuery Form Plugin di malsup

Qualcuno si è imbattuto in questo in precedenza o conosce un modo per forzare il plug-in a utilizzare sempre json? In alternativa, posso modificare l'url che il plugin usa per forzare Rails a rendere il json?

Grazie mille per qualsiasi aiuto! Codice seguente:

# 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); 
}); 

risposta

1

Apparentemente, l'impostazione Accept header non è possibile quando si utilizza ajaxSubmit e si carica un file.

Vedere la risposta di malsup in questa discussione here.

Egli dice: arrivi

di file non utilizzano AJAX, il modulo di plug-in fa solo sembrare che modo. Un vero invio del browser ha luogo quando si carica un file.

+0

Ho provato a impostare l'intestazione Accept, nel callback beforeSend, ma ciò non ha avuto alcun effetto. Quando ho guardato il codice di jQuery.form, l'oggetto XHR passato a beforeSend ha una funzione vuota inizializzata su "setRequestHeader". Tuttavia sto guardando la versione 2.16 del file, forse ci sono cambiamenti nelle versioni successive. – Prashant

1

Potete esaminare il post sul server con firebug e incollare qui le intestazioni della richiesta. Stiamo cercando di vedere che l'intestazione Accept è impostata su json. Inoltre, quale versione di rota stai usando?

+0

Purtroppo, questo è parte del problema. Sembra che il plug-in stia utilizzando un iframe per inviare il modulo, quindi non viene visualizzato in Firebug (non sono onestamente sicuro che questo sia il problema, ma non viene visualizzato e so che sta usando un iframe in modo ...). Quando funziona correttamente, ho verificato che l'intestazione sia impostata su json. Oh e sto usando Rails 2.3.5. –

1

Non sono ancora sicuro del motivo per cui non funziona, ma ho provato molte cose e alla fine ho trovato la soluzione.

Ho provato a cambiare l'URL aggiungendo .json alla fine che ha costretto Rails a rendere il blocco format.json, ma ha confuso il mio browser facendolo pensare che volevo scaricare un file.

Quindi, ho quindi provato a modificare l'url passando il parametro ?format=json che purtroppo ha fatto esattamente la stessa cosa.

Alla fine, ho provato a cambiare il format.json ad appena format.js (Javascript) e aggiungendo .js all'URL, ma ancora utilizzando lo stesso render :json => ... che avevo prima con l'impostazione del parametro dataType nella mia chiamata jQuery per json. Questo sembra funzionare anche se non è la soluzione ottimale.

Spero che qualcun altro lo trovi utile. Pubblicherò di nuovo se trovo una risposta adeguata. Nel frattempo, se qualcun altro ha una risposta adeguata, fammi sapere e accetterò il tuo!

+0

Funziona perfettamente in Firefox, ma produce un avviso in Safari (5.0.5). –

7

Diverse cose sono necessarie per far funzionare il plugin jQuery Form per i caricamenti di file con una risposta JSON. Nel JavaScript, le opzioni per .ajaxForm dovrebbe avere:

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

Il browser ha bisogno di dire ai Rails azione per restituire contenuto come JSON, un modo per farlo è aggiungere un campo di input formato nascosta nel file caricare modello di modulo:

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

l'azione Rails sarà quindi eseguire il metodo format.json all'interno del blocco respond_to.

Nel azione del server

  • incapsulare JSON in un tag, .ajaxForm sarà scartare la stringa e eval JSON correttamente
  • insieme di tipi di contenuto di ritorno a “text/html”, altrimenti alcuni browser (Firefox) proverà a scaricare il ritorno in un file.

ad es.

respond_to do |format| 
    format.json { 
      render :json => "<textarea>#{data.to_json}</textarea>", :content_type => "text/html" 
    } 
    } 
2

Ho fatto una soluzione per questo problema. Ho provato questa soluzione solo con Rails 3, ma forse funziona anche per la 2.3.x

La soluzione è molto semplice:

!#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 
Problemi correlati