ExtJSでファイルのダウンロードをするには、Ext.form.FormPanelのsubmitで通常のHTMLのsubmitを利用してサーバ側にリクエストを投げていた。以下のように。
var conditions = new Ext.form.FormPanel( { title : '抽出条件', defaults : { border : false }, bodyStyle : 'padding:5px', onSubmit : Ext.emptyFn, submit : function() { this.getForm().getEl().dom.action = '/customer/csv_output'; // CSVを返すサーバ側のURL this.getForm().getEl().dom.submit(); // HTMLのDom要素を取得しformのサブミットを行う }, items: [] // 省略 }); conditions.submit();
こうすることで「conditions」フォームの内容が普通にサブミットされて、ブラウザのダウンロードダイアログが表示される。(もちろんサーバ側の処理がちゃんとできてるのが前提だけど)
でも、この場合だとフォームで入力した内容がそのままリクエストされてしまう。ほとんどの場合問題ないのだけど、このチェックボックスが選択されてる場合はこっちの値は送信したくないとかって言う場合に、自分でリクエスト内容を決めてサブミットできた方が良い場合もある。
Ext.Ajax.requestでリクエストした場合、リクエストするパラメータは自分で設定できるのだけど(下の例のように)、ブラウザのダウンロードダイアログが表示されない。きっとリクエストをこのAjaxオブジェクト内で完結させているんだと思う。
Ext.Ajax.request({ url: 'foo.php', // URL success: someFn, // レスポンスが正常に返ってきたとき動くファンクションを指定 params: { foo: 'bar' } // リクエストパラメータ });
なので、ここ(Download File on('click'))にあるIFrameを利用する方法で対処した。(下の例はちょい書き換えてる)
/** * IFrameを利用したファイルのダウンロードを行う。というかリクエストを投げる。 * @param {String} url URL * @param {Hash} params ハッシュ形式のリクエストパラメータ */ download: function(url, params) { // ハッシュを分解してリクエストパラメータの文字列を作る requestParam = ''; for (key in params) { requestParam += key + '=' + params[key] + '&' } // ここから本題 try { Ext.destroy(Ext.get('downloadIframe')); // すでにあるIFrameを消す。 } catch (e) { } // iframeタグを作成する。(ここでサーバにリクエストが飛んでいく) Ext.DomHelper.append(document.body, { tag: 'iframe', id: 'downloadIframe', frameBorder: 0, width: 0, height: 0, css: 'display:none;visibility:hidden;height:0px;', src: url + '?' + requestParam }); }
downloadファンクションの引数「params」にリクエストしたいパラメータを指定することで、
URLで指定した場所に自由にデータを送信できるようになった。
しかし、もっと簡潔な方法はないのかね。探しきれなかった。。