O truque é bem conhecido e simples: basta ter um iframe escondido na página e mudar o target do form para mandar o POST para lá. Algo assim:
1 2 3 4 |
<% form_for(user, :html => { :target => "hiddenForm", :multipart => true }) do |f| %> ... <% end %> <iframe id="hiddenForm" name="hiddenForm" style="display:none" /> |
Isso vai funcionar bem, o POST vai para o controller e a action adequada e ele pode retornar Javascript para atualizar o que for necessário na página, como fechar o dialog box. Mas há um problema: o Javascript vai rodar dentro do iframe e não fará o que precisa.
A solução é simples: basta que o Javascript rode no contexto do window.parent no iframe e aí tudo vai funcionar. Existe um plugin que facilita isso, se chama respond_to_parent e no controller basta fazer algo assim:
1 2 3 4 5 6 7 8 9 |
def create @user = User.create(params[:user]) respond_to_parent do respond_to do |format| format.js end end end |
Para instalar, tendo o Git já pré-instalado, claro, basta fazer isto no seu projeto:
1 |
ruby script/plugin install git://github.com/markcatley/responds_to_parent.git |
Ou seja, basta passar coisas como o respond_to ou render como um bloco ao método respond_to_parent. Daí ele vai retornar algo assim:
1 2 3 4 5 6 7 |
var loc = document.location; with(window.parent) { setTimeout(function() { window.eval('Element.insert(\"users\", ... );\nModalbox.hide();\n'); window.loc && loc.replace('about:blank'); }, 1) } |
Para facilitar o entendimento eu coloquei no Github um micro-app só para demonstrar essa funcionalidade. Você pode baixar assim:
1 2 3 4 |
git clone git://github.com/akitaonrails/demo_responds_to_parent.git cd demo_responds_to_parent rake db:migrate ruby script/server |
Garantindo que você tem ImageMagick, RMagick e Paperclip instalado para o exemplo funcionar. Para não sair muito do padrão do Rails 2.3 (que usa Prototype e Scriptaculous) também estou usando o ModalBox que é um dialog box razoável se você não usa jQuery ou YUI.
Uma pequena dica, talvez seja útil.