本日のゴール
今日は@式を使って入力チェック機能を実装します。
入力エラーはHTMLを生成し、スコープ変数のviewScopeに書き込みます。
viewScopeを使う利点は、画面が更新されると値が消える点です。リロードで値が消えても良い場合や、消えて欲しい場合などはviewScopeを利用します。
【完成イメージ】
サーバーサイドJavaScript(SSJS)基礎
XPageのSSJSは下記のようなイメージで捉えるのが良いかと思います。
@式(一部+α) + LotusScriptっぽいクラス + Javaクラス
LotusScriptであれば、@式を呼び出すにはEvaluate を経由する必要がありましたが、SSJSではそのまま@式を記述することができます。
【@式】
Notesクライアント用@式と、SSJSの@式は下記の点が違います。
-
引数の区切り記号がカンマであること(Notesクライアントの場合は、セミコロン)
-
引数の多くがテキストで、Notesクライアント用@式で[FailSilent]と書いていた部分は、” [FailSilent]”とテキストとして記述する必要がある
記述する際はNotesクライアントと同じくフロントエンドのデータであることを意識して下さい。
XPageはサーバー上で実行されますが、Notesアプリケーションと同じく、フロントエンドデータと、バックエンドデータがあります。
例えば、@式でフィールドを変更し、同じロジック内でバックエンドクラスを使って同じフィールドを更新すると、競合文書が発生します。
@式とNotesクラスが同じところに書けるからと言って、フロントエンド更新とバックエンド更新をごちゃ混ぜに書くと沼にはまります。
【SSJS】
SSJSで最初にわからないのはViewデータソースやDocumentデータソースを配置した時に定義される、「view1」や「document1」は何なのか?ということだと思います。
簡単に言うと、view1や、document1は、それぞれSSJSのNotesViewクラス、NotesXspDocumentクラスを継承したインスタンス(実体)です。
データソース | SSJSのNotesクラス | 対応するLotuScriptのNotesクラス |
view1 | NotesView | NotesView |
document1 | NotesXspDocument | NotesUIDocument |
NotesXspDocumentクラスはLosutScriptのNotesUIDocumentクラスに当たりますので、フロントエンド処理になります。
【LotusScriptのNotesクラス宣言とSSJSのNotesクラス宣言】
SSJSでのNotesクラス制限は下記のように記述します。
同じ内容をLotusScriptで記述すると、下記のようなイメージになります。
Notesクラスを明示的に指定しなくても動作しますが、コードの入力支援を使うためには宣言が必要です。
エラーメッセージ表示領域を追加する
エラーメッセージは、スコープ変数にHTMLを書き込む形で実装します。
エラー表示にはBootstrapのAlertsコンポーネント使ってデザインします。
1 |
フォーム用XPageを開き、左メニューのコントロールタブから 「計算結果フィールド」コントロール を、フッタータグ<footer>の前にドロップする。 |
|||||||||||
2 |
ドロップした計算結果フィールドを選択し、プロパティ>計算結果フィールドを選択する。 下記のプロパティを設定する。
|
|||||||||||
3 |
プロパティ>値を選択する。
|
必須入力チェック(@式実装)
現在の保存処理はシンプルアクションで実装していますが、保存処理の前にエラー判定処理を追加するため、保存処理をSSJSに書き直します。
1 | 【保存関数を定義する】 コード>スクリプトライブラリを選択し、 「ssjsKeiji_frm」 を開く。 |
|||||
2 | 保存ボタン用のSSJS関数を記述する。 ソースは、【保存ボタン@式SSJS①】を参照。 |
|||||
3 | 【保存ボタンに作成した保存関数を設定する】 保存ボタンを選択し、イベント>マウス>onclickを選択する。 サーバータブでスクリプトエディタを選択し、定義した保存ボタン関数を呼び出す。 【beforePageLoadイベント】 btnSave_Click() |
|||||
4 | サーバーオプションで「部分更新」を選択し、要素の選択をクリックする。
エラー表示用計算結果フィールド「computedErrMsg」を選択し、OKボタンをクリックする。 |
|||||
5 | ブラウザでプレビューし、表示内容を確認する。 下記の点を確認する。
|
|||||
6 | 【必須入力を示すCSSクラスを追加する】 リソース>スタイルシートを選択し、 「css/original.css」 を開く。 |
|||||
7 | フォーム用のCSSクラスの最後に必須入力用CSSクラスを追加し、スタイルシートを保存する。 ソースは、【オリジナルCSSクラス⑧】を参照。 |
|||||
8 | フォーム用XPageを開き、タイトル、本文ラベルタグ<label>の内側に必須入力用HTMLタグを追加する。 | |||||
9 | ブラウザでプレビューし、表示内容を確認する。 下記の点を確認する。
|
【保存ボタン@式SSJS①】
// save click
function btnSave_Click(){
try{
// Input Check & save
var errMsg = @If(@IsNull(@GetField("Subject")),"タイトルを入力して下さい。<br>","");
errMsg = errMsg + @If(@IsNull(@GetField("Memo")),"本文を入力して下さい。","");
@If(errMsg!="",
viewScope.errMsg = "<div class='alert alert-danger'>"+errMsg+"</div>",
@Do(
document1.save(),
context.redirectToPrevious()
)
)
}catch(e){
print("btnSave_Click Error:" + e);
}
}
【オリジナルCSSクラス⑧】
.org_mandatory{
color :red;
margin-left :10px;
}
【必須入力用HTMLタグ】
<label class="org_mandatory">
*
</label>
必須入力チェック(Notesクラス実装)
必須入力チェック用のSSJSは、@式を使わずに記述すると下記のように記述できます。
【保存ボタンNotesクラスSSJS】
function btnSave_Click(){
try{
// Input Check & save
var errMsg = "";
if(document1.getItemValueString("Subject")==""){
errMsg = "タイトルを入力して下さい。<br>";
}
if(document1.getItemValueString("Memo")==""){
errMsg = errMsg + "本文を入力して下さい。";
}
if(errMsg!=""){
viewScope.errMsg = "<div class='alert alert-danger'>"+errMsg+"</div>";
}else{
document1.save();
context.redirectToPrevious();
}
}catch(e){
print("btnSave_Click Error:" + e);
}
}
保存ボタンクリック時に、最終更新者を更新する。
現状のままでは、保存時のフォームの計算結果フィールドがサーバー上で更新され、最終更新者がサーバー名になってしまいます。
シンプルな改善方法としては、下記の方法で実装を行います。
-
フォームの計算結果フィールドを編集可能フィールドに変更する(入力はXPage上からのみ行う)
-
保存前にログインユーザーの氏名を書き込む
1 |
【フォームのフィールドプロパティを変更する】 「frmKeiji」フォームを開き、「ModifiedKanjiName」フィールドを編集可能フィールドに変更する。
|
|||||||
2 |
「ModifiedKanjiName」フィールドの計算式(デフォルト値)は削除する。 | |||||||
3 |
スクリプトライブラリ「ssjsKanji_frm」を開き、保存ボタンクリック時のSSJSを変更する。 ソースは、【保存ボタン@式SSJS②】を参照。 |
|||||||
4 |
ブラウザでプレビューし、表示内容を確認する。 下記の点を確認する。
|
【保存ボタン@式SSJS②】
// save click
function btnSave_Click(){
try{
// Input Check & save
var errMsg = @If(@IsNull(@GetField("Subject")),"タイトルを入力して下さい。<br>","");
errMsg = errMsg + @If(@IsNull(@GetField("Memo")),"本文を入力して下さい。","");
@If(errMsg!="",
viewScope.errMsg = "<div class='alert alert-danger'>"+errMsg+"</div>",
@Do(
@SetField("ModifiedKanjiName",@Name("[Abbreviate]" ,getKanjiName(@UserName()))),
document1.save(),
context.redirectToPrevious()
)
)
}catch(e){
print("btnSave_Click Error:" + e);
}
}