2013-05-19 5 views
7

Sto usando simple_form gemma e generando la forma che sto specificando il telecomando: vera opzione in questo modo:controllore non può rilevare ajax richiede

<%= simple_form_for @webinar, validate: true, remote:true do |f| %> 

Quindi, il codice html di uscita per il modulo è il seguente frammento:

<form accept-charset="UTF-8" action="/webinars" class="simple_form new_webinar" data-remote="true" data-validate="true" enctype="multipart/form-data" id="new_webinar" method="post" novalidate="novalidate"> ... </form> 

Come ho controllato, utilizzando lo standard form_for aiutante è l'aggiunta del dati remota = 'true' alla forma quando remoto: viene utilizzato veri opzioni. E come puoi vedere dall'html generato, quando sto usando la gemma simple_form c'è anche questo attributo.

Quindi, a mio regolatore ho:

def create 
    @webinar = Webinar.new(params[:webinar]) 

    respond_to do |format| 
    if @webinar.save 
     format.html { redirect_to @webinar, notice: 'Webinar was successfully created.' } 
     format.js 
     format.json { render json: @webinar, status: :created, location: @webinar } 
    else 
     format.html { render action: "new" } 
     format.json { render json: @webinar.errors, status: :unprocessable_entity } 
    end 
    end 
end 

Ma, sempre il format.html viene utilizzato. Cosa sto facendo di sbagliato?

EDIT:

ho usato logger.debug request.format per verificare qual è il formato effettivo chiedere e nel file di registro è stato:

text/html

Quindi, il problema deve essere nella forma generata da simple_form - cosa può esserci di sbagliato quando abbiamo "data-remote = true"?

+0

Possiedi '// = richiede jquery' e '// = require jquery_ujs' nel tuo' a pplication.js'? Hai un file 'create.js.erb' sotto'/app/assets/view/webinar '? – mccannf

+0

Sì, ho tutto questo a posto. Ho effettuato con successo una richiesta jax a partial per tutte le azioni senza creare e aggiornare. Ho anche <% = csrf_meta_tags%> nel mio file application.html.erb. In realtà, il problema è che il controller si comporta come il formato è html non js. – gotqn

+0

Si potrebbe provare ad aggiungere ': html => {: data => {: type =>: json}}' come opzione a simple_form_for ... – mccannf

risposta

2

Non posso credere che ho perso così tanto tempo nel cercare di capire il motivo per cui la simple_form non funziona come previsto.

Infine, sembra che ho fatto tutto nel modo giusto e il problema è stato causato perché:

AJAX non può essere utilizzato per il caricamento dei file.

Al fine di risolvere il mio problema ho semplicemente devo aggiungere il seguente gemma nel mio Gemfile ed eseguire il fascio installare comando:

gem 'remotipart', '~> 1.0' 

quindi aggiungere la seguente riga nella mia applicazione .js di file:

// = richiedere jquery.remotipart

Maggiori informazioni su:

  1. remotipart gem
  2. How to upload multiple files using jQuery
2

Sembra che tu non stia richiedendo direttamente un documento formattato JSON nell'azione del modulo generato. Forse una possibilità è quella di impostare :format a json nel file percorsi utilizzando questa tecnica: http://guides.rubyonrails.org/routing.html#defining-defaults

È anche possibile definire altre impostazioni predefinite in un percorso fornendo un hash per l'opzione: default. Questo vale anche per i parametri che non vengono specificati come segmenti dinamici. Per esempio:

match 'photos/:id' => 'photos#show', :defaults => { :format => 'jpg' } 

Rails sarebbe abbinare le foto/12 per l'azione show di PhotosController, e impostare params [: Formato] su "jpg".

4

Stai confondendo format.json|format.html con remote: true. Entrambi sono diversi. La presenza di remote: true non implica format.json.

non indica che l'URL è stato richiamato tramite javascript. Significa solo che il cliente si aspetta l'uscita JSON . cioè non indica da dove proviene l'input, indica quale output è richiesto.

