読書感想文ブログですが、hidesukeの本業はweb系エンジニアだったりします。
最近までSenchaTouchを使ってごにょごにょするお仕事をやっていたのですが、はまったというか、バグっぽい挙動を見つけてしまったのでメモ。
SenchaTouchでformを作るときは、Ext.form.FormPanelを使って実装すると思います。
んで、Ext.form.Selectとか、Ext.form.Textとか使って、入力コンポーネントを書く。
こんな感じになるはず。
var form = Ext.form.FormPanel({ items : [ { xtype : "selectfield", label : "選択肢のサンプル", name : "selection", options : [ {text : "option1", value : 1}, {text : "option2", value : 2) ] } ] }); var button = Ext.Button({ text : "submit", listeners : { tap : function() { form.submit(); } } });
実はすでにここで注意しなきゃ行けない点があります。
SenchaTouchのAPIドキュメントのSmapleなどでは、selectfieldにnameプロパティが書いてないのですが、このnameプロパティを省略すると、実機(iPhone or Android)でselectができません。
いちいち実機で確認するの面倒なので、ChromeとかSafariで確認していると陥りやすい罠です。
Ext.form.FormPanelのsubmit()は、デフォルトだとAjax通信することを期待しています。なので、successとか、failuerとかのコールバック関数を書いてあげる必要があります。
まぁ、スマホだし、そういうUIの方が普通ですよねー。
で、自分がやってる案件ではちょっと特殊なことをしていて、Ajax通信したくなかったんですね。submit押すとsubmit先のアクションでリダイレクトさせたいみたいな。
こういう場合だと、SenchaTouchは「そんなリソースねぇよ!」とエラーをはいて、ページ遷移を行いません。
こういう時は、standardSubmitをtrueにしてあげると解決します。
var form = Ext.form.FormPanel({ standardSubmit : true, items : [ { xtype : "selectfield", label : "選択肢のサンプル", name : "selection", options : [ {text : "option1", value : 1}, {text : "option2", value : 2) ] } ] });
で、こっからが問題。
単純にstandardSubmit : true と付けるだけだと、selectfieldの挙動がおかしくなります。
どうおかしくなるかというと、パラメタとして、 「http://example.com/?selection=1」 とかじゃなくて、「http://example.com/?selection=選択肢のサンプル」みたいにlabelの値を何故か値として送信します。
これは、APIリファレンスに対策が書いてあって(Ext.form.Selectに書いてある)、standardSubmitのときは、nameではなくてhiddennNameを使いましょうと書いてあります。
なので、hiddenNameに修正.
var form = Ext.form.FormPanel({ standardSubmit : true, items : [ { xtype : "selectfield", label : "選択肢のサンプル", hiddenName : "selection", options : [ {text : "option1", value : 1}, {text : "option2", value : 2) ] } ] });
よしよし、意図通りに動いた。
と、PCのブラウザだけで確認して満足したら大間違い。
実機で確認してみてください。また、selectボックスが動かなくなっています!
じつはnameプロパティが無いと実機でselectボックスは動かないらしい。。。
var form = Ext.form.FormPanel({ standardSubmit : true, items : [ { xtype : "selectfield", label : "選択肢のサンプル", hiddenName : "selection", name : "dummyName", options : [ {text : "option1", value : 1}, {text : "option2", value : 2) ] } ] });
これでselectもできるようになりました。
ただ、 「http://example.com/?selection=1&dummyName=選択肢のサンプル」 のようなリクエストを吐いています……。
これってバグだよなぁ。
というようなことにハマって、頭を掻き毟っていたのでしたので、メモ、と。
みんなで幸せになろうよ。