なにげに。。。自宅パソコンのプリザンターをバージョンアップしました。バージョンアップ方法がわからなかったのでインストールしっぱなしで、バージョンアップしてなかったのですが、パソコンを変えて、新たにインストールしたらバージョンも上がった、と。そうゆうことです。1回目のインストールは鬼苦労したけど、二回目は自分の記事を見ながらスイスイいけた。ありがとう、過去の自分。バージョンアップしたらあこがれの「ダッシュボード」がでてきた。そのうちにいじってみよう。
さて、今回もサーバースクリプトをやってみたいと思います。ユーザー、組織関係であれこれする際に、これつかえそうだなーと思ったのが、一覧のフィルタ。●●部にはこれしか見せないけど、□□部には全部見せる、とか。自分の部署だけ表示する、とか。自分が作成者の文書しか見せたくない、とか。
なお、今回長くなったので、後半2回目に分けました。
※おことわり
2024年1月時点の情報です。プリザンターのバージョンは 1.3.50.2 です。Google Chrome でやっています。
javascript,html,cssともに初心者です。調べながら、やってみながら、きっとこうすればいいんだ!という感じで書いていますので、間違っている場合、効率的な書き方ではない可能性が大いにあります。間違ってるよ!とか、こうしたほうがいいよ!ということがありましたら、コメント等で教えていただけると大変ありがたいです。
1.はじめに
公式マニュアルより
概要
引用元:https://pleasanter.org/manual/server-script-view-filters
「viewオブジェクト」の「Filters」です。「サーバスクリプト」で「一覧画面」や「エディタ」に表示する「レコード」を「フィルタ」することで、ユーザに閲覧させるレコードを制限することができます。「レコードのアクセス制御」と異なり「レコード」1件1件にアクセス権を設定する必要がありません。「JSONデータレイアウト:View」が使用できます。
そのほか、使用できる「条件」は「ビュー処理時」のみ。サーバースクリプトにてフィルタ処理した場合は、一覧画面の「フィルタ」が上書きされてしまう、などの制約事項があるそうです。
詳細は公式マニュアルをご参照ください。
開発者向け機能:サーバスクリプト:view.Filters
以上を踏まえ、サーバースクリプトでフィルタをかけるときは以下の点に注意してやるのがよいのかなと思いました。
・サーバースクリプトの条件は「ビュー処理時」を使用する
・サーバースクリプトで強制的にフィルタをかけている項目はユーザー手作業でのフィルタが効かなくなるので、サイト設計の際に一覧のフィルタから当該項目を外したほうが良い場合がある
・管理者自身も強制的にかけたフィルタが適用されてしまうため、全部見れるユーザー(または組織・グループ)を考慮したコードにする必要がある
2.自分が作成したレコードだけを表示する(担当者項目)
やってみましょう。
(1)やりたいこと
ログインユーザーが作成したレコードだけを一覧画面で表示する、というのをやってみます。
人事関連の申請書、アンケートなどでほかの人には見てほしくないケースがありますよね。
今回は、
①自分が作成した文書だけ一覧画面に表示
②総務部(組織ID=2)に所属するユーザーは全文書が見える
というのをやってみます。
(2)エディタ・フィルタの設定
テーブルの管理>エディタ
「担当者」項目の選択肢に [[Users]] 、規定値に [[Self]] とします。
読み取り専用にチェックを入れます。
テーブルの管理>フィルタ
「担当者」を無効化します。
(3)サーバースクリプト
以下のコードをサーバースクリプトに入力します。条件は「ビュー処理時」とします。
//総務部(組織ID2)以外のユーザーには担当者が自分以外のレコードは一覧に表示しない
if ( context.DeptId !== 2) {
view.Filters.Owner = context.UserId;
}
(4)結果
下図上段は総務部田中花子さんから見える一覧画面、下段は営業部山田太郎さんから見える一覧画面です。
(5)コードの解説
今回は短いので一気に。
if ( context.DeptId !== 2) {・・・}
context.DeptId でログインユーザーの組織IDを取得しています。
それが「2」でなければ{}内の処理を行います。
※組織ID2が総務部です。
総務部の田中さんがログインした場合は{}内の処理が行われず、営業部の山田さんがログインしている場合は{}内の処理が実行されます。
view.Filters.Owner = context.UserId;
一覧のOwner(担当者)のフィルターを context.UserId (ログインユーザーのユーザーID)で絞り込みします。
(6)おまけ:一覧のフィルタ項目の表示・非表示をスクリプトで切り替えする
ちょっと思ったのが。総務部以外の人が見ている分には自分のしか見えないから「担当者」のフィルタ項目はないほうが良いと思うのですが、総務部の人には全部見えるから「担当者」のフィルタが欲しいなと思いました。
サーバースクリプトでそのあたりも調整できたら。。。と思ったのですが、わからなかったので、スクリプトで切り替えを行うコードを設定してみました。
①テーブル設定>フィルタ
「担当者」を有効化します。
②テーブル設定>スクリプト
以下のコードを入力します。出力先は「一覧」にチェック。
※サーバースクリプトではなくスクリプトなのでご注意!
$p.events.on_grid_load = function () {
const deptId = $p.deptId();
//ログインユーザーが総務部(deptId:2)以外の場合、担当者フィルタを非表示にする
if ( deptId !== 2 ) {
$('#ViewFilters__OwnerField').css("display","none");
}
}
下図がスクリプト適用後の総務部・営業部のユーザーがログインした場合の一覧画面です。
3.自分が設定されたレコードだけを表示する(分類項目)
前項と同じようなことですが、「担当者」(または「管理者」「作成者」「更新者」)の場合と、分類項目を使用したときでは、サーバースクリプトのフィルタの指定方法が異なるので、分類項目を使用したパターンをやってみます。
(1)やりたいこと
①分類Cにログインユーザーが設定されている文書だけ一覧画面に表示
②管理者田中花子さん(ユーザーID=3)は全文書が見える
というのをやってみます。
(2)エディタの設定
テーブルの管理>エディタ
分類Cの選択肢に [[Users]] を設定します。
(テストデータ作成時に分類Cに手作業でユーザーを設定しています)
(3)サーバースクリプト
以下のコードをサーバースクリプトに入力します。条件は「ビュー処理時」とします。
//ユーザーID3の場合、フィルタかけない
//ユーザーID3以外の場合、分類C=自身のユーザーIDのレコードで絞り込み表示
if ( context.UserId !== 3 ) {
view.Filters.ClassC = '["' + context.UserId + '"]';
}
(4)結果
(5)コードの解説
ポイントだけ。
view.Filters.ClassC = ‘[“‘ + context.UserId + ‘”]’;
そうなんです。
view.Filters.ClassC = context.UserId;
ではダメなんです。かっこでくくらないとダメなんです。
context.log(‘[“‘ + context.UserId + ‘”]’) でコンソールに出力すると、
[“2”]
のように出力されていることがわかります。
通常の分類項目では [“XXX”] や [“AA”,”BB”] のように指定するのですね。Owner項目などが特別なんですね。
ちなみにユーザーIDの場合は以下のように””なしでも行けました。
view.Filters.ClassC = ‘[‘ + context.UserId + ‘]’;
context.UserId を変数に入れて以下のようにしても大丈夫です。
const vUserId = context.UserId;
if ( vUserId !== 3 ) {
view.Filters.ClassC = ‘[“‘ + vUserId + ‘”]’;
}
4.自分の部署しか見えない
(1)やりたいこと
①自分の部署が作成した分だけ見える
②総務部(組織ID=2)および特定IDのユーザーには全部見える(ユーザID=1)
(2)エディタの設定
テーブルの管理>エディタ
分類Aを以下の設定にします
・表示名:部署
・選択肢:[[Depts]]
・規定値:[[Self]]
(3)サーバースクリプト
以下のコードをサーバースクリプトに入力します。条件は「ビュー処理時」とします。
context.Log("ユーザーID:" + context.UserId );
context.Log("組織ID:" + context.DeptId );
if ( context.UserId !== 1 && context.DeptId !==2 ) {
view.Filters.ClassA = '["' + context.DeptId + '"]';
}
(4)結果
(5)コードの解説
これまで解説してきたことと同じでuserIdをdeptIdに変えただけ。。。
context.Log(“ユーザーID:” + context.UserId );
context.Log(“組織ID:” + context.DeptId );
ログインユーザーのユーザーIDと組織IDをコンソールに出力しています。
if ( context.UserId !== 1 && context.DeptId !==2 ) {・・・}
「ユーザーIDが1ではない」「組織IDが2ではない」を両方満たした場合、{}内の処理を行います。
これって、わかりにくいですよね。私は否定とかつ(または)が混在すると混乱します。
if ( context.UserId === 1 || context.DeptId ===2 ) {
} else {
view.Filters.ClassA = ‘[“‘ + context.DeptId + ‘”]’;
}
とかいても同じ結果となります。
&&(かつ)の場合、すべての関所(条件判定)を通過(すべてTRUE)して{}内の処理に行きます。
||(または)の場合、一つでも関所(条件判定)を通過したら(ひとつでもTRUE){}内の処理に行けます。
&&の関所のほうが厳しい、と覚えておきましょう。
そして、否定の場合 「条件判定がFalse」の場合、ひっくり返って「TRUE」になります
context.UserId !== 1
の場合、ユーザーID が1かどうか → NO(False) → 反転して Yes(True) となります。
ユーザーID が1かどうか → NO(False) → 反転して Yes(True)
組織IDが2かどうか → NO(False) → 反転して Yes(True)
の二つがNO、つまり転じてYESの場合、{}内のフィルター処理が実行されます。
逆に
ユーザーID が1かどうか → Yes(True) → 反転して NO(False)
と一つでもYesがあればはじかれるので{}内の処理を行いません。
view.Filters.ClassA = ‘[“‘ + context.DeptId + ‘”]’;
分類Aがログインユーザーの組織IDと一致したレコードを一覧画面に表示します。
5.その部に割り当てられた区分しか見えない(switchを使用した分岐)
(1)やりたいこと
分類D:A,B,C 割り当て
①総務部(組織ID=2):すべて見える
②営業部(組織ID=1):分類DがAのレコードのみ見える
③開発部(組織ID=3):分類DがBのレコードのみ見える
④マーケティング部(組織ID=4)および経理部(組織ID=5):分類DがCのレコードのみ見える
(2)エディタ
分類D
・選択肢:A,B,C
(3)サーバースクリプト
以下のコードをサーバースクリプトに入力します。条件は「ビュー処理時」とします。
context.Log(context.DeptId);
if ( context.DeptId !==2 ) {
switch (context.DeptId) {
case 1:
view.Filters.ClassD = '["A"]';
break;
case 3:
view.Filters.ClassD = '["B"]';
break;
case 4:
case 5:
view.Filters.ClassD = '["C"]';
break;
}
}
(4)結果
総務部(ID2)がログインした場合はフィルタなし。
ログインユーザーが営業部(ID1)の場合、分類Dが「A」のレコードのみ表示される。
ログインユーザーが開発部(ID3)の場合、分類Dが「B」のレコードのみ表示される。
ログインユーザーがマーケティング部(ID4)の場合、分類Dが「C」のレコードのみ表示される。
ログインユーザーが経理部(ID5)の場合、分類Dが「C」のレコードのみ表示される。
(5)コードの解説
今回のポイントは switch を使用していることです。
if で切り分けてもよいのですが、たまには Switch を使ってみようかと思って。
switch で注意すべきは break を入れないと、判定がTrueになった後も次の判定に進んでしまうという点です。if の場合、一つTrueになると、その後の elseif , else は飛ばすのですが。
逆に複数の条件を OR(または) で指定したいとき break を入れないことにより、複数の条件を指定することができます。フォールスルーというそうです。
こちらのサイトで勉強されていただきました。
【JavaScript】switch文で条件分岐!基本の書き方やif文との使い分け
if ( context.DeptId !==2 ) {・・・}
ログインユーザーの組織IDが2ではない場合、{}内の処理に進みます。
switch (context.DeptId) {・・・
続くcase句で組織IDを判定し処理を分岐します。
case 1:
view.Filters.ClassD = ‘[“A”]’;
break;
組織IDが1の場合、分類D「A」のレコードで絞り込み表示します。
break があるため switch 文を抜けます。
(case 2 の構文の解説は case 1 と同様のため、割愛します)
case 4:
case 5:
view.Filters.ClassD = ‘[“C”]’;
break;
組織IDが4の場合、次の行の処理に進み、break までの処理を実行します。
組織IDが5の場合、次の行の処理に進み、break までの処理を実行します。
分類D「C」のレコードで絞り込み表示します。
break があるため switch 文を抜けます。
ここは組織IDが4、または5の場合のORの処理を実現しています。
(6)手動でフィルタをやってみた
サーバースクリプトで制御されている項目でフィルタしてみたらどうなるんだろうと試してみました。
マーケティング部のIDでサイトを開いてみると、すでに分類Dに「C」が入力されている状態でした。
分類Dのフィルタを「B」に切り替えてみたところ、一覧の表示は分類Dが「C」のレコードが表示されている状態のまま、変化はありませんでした。
なので、サーバースクリプトでフィルタを制御している場合、フィルタに制御項目を出しておくと、混乱する可能性がありますな、と思いました。上記2の(6)でやったように、フィルタ項目の表示・非表示を切り替えする、そもそも最初から該当項目をフィルタから外しておくなどの対応をしたほうが良い場合がありますね。
なお、この例での全部見える「総務部」のユーザーの場合、項目Dの手動フィルタは通常通りの挙動をします。
6.最後に
実は最後じゃなくて、次回に続きます。長くなっちゃったので分けることにしました。
今回学んだことは
・プリザンターの一覧画面での絞り込み表示をサーバースクリプトで実現する方法
一覧画面で見えないレコードは閲覧したり、編集したりすることができないので、見せたい情報を制御したいときに有効な手段かと思います。
・switch文の使い方
・switch文でのOR条件の指定の仕方
・サーバースクリプトでフィルタを制御している場合の手動フィルタの挙動
・スクリプトによるフィルタ項目の表示、非表示の切り替え
7.参考文献
公式マニュアルより
開発者向け機能:サーバスクリプト:view.Filters
【プリザンター】 第123回)サーバスクリプトでビューのフィルタリング設定
【JavaScript】switch文で条件分岐!基本の書き方やif文との使い分け
■ユーザー組織あたりをあれこれやってみたシリーズ
【pleasanter】ユーザー、組織、グループあたりをあれこれやってみた①
【pleasanter】ユーザー、組織、グループあたりをあれこれやってみた②~プルダウンリストのフィルター、ソート
【pleasanter】ユーザー、組織あたりをあれこれやってみた③~ルックアップ
【pleasanter】スクリプト~ボタンでユーザー、組織を入力~ユーザー組織あたりをあれこれやってみたシリーズ④
【pleasanter】スクリプト~ユーザーにより項目の編集可否を切り替える~ユーザー組織あたりをあれこれやってみたシリーズ⑤
【pleasanter】スクリプト~セクションの表示・非表示~ユーザー組織あたりをあれこれやってみたシリーズ⑥
【pleasanter】スクリプト~タブの表示・非表示~ユーザー組織あたりをあれこれやってみたシリーズ⑦
【pleasanter】サーバースクリプト~context,user,dept~ユーザー組織あたりをあれこれやってみたシリーズ⑧
【pleasanter】サーバースクリプト~group~ユーザー組織あたりをあれこれやってみたシリーズ⑨
【pleasanter】サーバースクリプト~プルダウンリスト作成~ユーザー組織あたりをあれこれやってみたシリーズ⑩
【pleasanter】サーバースクリプト~一覧のフィルター~ユーザー組織あたりをあれこれやってみたシリーズ⑪
【pleasanter】サーバースクリプト~一覧のフィルター2~ユーザー組織あたりをあれこれやってみたシリーズ⑫
コメント