メインコンテンツへスキップ
見出し画像

ServiceNowのResolveボタンはどこで動く? UI Actionの表示条件とClient/Server処理


    Incidentフォームの「Resolve」ボタンを押すと、処理はどこで動くのでしょうか。押した後の処理がクライアント側の画面操作なのか、サーバー側のレコード更新なのか、コードを開くまで分からないという相談を受けることがあります。ServiceNowはこの手のボタン・メニュー・リンクをsys_ui_actionという1つのテーブルにまとめており、1レコードのフィールドを追うだけで表示条件・実行場所・処理本体まで読み取れます。Zurich PDIでResolveボタンを実際にたどり、条件判定からクライアント/サーバーの実行分岐までを確認しました。

    検証環境:Zurich PDI / OOTB / 2026-08-08 確認


    結論:Resolveボタンは1レコードのフィールドで説明できる

    全体像を先に示します。

    • UI Actionはsys_ui_actionという1つのテーブルに、1ボタン=1レコードで保存されています。業務データとは別に、Business RuleやClient Scriptと同じ「アプリ構成」側で管理されます。

    • 表示するかどうかはconditionがサーバー側で判定します。条件を満たさない場合、ボタンのHTML/JavaScriptはブラウザへ送られず、画面には最初から現れません。

    • 表示された後にクリックすると、clientフラグの値によって実行場所が分かれます。trueならonclickのクライアントJavaScript、falseならscriptのサーバーJavaScriptが動きます。

    新規インシデントのフォームを開くと、右上に「Submit」と「Resolve」のボタンが並びます。


    画像

    この「Resolve」がsys_ui_actionの1レコードです。条件判定から実行場所の分岐までを1枚にすると、次の流れになります。


    画像

    図の色は6種類の意味に固定しています。

    • 濃紺 … 起点

    • 橙 … 分岐点

    • 赤 … 描画しない経路

    • 緑 … 表示からクリックまでの進行

    • 紫 … クライアントでの実行

    • 水色 … サーバーでの実行

    ①でフォームやリストが表示されると、②のconditionをサーバーが判定します。満たさなければ③でボタンごと描画されません。満たせば④で表示され、⑤でユーザーがクリックします。クリック後は⑥のclientフラグを見て、⑦のクライアント実行か⑧のサーバー実行に分かれます。


    UI Action(UIアクション)とは何か

    UI Actionは、フォームやリストの上にボタン・コンテキストメニュー・リンクとして現れ、クリックするとJavaScriptを実行する画面部品です。「Resolveを押したらStateを解決済みにする」「選択した行をまとめて更新する」「関連リンクから別画面へ飛ぶ」といった操作の入口を担います。

    ServiceNowはUI Actionをsys_ui_actionというテーブルに格納します。System Definition > UI Actionsから一覧でき、1レコードが1つのボタン・メニュー・リンクに対応する仕組みです。どこに出すか、どんな条件で出すか、どこで何を実行するかは、すべて同じレコードのフィールドに入っています。

    Resolveレコードに入っていた値

    「Resolve」レコードを開くと、次の値が入っていました。

    • table=incident … incidentのフォームに出る

    • form_button=true … フォーム上部のボタンとして出す

    • client=true / onclick=resolveIncident(); … クリックするとクライアント側で実行

    • order=100 … 同じ表示先での並び順(既定値)

    • show_update=true / show_insert=false … 保存済みのインシデントだけで表示

    • condition=new global.IncidentUtils().canResolveIncident(current) … 解決可能なときだけ表示

    新しくUI Actionを1つ作るときも、同じフィールドに「どのテーブルに/どこに出し/どんな条件で/押したらどこで何を動かすか」を入れます。


    sys_ui_actionは何を継承しているテーブルか

    sys_ui_actionは、incidentやcmdb_ciのような業務データのテーブルではありません。


    画像

    今回のPDI(Zurich / OOTB)で確認すると、sys_ui_actionはsys_metadata(Application File)を継承するテーブルでした。sys_metadataはUpdate Setで持ち運べる「アプリ構成」の基底です。UI Actionは設定側のレコードとして管理されるため、Update Setで別インスタンスへ移送できます。Business Rule(sys_script)やClient Script(sys_script_client)も、同じsys_metadata配下の兄弟にあたります。この継承関係を知っておくと、UI Actionを別インスタンスへ移送するとき、Business RuleやClient Scriptと同じUpdate Set管理下にあるとみなせて安心です。

    UI Actionが「どの業務テーブルに出るか」は、table(画面ラベル: Table)フィールドで決まります。incidentのボタンならtable=incident、という具合です。sys_ui_action自体は1つのテーブルですが、tableを通じてあらゆる業務テーブルにボタンを差し込めます。

    テーブル定義は、次のURLで確認できます(先頭の<YourInstance>は自分のインスタンスに置き換えてください)。

    https://<YourInstance>/sys_db_object_list.do?sysparm_query=name=sys_ui_action


    画像

    ボタンはどこに出る? 表示先はフォーム系とリスト系の8種類

    UI Actionはまず「どこに出すか」を決めます。フォーム上部か、リストのバナーか、行を右クリックしたメニューかで、意味は別物です。表示先はbooleanのフラグで決まり、1つのUI Actionを複数の表示先に同時に出すこともできます。

    表示先フラグの一覧

    • form_button … フォーム上部のボタン(「Resolve」など)

    • form_context_menu … フォーム左上の歯車メニューの項目

    • form_link … フォーム下部のRelated Linksリンク

    • list_button … リスト上部のボタン

    • list_banner_button … リストのバナーボタン

    • list_context_menu … リスト行を右クリックしたときのメニュー

    • list_choice … 行を選択したときの操作

    • list_link … リストのリンク

    これらは排他条件ではありません。組み合わせて指定できます。集約フラグのform_action(フォーム系のいずれか)が1752件、list_action(リスト系のいずれか)が806件で、フォームに出るUI Actionが中心でした。


    画像


    画像

    表にすると傾向がはっきりします。form_buttonが865件と最多で、form_link(715件)、list_banner_button(322件)、form_context_menu(293件)が続きます。フォーム上部のボタンが、いちばんよく使われる表示先でした。

    特定テーブルのUI Actionは、次のURLで確認できます。

    https://<YourInstance>/sys_ui_action_list.do?sysparm_query=table=incident^active=true^ORDERBYorder


    画像

    表示条件(condition)はどこで判定される?

    UI Actionは、いつでも表示されるわけではありません。「このState・このロールのときだけ出す」という条件を、conditionフィールドが受け持ちます。

    conditionを持つUI Actionは2073件あり、全2484件のうち約83%を占めていました。大多数のUI Actionが、特定の条件のときだけ出す表示制御を持っています。

    判定はサーバー側で行われます。条件を満たさない場合、ボタンのHTML/JavaScriptはそもそもブラウザへ送られず、ボタン自体が画面に現れません。クライアント側で隠すのではなく、描画する前にサーバーで判定するという順序です。

    前掲のリスト画面の「Resolve」では、conditionにnew global.IncidentUtils().canResolveIncident(current)が入っていました。解決可能な状態のインシデントでだけ、Resolveボタンが出る仕組みです。

    新規(未保存)か、既存(保存済み)かでも出し分けられます。

    • show_update=true … 保存済みのレコードのフォームで表示(2251件)

    • show_insert=true … 新規・未保存のフォームで表示(1350件)

    show_updateの方が多く、既存レコードを操作させるUI Actionが中心という結果でした。show_query=trueとshow_multiple_update=trueは、それぞれ1件・2件しかありません。照会時や複数選択時の表示は、ごく一部の限られた場面でしか使われていませんでした。


    押したときはどこで動く? client フラグでクライアント/サーバーが分かれる

    UI Actionをクリックしたとき、処理がブラウザ側で動くのか、サーバー側で動くのかを決めるのがclientフラグです。

    • client=true … onclickに書いたクライアントJavaScriptが動きます。g_formなどブラウザ側のオブジェクトを使い、入力チェックやダイアログ表示のような画面側で完結する処理に向きます。client=trueは975件、onclickを持つものは973件でした。

    • client=false … scriptに書いたサーバーJavaScriptが動きます。currentなどサーバー側のオブジェクトを使い、レコードの更新や別テーブルへの書き込みに向きます。client=falseは1509件でした。

    サーバー実行の方がクライアント実行よりやや多い結果です。

    クライアント側でチェックしてからサーバー側の処理を呼ぶ、という組み合わせもあります。client=trueのonclickの中で入力を検証し、問題なければgsftSubmit(...)のような仕組みで、同じaction_nameのサーバー処理を呼び出します。この連携が実行時にどう動くかまでは、今回の確認の範囲外です。


    画像

    主な固有フィールドを役割で整理すると、次のとおりです。ラベルは画面上の表示名で、実機どおり記載します。


    画像

    なお、クライアントスクリプトを分離スコープで動かすisolate_script=trueのUI Actionが332件あり、互換性に配慮した実行が一部で使われていました。


    同じ場所に複数並ぶとき、順番はどう決まる?(order)

    表示先が同じUI Actionが複数あるとき、並び順を決めるのがorderです。数値が小さいほど先(左)に並びます。

    order=100が1601件と最多でした。order=0が47件、100未満が310件、100超が572件、orderを持たない(空の)UI Actionは1件だけです。多くのUI Actionはorder=100のままにし、特定の並び順が必要なものだけ値をずらしていました。

    フォーム上部に複数のボタンが並ぶとき、orderの小さいものから左に置かれます。「Resolve」を「Close」より左に出したいなら、Resolveのorderを小さくする、という調整になります。


    どのテーブルに効く? table と継承の関係

    UI Actionが「どのテーブルに出るか」はtableで決まります。incidentに紐づくボタン、change_requestに紐づくボタンというように、対象テーブルごとにレコードが束ねられます。

    table=incidentのUI Actionは29件(active 27件)でした。table=change_requestは33件、table=taskは24件です。テーブルを指定しない(tableが空の)UI Actionも1件あり、特定テーブルに限らず扱われます。


    画像

    incidentはtaskを継承するテーブルです。incidentのフォームを開くと、incidentに紐づくUI Actionだけでなく、親のtaskに紐づくUI Actionも出ます。「incidentのボタン」を調べるときは、incidentだけでなくtaskのUI Actionも合わせて見る必要があります。継承時の表示マージ順の実測は、今回の確認の範囲外です。

    全フィールドは、次のURLで一覧できます。

    https://<YourInstance>/sys_dictionary_list.do?sysparm_query=name=sys_ui_action^elementISNOTEMPTY


    画像

    実機で気づいたこと

    同じPDIを1か月半ほど空けてもう一度見ると、sys_ui_actionの総数は2413件から2484件に増えていました。カスタマイズは何も加えていません。それでも71件増えています。OOTBの数値は固定値ではありません。パッチや自動更新のたびに動く、一時点のスナップショットだと考えた方が安全です。

    最初はボタンというと、画面側でさっと完結するクライアント処理のイメージを持っていました。実際にはclient=falseのサーバー実行が1509件で、client=trueより明らかに多い結果です。ボタンを押した先の多くは、サーバー側のcurrentオブジェクトを直接触っています。ブラウザ側だけで完結する処理は、むしろ少数派でした。

    table=incidentのUI Actionはわずか29件でした。Incidentフォームに並ぶボタンの数と比べると、少なく感じます。理由は継承です。incidentはtaskを継承するテーブルなので、task側に登録されたUI Actionもフォームに出てきます。同じボタンをテーブルごとに複製せずに済む設計だと考えられます。ここは推測です。


    実務では何に使える? 新しいUI Actionを作るときに見るフィールド

    新しくUI Actionを作るとき、あるいは既存のものを読み解くとき、見るフィールドは実質5つに絞れます。

    • table … 対象テーブル

    • 表示先フラグ … form_button / list_buttonなど、どこに出すか

    • condition・show_insert・show_update … いつ出すか

    • client・onclick・script … どこで何を動かすか

    • order … 並び順

    既存のボタンを調べるときは、対象テーブルのsys_ui_action一覧をorder順に並べれば、画面に出る順番のままフィールドを追えます。前述のsys_ui_action_list.do?sysparm_query=table=<テーブル名>^active=true^ORDERBYorderは、そのままチェックの起点として使えるURLです。表示先・condition・client・orderの4点を上から埋めていけば、ボタン1個分の設計が完成します。

    既存のUI Actionを複製して新規作成する方法もよく使われます。近いtableと表示先を持つレコードを1件開き、Insert and Stayで複製してからcondition・client・orderだけを書き換える進め方です。8つの表示先フラグをゼロから覚え直すより、手元の実例を1つ真似る方が早く仕上がります。


    さらに詳しく知りたい人へ


    まとめ

    UI Actionは、sys_ui_actionという1つのテーブルに、1ボタン=1レコードで保存されています。表示先はboolean、表示条件はcondition、実行場所はclientという、3つのフィールドを順に見ればボタン1個の仕組みが読み解けます。orderとtableは、その周りの並びと対象範囲を決める役割です。

    Resolveボタンを起点に追った今回の確認では、フォーム系のUI Actionが多数派で、サーバー実行が半分を超えるという結果になりました。数はPDIのバージョンで動きますが、フィールドの読み方そのものは変わりません。次にボタンを1個読み解くときは、結論で示した8段階のうちconditionとclientの2点から見ると、早く実行場所まで辿り着けます。

    用語

    • PDI … Personal Developer Instance(無料の検証用インスタンス)

    • OOTB … Out of the Box(初期設定のまま)

    • UI Action … フォーム/リスト上のボタン・メニュー・リンクの定義

    • sys_ui_action … UI Actionを格納するテーブル

    • table … そのUI Actionが紐づく対象テーブル名(画面ラベル: Table)

    • action_name … サーバー実行やgsftSubmitから参照する内部アクション名

    • condition … 表示条件(サーバー側で評価され、満たさないと描画しない)

    実機で調べるときに開いたURL

    • sys_db_object_list.do?sysparm_query=name=sys_ui_action … テーブル定義

    • sys_dictionary_list.do?sysparm_query=name=sys_ui_action^elementISNOTEMPTY … フィールド一覧

    • sys_ui_action_list.do?sysparm_query=table=incident^active=true^ORDERBYorder … incidentのUI Action

    • sys_ui_action_list.do … 全UI Action一覧


    参考リンク


    検証環境と未検証範囲

    確認した範囲(PDI/Zurich/2026-08-08 再確認のOOTBで取得。初回確認は2026-06-22):

    • sys_ui_actionの継承(sys_metadata配下)

    • 固有フィールド数(40)

    • 表示先フラグの件数分布

    • client(実行場所)分布

    • condition保有率

    • show_insert / show_update

    • order分布

    • isolate_script

    • table紐づき(incident / task / change_request / 空)

    確認していない範囲:

    • 各UI Actionのonclick / scriptの実際の挙動

    • gsftSubmitによるclient→server連携の実行時挙動

    • 継承テーブルでの表示マージ順の実測

    • Workspace向け(form_button_v2 / client_script_v2)やDeclarative Actionの表示挙動

    • UI Builderでの扱い

    • ドメイン分離環境での差異

    件数は2026-08-08時点の値です。本番環境やカスタマイズ済み環境では、UI Actionの数・内容・表示条件が異なります。

     
     
    ServiceNowのPDI(Personal Developer Instance)を実機で観察して、Noteに記事を書いています 実装・運用・教育の現場視点で淡々と記録中です リクエストがあればその記事も書きます 個人の観察日記です

    あなたへのおすすめ