L'uso generale di remote:true è, invece di ricaricare la pagina, inviare il modulo come richiesta Ajax e quindi mostrare la risposta in un popup di JQuery o qualcosa del genere. Ma se vuoi mostrare la risposta come un popup di JQuery - hai bisogno dell'output HTML, non dell'output JSON vero?

Alcune persone utilizzano remote: true per caricare il contenuto HTML in un popup.Il tuo caso d'uso è quello di fare remote: true ma ti stai aspettando dati formattati JSON. Rails non può prendere queste decisioni per te. Per impostazione predefinita invia la richiesta a /webinars e prevede che gestirai la risposta HTML. Se si vuole veramente risposta JSON - quindi personalizzare l'URL a cui viene inviato la richiesta Ajax:

simple_form_for @webinar, url: webinar_path(format: :json), ..... 

Se fate quanto sopra, ora il controller webinar sarà chiamato con il formato JSON.

complessivo:

  • remote:true può essere utilizzato sia con format.html e format.json
  • Il caso di utilizzo maggioranza in un'applicazione Rails è quello di gestire remote: true come richiesta controllore come al solito, il rendering di un modello parziale HTML (ie il contenuto della risposta da solo senza il layout di pagina/navigazione/ecc.) e lo rimando come HTML per essere visualizzato in un popup
  • La maggior parte delle persone gestisce solo le chiamate remote e visualizza un popup JQuery. Quindi non c'è bisogno di scrivere codice individuale per ogni forma remoti
  • Quindi per default, Rails chiama format.html per le richieste remote
  • Se si vuole specificamente format.json, e se davvero si vuole gestire il JSON manualmente sul client, cambia l'URL di conseguenza. Ma questo non è il caso di utilizzo della maggioranza
  • Fare una richiesta Ajax non corrisponde a significa che il tipo di contenuto è JSON. È una richiesta HTML creata usando Javascript. per esempio. Nel metodo jquery $.ajax, selezionare queste due opzioni: accept e dataType. Se vuoi davvero inviare l'intestazione Accepts: application/json, devi specificarlo manualmente quando effettui la richiesta Ajax (o devi terminare l'url con .json se è un'app Rails).
  • Quindi, anche se si effettua una normale richiesta Ajax su /webinars, ad esempio $.ajax('/webinars', ...), non va a format.json! Andrà comunque solo a format.html. Se si vuole veramente un formato JSON, allora si deve dire $.ajax('/webinars', { accepts: 'application/json' }), oppure è necessario dire $.ajax('/webinars.json')

Edit: chiarimenti Minore

+0

La mia prima necessità era di poter inviare il modulo usando ajax, quindi se ci sono errori o se i dati sono inviati correttamente, per aggiornare solo parte della pagina - ora sta aggiornando l'intera pagina. Penso che aggiungendo il telecomando: true farà in modo che il mio controller utilizzi il partial * .js. Per i collegamenti nella mia applicazione funziona correttamente, ma suppongo che per l'invio del modulo no? In tal caso, questo significa che per aggiornare solo una parte della mia pagina quando ho un modulo devo usare solo il formato JSON? – gotqn

+0

Dopo aver effettuato una richiesta Ajax usando 'remote: true', ora hai due modi per aggiornare parte della tua pagina: (1) Restituisci un JSON dall'URL, analizzalo nel browser e aggiorna la tua pagina usando javascript/jquery, * O * (2) Restituisce un modello parziale (piccolo frammento di codice HTML senza layout dell'intera pagina Web) dall'URL, mostra un popup jquery. Se hai bisogno di (1) - finirai per scrivere altro codice javascript, e allo stesso modo nell'URL devi specificare l'URL del modulo come '/ webinars.json'. Se hai bisogno di (2) - puoi dire l'URL del modulo come '/ webinars'. – Subhas

+0

Al momento, sembra che tu voglia fare (1) (restituire JSON) e vuoi gestire manualmente il JSON nel browser. Quindi devi specificare l'URL simple_form come '/ webinars.json' – Subhas