No.3 コンポーネントの利用 – (3)フォーム
前回までの2回で、画面の左側と中央部を定義しました。 コンポーネントもデータビューとグリッドを使いましたね。
今回は、社員の情報を表示、編集するためにフォームを使ってみましょう。
フォームパネル
フォームパネル (Ext.form.Panel
) は、その名の通りフォームとして利用できるパネルです。
フォームパネルでは、HTML の<form>
タグが生成されます。
ですから通常の HTML 同様に POST/GET でサーバーにデータを送ることができます。
送信方法としては、デフォルトでは XHR (Ajax通信) を使って送信されますが、通常の送信方法を選択することもできます。
また、フォームパネルにはバリデーションの機能も備わっています。
入力された値をチェックして、ユーザーにフィードバックすることができます。
BasicForm
ここで、フォームパネルの構造についてお話ししましょう。
Ext.form.Panel
(FormPanel) クラスの背後には、
Ext.form.Basic
クラス (BasicForm) があります。
こちらはフォームパネルのフォームとしての動作の部分を司るクラスです。
FormPanel
内のフィールド操作や、サブミットなどは、
BasicForm
が管理します。
Ext.form.Panel
クラスのコンフィグオプションには、
Ext.form.Basic
がサポートするコンフィグオプションを指定することができ、それらはそのまま
内部的に生成される
Ext.form.Basic
に渡されます。
Ext.form.Panel
クラスの getForm
メソッドを使うと、
Ext.form.Basic
オブジェクトを取得することができます。
BasicForm の主立ったメソッドは、FormPanel で再定義されているので、FormPanel から直接使うことができますが、再定義されていないメソッドを使うようなときは、このようにして BasicForm を取得します。
- フィールドのバリデーション管理も、この
Ext.form.Basic
が担当します。isValid
メソッドを利用することで、フィールド全体のバリデーション結果を取得することが可能です。 - データ送信は、
submit
メソッド、リセットは、reset
メソッドを利用します。このように通常の<form>
タグの操作を担うのがこのExt.form.Basic
になります。
同様にイベントに関しても、BasicForm によって発火される以下のイベントを、 FormPanel が再発火します。
- beforeaction
- actionfailed
- actioncomplete
- validitychange
- dirtychange
フォームデータの取得
getValues
メソッドを呼び出すと、内部のフィールドの値をキーバリューペアのオブジェクトで取得することができます。
その際のキーになるのが、フィールドの “name” コンフィグオプションです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | var form = Ext.create('Ext.form.Panel', { title: 'Test Form', width: 500, bodyPadding: 5, defaultType: 'textfield', items: [{ name: 'text1', fieldLabel: 'Text1' },{ name: 'text2', fieldLabel: 'Text2' }], buttons: [{ text: 'Submit', handler: function() { // フォームデータの取得 console.log(form.getValues()); } }], renderTo: Ext.getBody() }); |
このフォームを開いて、Submit ボタンをクリックすると、コンソールに取得した値が記録されます。
1 | Object {text1: "aaa", text2: "bbb"} |
フォームデータの設定
逆にフォームに値を設定するのも簡単にできます。
BasicForm の setValues
メソッドにオブジェクトを渡すと、フォームに配置されたフィールドに値を設定することができます。
このメソッドは、getValues
のように FormPanel で再定義されていないので、BasicForm を取得して使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | var form = Ext.create('Ext.form.Panel', { title: 'Test Form', width: 500, bodyPadding: 5, defaultType: 'textfield', items: [{ name: 'text1', fieldLabel: 'Text1' },{ name: 'text2', fieldLabel: 'Text2' }], buttons: [{ text: 'Set Data', handler: function() { // フォームにデータを設定 form.getForm().setValues({ text1: 'foo', text2: 'Bar' }) } }], renderTo: Ext.getBody() }); |
このフォームを開いて、Submit ボタンをクリックすると、コンソールに取得した値が記録されます。
社員のデータ詳細を表示するフォームを作成
では、前回まで作ってきたプロジェクトにフォームを追加しましょう。
画面の下側 (south
リージョン) にフォーム (Form.js) を表示します。
まず、view ディレクトリに Form.js を作ります。 これがフォームのビューになります。
app/view/Form.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | Ext.define('SlView.view.Form', { extend: 'Ext.form.Panel', alias: 'widget.myform', requires: [ 'Ext.form.field.ComboBox' ], bodyPadding: 10, title: '詳細', items: [{ xtype: 'textfield', // 名前のテキストフィールド fieldLabel: '名前', name: 'name', anchor: '100%' }, { xtype: 'combobox', // 部署のコンボボックス fieldLabel: '部署', queryMode: 'local', name: 'department_id', store: 'Departments', // リストに表示するストア displayField: 'name', // 表示するフィールド valueField: 'id', // 値として使うフィールド anchor: '100%' }, { xtype: 'textfield', // メールのテキストフィールド fieldLabel: 'メール', name: 'email', anchor: '100%' }, { xtype: 'combobox', // 性別のコンボボックス fieldLabel: '性別', name: 'gender', store: { // リストのストアをインライン指定 fields: ['text'], data:[{ text: '男' }, { text: '女' }] } }, { xtype: 'numberfield', // 年齢は数値フィールドで fieldLabel: '年齢', name: 'age' }], buttons: [{ text: '保存' }, { text: 'キャンセル' }] }); |
このフォームを Main ビューに追加します。
xtype
を myform
にして、height
プロパティを削除します。
これでフォームの高さに合わせて自動的に設定されます。
app/view/Main.js
27 28 29 30 31 32 33 34 | // south リージョン region: 'south', xtype: 'myform', // フォーム title: '詳細', //height: 200, collapsible: true, // 折りたためるようにする collapsed: true, // 初期状態を折りたたんだ状態にする weight: 10 // west が上下一杯使うようにweightを調整 |
この時点で表示してから、画面下のパネルを開いてみると次の様にフォームが表示されるのがわかります。
バリデーション
Sencha Ext JS のフォームには、非常に強力なバリデーション機能があります。 入力値を即座にチェックしてユーザーにフィードバックできます。 便利でかっこいいフォームが作れますよ。
テキストフィールド (xtype: textfield)
のバリデーションをするためのコンフィグには次のものがあります。
allowBlank
:
false
を設定するとその項目は必須項目になります。minLength
:
文字列の最小の長さを指定します。maxLength
:
文字列の最大長を指定します。regex
:
正規表現を使って値をチェックします。
この他に、vtype
コンフィグに値を設定すると、高度なバリデーションを設定できます。
vtype
には標準で次の値をセットすることができます。
alpha
: 英文字のみalphanum
: 英数字のみemail
: 電子メールの形式を判定url
: URL の形式を判定
これらのバリデーションを設定したフォームを用意しました。
各フィールドにいろいろ値を入れてみて、エラーメッセージが表示されるのを確認してみてください。
バリデーションの制御
さきほどのエラーメッセージは英語で表示されましたね。 ご安心ください。Ext JS には言語ファイルがありまして、それを使えば日本語にすることができます。 また、エラーメッセージの内容や表示位置も自由に設定できるようになっています。
blankText, minLengthText, maxLengthText, regexText
を設定すると、エラーメッセージを指定できます。vtype
で指定したバリデーションのエラーメッセージは、vtypeText
コンフィグに設定できます。- エラーメッセージの表示位置を指定するには、
'msgTarget'
コンフィグを設定します。side, under
などが指定できます。 デフォルトでは、ユーザーがフィールド入力している時、フィールド値はすぐにバリデーションされます。 これは、
validateOnChange, checkChangeEvents, checkChangeBugger
コンフィグで制御することができます。フォームに配置したボタンなどの
formBind
コンフィグにtrue
を設定すると、フォームのバリデーションの結果によって、そのコンポーネントの有効/無効が切り替わります。
バリデーションの例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | var fp = Ext.create('Ext.form.Panel', { title: 'バリデーション', frame: true, bodyPadding: 5, width: 500, defaultType: 'textfield', items: [{ fieldLabel: '名前', allowBlank: false, blankText: '名前は省略できません', msgTarget: 'side' }, { fieldLabel: 'URL', anchor: '100%', vtype: 'url', vtypeText: 'URLの形式が不正です', msgTarget: 'under' }], buttons: [{ text: 'OK', formBind: true }], renderTo: Ext.getBody() }); |
メッセージの内容や表示位置を変えています。
カスタムVType
前記の vtype
で指定するバリデーションは、Ext.form.field.VTypes
で定義されています。
この Ext.form.field.VTypes
にはカスタムの vtype
を追加することができます。
カスタムVTypeの例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | Ext.apply(Ext.form.field.VTypes, { password: function(val, field) { if (field.initialPassField) { var pwd = field.up('form').down('#' + field.initialPassField); return (val == pwd.getValue()); } return true; }, passwordText: 'パスワードが一致しません。' }); Ext.create('Ext.form.Panel', { title: 'バリデーション', frame: true, padding: 10, width: 500, items: [{ xtype: 'textfield', fieldLabel: 'パスワード', inputType: 'password', name: 'pass', id: 'pass' },{ xtype: 'textfield', fieldLabel: 'パスワード確認', inputType: 'password', name: 'pass-cfrm', vtype: 'password', initialPassField: 'pass' }], renderTo: Ext.getBody() }); |
社員フォームを修正
ではプロジェクトの社員フォームにもバリデーションを追加してみましょう。 次の3つのことをやります。どうです?回答はもうおわかりですよね。
- 名前(
name
)を必須にする - メールアドレスの形式をチェックする
- エラーがあるときは保存ボタンが押せないようにする。
名前(name
)を必須にする
13 14 15 16 17 | xtype: 'textfield', // 名前のテキストフィールド fieldLabel: '名前', name: 'name', allowBlank: false, // 名前は必須 anchor: '100%' |
メールアドレスの形式をチェックする
28 29 30 31 32 | xtype: 'textfield', // メールのテキストフィールド fieldLabel: 'メール', name: 'email', vtype: 'email', // メール形式チェック anchor: '100%' |
エラーがあるときは保存ボタンが押せないようにする。
50 51 52 53 54 55 | buttons: [{ text: '保存', formBind: true // エラーがあるときは押せない }, { text: 'キャンセル' }] |
ここまで3回に渡ってコンポーネントを学びながら、画面を作成してきました。 ただ、ここまでのプロジェクトは単にデータを画面に表示しただけで、ユーザーの操作に対応する部分は何もありません。 ユーザーのインタラクションに対応するには、コンポーネントなどのイベントを適切に処理する必要があります。 Sencha の MVC フレームワークでイベント処理を担当するのがコントローラーです。
次回は、コントローラーを使って、作りかけのアプリケーションをユーザー操作に対応させていきます。お楽しみに。