Plugin: Respond to Parent
Posted on July 30, 2010
Este é um pequeno truque para a seguinte situação: estou abrindo um dialog box via Ajax (e para isso existem vários plugins como os de jQuery, de YUI e assim por diante). O formulário que se abre serve para fazer upload de imagens ou arquivos. A primeira vontade é usar algo como um remote_form_for e enviar um POST via Ajax. Mas isso não é possível para situações de upload – Javascript não deveria mesmo ter privilégios para acessar arquivos na sua máquina local, a menos que você use Firefox e use esta configuração. O que fazer?

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.
blog comments powered by Disqus
Archives
- February 12(2)
- December 11(1)
- November 11(4)
- October 11(6)
- September 11(5)
- August 11(1)
- July 11(5)
- May 11(4)
- April 11(11)
- March 11(4)
- February 11(3)
- January 11(4)
- December 10(9)
- November 10(2)
- October 10(10)
- September 10(4)
- August 10(6)
- July 10(14)
- June 10(16)
- May 10(8)
- April 10(14)
- March 10(9)
- February 10(6)
- January 10(14)
- December 09(10)
- November 09(10)
- October 09(7)
- September 09(19)
- August 09(4)
- July 09(12)
- June 09(7)
- May 09(12)
- April 09(11)
- March 09(9)
- February 09(9)
- January 09(12)
- December 08(14)
- November 08(20)
- October 08(15)
- September 08(18)
- August 08(25)
- July 08(13)
- June 08(21)
- May 08(29)
- April 08(27)
- March 08(12)
- February 08(32)
- January 08(31)
- December 07(27)
- November 07(30)
- October 07(25)
- September 07(28)
- August 07(16)
- July 07(15)
- June 07(16)
- May 07(7)
- April 07(13)
- March 07(8)
- February 07(9)
- January 07(24)
- December 06(17)
- November 06(17)
- October 06(15)
- September 06(38)




