ThreadSingleSelectFieldの選択肢の同期処理
ThreadSingleSelectFieldの選択肢は、ページの初期表示のタイミングで作成されてブラウザに送信されます。そのためArticlePageを操作して新たなスレッドを登録しても、ThreadSingleSelectFieldの選択肢は更新されません。そこで、ArticleEditFormがArticleTableを更新したタイミングで、ThreadSingleSelectFieldの選択肢を取得するようにします。
まず、ThreadSingleSelectFieldに選択肢の取得機能を実装します。「ThreadSingleSelectField.java」にオプション取得用のメソッドqueryOptionを作成し、そのメソッドに@WebMethodというアノテーションを付けます。このアノテーションを指定しないと、JavaScriptから呼び出すことができません。また、このようなメソッドは戻り値がResponseで、引数がMap<String,Object>である必要があります。
package bbs.field; ・・・ 中略 ・・・ /** * スレッド選択フィールド。 * */ public class ThreadSingleSelectField extends SingleSelectField<Long> { /** * コンストラクタ。 */ public ThreadSingleSelectField() { super(null); } /** * コンストラクタ。 * @param id フィールドID。 */ public ThreadSingleSelectField(final String id) { super(id); } ・・・ 中略 ・・・ /** * スレッドの一覧を取得します。 * @param p 入力パラメータマップ。 * @return スレッド一覧。 * @throws Exception 例外。 */ @WebMethod public JsonResponse queryOption(final Map<String, Object> p) throws Exception { List<Map<String, Object>> list = this.queryOptionList(); Map<String, Object> m = new HashMap<String, Object>(); m.put("value", ""); m.put("name", ""); list.add(0, m); JsonResponse resp = new JsonResponse(JsonResponse.SUCCESS, list); return resp; } }
次に[開発ツール/Webリソース作成]を使用して、「ThreadSingleSelectField.js」を作成してください。作成されたソースに以下の太字部分を追加して、queryOptionメソッドを呼び出す処理を追加します。
/** * @fileOverview {@link ThreadSingleSelectField}クラスを記述したファイルです。 */ /** * @class ThreadSingleSelectField * * @extends SingleSelectField */ ThreadSingleSelectField = createSubclass("ThreadSingleSelectField", {}, "SingleSelectField"); /** * HTMLエレメントとの対応付けを行います。 */ ThreadSingleSelectField.prototype.attach = function() { SingleSelectField.prototype.attach.call(this); }; /** * サーバからスレッドの一覧を取得します。 */ ThreadSingleSelectField.prototype.getOptionList = function() { var m = this.getSyncServerMethod("queryOption"); var r = m.execute(""); if (r.status == ServerMethod.SUCCESS) { this.setOptionList(r.result); } };
ThreadSingleSelectFieldに選択肢の取得機能ができたので、記事の更新を行ったタイミングで選択肢の取得を行うようにします。
記事テーブルの更新を行うのはArticleEditFormなので、[開発ツール/Webリソース作成]を使用して「ArticleEditForm.js」を作成し、以下の太字部分を追記します。
/** * @fileOverview {@link ArticleEditForm}クラスを記述したファイルです。 */ /** * @class ArticleEditForm * * @extends EditForm */ ArticleEditForm = createSubclass("ArticleEditForm", {}, "EditForm"); /** * HTMLエレメントとの対応付けを行います。 */ ArticleEditForm.prototype.attach = function() { EditForm.prototype.attach.call(this); }; /** * ThreadSingleSelectFieldのオプション更新を行います。 */ ArticleEditForm.prototype.updateThreadOptionList = function() { // このArticleEditForm中のThreadSingleSelectFieldのオプション更新 var ths = this.getComponent("threadId"); if (ths != null) { ths.getOptionList(); } // ArticleQueryForm中のThreadSingleSelectFieldのオプション更新 var qf = currentPage.getComponent("queryForm"); if (qf != null) { var qths = qf.getComponent("threadId"); if (qths != null) { qths.getOptionList(); } } }; /** * 保存や削除後の画面状態遷移を行います。 */ ArticleEditForm.prototype.changeStateForAfterUpdate = function() { this.updateThreadOptionList(); EditForm.prototype.changeStateForAfterUpdate.call(this); };
このフォームの親クラスである「EditForm.js」には、データの保存や削除の動作後にページの状態を遷移させるためのchangeStateForAfterUpdateといったメソッドが存在します。このメソッドをオーバーライドして、スレッドの選択肢を更新する処理を呼び出すようにしています。
ThreadSingleSelectFieldの制御
記事の新規追加の際にスレッドを指定できるようにするため、ThreadSingleSelectFieldを作成しました。新規登録の際はこれでいいのですが、既存の記事を更新する場合にもThreadSingleSelectFieldが存在するため、スレッドの変更ができてしまいます。記事の更新時にスレッドをうっかり変更してしまうと会話の流れが途切れるため、更新時にはスレッドを変更できないようにロックする処理を追加します。
EditForm.jsにはtoEditModeとtoConfirmModeのメソッドがあります。新規登録やデータ更新の際にはtoEditModメソッドが呼ばれ、各フィールドを編集可能な状態に設定します。[確認]ボタンが押されると、toConfirmModeメソッドが呼ばれ、各フィールドを編集不可に設定します。今回はtoEditModeをオーバーライドして、新規追加の場合はスレッドを編集可能にし、更新の場合はスレッドをロックするように修正します。
/** * 編集モードにします。 * <pre> * 各フィールドを編集可能状態にします。 * threadIdはArticlePageが新規のときのみ編集可能に設定します。 * </pre> */ ArticleEditForm.prototype.toEditMode = function() { EditForm.prototype.toEditMode.call(this); var tid = this.getComponent("threadId"); if (this.saveMode == "new") { tid.lock(false); } else { tid.lock(true); } };