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

ServiceNowはClient Scriptを書かずにフォームを動かせる? UI Interactionの40部品を実機で読む


    「この項目を選んだら、あの欄を必須にしたい」。この程度の要望でも、これまでは Client Script を1本書くのが定番でした。UI Interaction は、その種の画面操作を部品を並べて組み立てる仕組みです。UI Builder で作る画面のために用意されたもので、従来のフォーム制御とは別系統になります。何ができる仕組みなのかを押さえたうえで、実機の中身を読みました。

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

    フォームの挙動を作るとき、本当に欲しいもの

    「優先度が高いときだけ、この欄を必須にする」。現場から来る要望はこの粒度です。

    作る側が欲しいのは3つあります。書かずに済むこと。あとから何をしているか読めること。そして既存の資産を捨てずに済むことです。

    Client Script で書けば実現はできます。ただ数が増えると、どの条件でどれが動くのかが追えなくなります。読めなくなるのが一番の負担です。

    Client Script・UI Policy と何が違うのか

    フォームの挙動を作る手段は、これまで2つありました。位置づけを整理します。

    UI Policy は宣言的です。「条件がこうなら、この項目を必須にする」と書けば、順番を意識せずに済みます。単純な制御には向いていますが、複数の条件が絡むと実行順に依存します。

    Client Script はコードです。何でもできる代わりに、いつ動くか(onLoad / onChange / onSubmit)を自分で選び、順序も自分で管理します。

    UI Interaction はその中間にあります。ひとつひとつの操作が用意された部品である点は UI Policy 寄り。処理の順序を自分で繋ぐ点は Client Script 寄りです。順序が図として見えるのが、この仕組みの持ち味になります。

    従来の2つの違いはClient ScriptとUI Policyの違い(フォーム挙動)で扱いました。

    決定的な違いは「どの画面のためか」

    もうひとつ重要な違いがあります。この仕組みはUI Builder で組む画面のためのものです。

    根拠は公式のフィールド説明にあります。required_builder_translations という項目の説明が「JSON Array, holding the translations required by this UI interaction in UI Builder」。UI Builder という名前が明記されています。

    従来のフォームで動くかどうかは、この記事では確認していません。ワークスペースと従来フォームの違いはServiceNowのワークスペースは従来のフォームと何が違う?にまとめました。自分の環境がどちらを使っているかで、そもそも使えるかが変わります。

    公式の説明で仕組みを読む

    3つのテーブルの主要な項目に、ServiceNow 自身の説明が付いていました。これを読むと構造が分かります。

    部品の側(sys_ui_interaction_step_definition):

    step_type は「Determines how the step is executed alongside the step options」。ステップをどう実行するかを決める項目です。step_options が「Configuration options for the step type」で、その実行方法に対する設定になります。

    input_definitions は「Definitions of inputs needed for the execution of the step」。その部品を動かすのに必要な引数の定義です。

    events は「Definitions of events that can be triggered by the step」。部品が発火できるイベントの定義で、これが後で遷移のきっかけになります。

    associated_types の説明は親切でした。前半は「Types of UI interactions in which the step definition can be used」。後半に 「If empty, the step definition is available in all types」とあります。空欄なら全種類で使える、と明記されていました。

    組み立ての側(sys_ui_interaction):

    steps は「Steps to be executed in the UI interaction」。on_start は「Comma separated list of steps to execute when the UI interaction starts」でした。開始時に動かすステップをカンマ区切りで並べると書かれています。複数の起点を持てるということです。

    inputs は「Definitions of inputs to be passed to the UI interaction」。組み立てたもの全体が引数を受け取れます。

    sys_overrides は「UI interaction being overridden by the current record」。標準のものを上書きする仕組みが用意されています。標準を直接編集せずに差し替えられる、という意味で実務的に重要です。

    テーブルの性格

    3つとも Application File を継承していました。更新セットで移送される、アプリケーションの一部という扱いです。自分で作ったものは他の環境へ持っていけます。

    結論:40部品すべてが有効で、半分以上がフォーム操作

    40件の部品はすべて有効な状態で入っていました。9つのカテゴリに分かれ、いちばん多いのが項目を操作する Field action の11件です。

    部品を並べて繋ぐと1つの動作になります。実機には組み立て済みの例が1件だけ入っていて、4つのステップがイベント名で分岐しながら繋がっていました。

    Client Script を呼ぶ部品も、サーバスクリプトを走らせる部品も、この40件のなかにあります。スクリプトを全廃する仕組みではありません。書かずに済むところを減らす仕組みです。


    画像

    3つのテーブルでできている

    関係するテーブルは3つです。どれも Zurich には無く、Australia で追加されていました。

    sys_ui_interaction_step_definition が部品のカタログで40件。sys_ui_interaction_type が部品を使える場所の分類で3件。sys_ui_interaction が組み立て済みの動作で1件です。


    画像

    タイプの3件は Generic / Form / List でした。説明によると Generic はどのコンポーネントでも使える汎用。Form はフォームの保存や検証に対応し、List は一覧の再読込やスクリプトに対応します。


    画像

    部品側の associated_types を数えると、Form が21件、空欄が14件、List が5件でした。空欄はどこでも使える部品という意味になります。

    40件を9つのカテゴリで見る


    画像

    Field action が11件で最多。Form action が10件で続きます。この2つで半分を超えます。

    残りは Modal が5件、List action が5件、Navigation が4件、Modeless dialog が2件。Alert、Logic、Script はそれぞれ1件ずつでした。

    配分から意図が読めます。部品の過半数がフォーム上の操作に割り当てられています。 一覧や画面遷移は最低限で、力を入れたのはフォームです。

    項目を操作する11件

    いちばん厚いカテゴリを詳しく見ます。


    画像

    Set field value の説明は「利用者が入力したのと同じ扱いで値を入れる」でした。裏で値だけ書き換える動きとは違い、入力イベントを伴う扱いになります。この違いは、他のスクリプトが反応するかどうかに影響します。

    Set field visibility / Set field read-only / Set field required / Set field invalid の4つは、いずれも状態の切り替えでした。説明文はどれも「〜にする、または解除する」という書き方で、片道の操作ではありません。

    メッセージ系が3件あるのも特徴です。項目の下に文言を出す Add field message、それを消す Clear field message(s)、種類を指定してまとめて消す Clear field messages by type。出すだけでなく消す手段が用意されています。

    これは実装上ありがたい設計です。メッセージを出す処理だけあって消す処理が無いと、条件が変わったあとも表示が残ります。

    残る5カテゴリの中身

    Field action と Form action 以外も見ておきます。

    Modal の5件は、確認や入力を求める画面です。単純な通知の Alert / はい・いいえを聞く Confirm / 削除の確認に使う Confirm and destroy / 利用者に文字を入力させる User input / 自由に組み立てる Create modal。用途ごとに別の部品になっていました。

    Confirm and destroy が独立しているのが目を引きます。通常の確認と、消す操作の確認を分けてあるということです。取り返しのつかない操作には別の見た目を用意する、という考え方が部品の粒度に出ています。

    List action の5件は一覧の操作です。並べ替えの Sort / グループ化の Group by column / 再読込の Refresh list / 絞り込みの Set query / Execute client script。Set query はエンコード済みクエリを渡す形なので、条件を文字列で組み立てられます。

    Navigation の4件は移動先の種類で分かれています。レコードへ、外部URLへ、画面のルートへ、そしてワークスペースのタブを閉じる。閉じる操作が移動の仲間に入っているのは、タブで画面を持つ基盤ならではです。

    Modeless dialog は2件だけでした。自由に組み立てる Create modeless dialog と、フォームを開く Form。フォームを開くケースだけ専用の部品が用意されています。

    部品の粒度は揃っていない

    40件を眺めると、粒度がばらついています。

    Set field value のように操作が1つだけの部品もあれば、Submit form using UI action のように検証と実行をまとめた部品もあります。Create modal に至っては、中身を自分で組み立てる器です。

    これは使いやすさを優先した結果だと考えています。よく使う組み合わせを1部品にしておけば、並べる手間が減るためです。粒度を厳密に揃えると、単純なことをするのに部品が5個必要になってしまいます。

    読むときは「この部品は何ステップぶんか」を意識しておくと、後から動きを追いやすくなります。

    フォーム全体を操作する10件

    Save、Validate、Refresh form のような基本操作に加えて、既存資産を呼ぶ部品が3つあります。

    Execute UI action は UI Action をそのまま実行するもの。Execute client script は Client Script を実行します。Submit form using UI action はフォームを検証してからサーバ側で UI Action を走らせる部品でした。

    つまり、これまで作った UI Action や Client Script は捨てなくてよい。新しい仕組みから呼び出せます。UI Action の作りそのものはClient ScriptとUI Policyの違い(フォーム挙動)で扱った領域と重なります。

    部品の入力はどう定義されているか

    各部品は input_definitions に受け取る引数を持っています。Set field value を開くと4つありました。

    対象の項目名を指す fieldName が必須。実際に入れる値の value は任意。表示用の文字列を別に渡す displayValue も任意。フォームを変更済み扱いにするかを決める setFormDirtyState は真偽値で任意でした。

    displayValue が別にあるのは参照フィールドのためでしょう。参照項目は内部的に sys_id を持ち、画面には名前を出します。両方を渡せる形になっています。参照の仕組みは参照フィールドと参照修飾子:候補はどう絞られるかに書きました。

    setFormDirtyState があるのも実務的です。プログラムから値を入れたときに「未保存の変更あり」と扱うかどうかは、場面によって変えたいところです。

    初期値を自動で埋める場面では false が向きます。利用者が何もしていないのに「保存しますか」と聞かれるのは不親切だからです。逆に、値を書き換えて保存を促したい場面では true にします。

    こうした細かい制御が引数として出ているのは、実際の運用で必要になった項目だからでしょう。部品の入力定義を読むと、設計者が想定した使い方が見えてきます。

    組み立て済みの1件を分解する

    sys_ui_interaction には1件だけレコードがありました。ラベルは Execute UI action and redirect です。


    画像

    使っている部品は Execute UI action、If/else、Form、Navigate to record の4つ。開始点は on_start で execute_ui_action_1 を指しています。

    遷移はイベント名で分かれる

    steps の中身を見ると、単純な順番ではありませんでした。各ステップが nextSteps を持ち、そのキーが遷移のきっかけの名前になっています。

    execute_ui_action_1 の次は redirect というキーで if_else_1 へ。if_else_1 の次は if というキーで form_1 へ。form_1 の次は MODELESS_FORM#SECONDARY_BUTTON_CLICKED というキーで navigate_to_record_1 へ繋がります。

    最後のキーが分かりやすい例です。モードレスダイアログの副ボタンが押されたときだけ、レコード画面へ移動します。押されなければ、そこで止まります。

    条件分岐ではなく、発生したイベントに応じて次が決まるモデルです。フローチャートというより、イベント駆動の状態遷移に近い作りでした。

    値の渡し方は2種類

    steps の各 inputs には type が付いていて、2種類ありました。

    DATA_OUTPUT_BINDING は別の場所の値を参照するもので、["inputs","uiAction"] のようにアドレスで指定します。インタラクション全体が受け取った引数を、個々のステップに配る仕組みです。

    JSON_LITERAL はその場に書いた固定値です。ダイアログの高さ700、閉じるボタンを出すかどうかの true、といった設定がこの形で入っていました。

    参照と固定値を型で区別してあるので、後から読んでも「これは外から来る値か、ここで決めた値か」が判別できます。

    このインタラクション自体も引数を取る

    inputs を見ると、組み立て済みの動作そのものが引数を受け取る作りでした。

    uiAction は sys_ui_action への参照で、必須。referenceFilter に active=true が入っていて、有効な UI Action だけが候補に出ます。説明文には「選んだ UI Action はクライアント側・サーバ側とも丸ごと実行される」とありました。

    openInDialog は真偽値で既定は false。true にすると、UI Action のリダイレクト先がモードレスダイアログで開きます。false ならページ全体で開きます。

    同じ動作を、どの UI Action に対しても使い回せる形になっています。部品を並べたものを、さらに部品として扱えるということです。

    部品が1件しか組み立てられていない意味

    sys_ui_interaction に入っていたのは1件だけでした。40件の部品に対して、完成品は1つ。

    OOTBの状態としては、これは自然です。部品は製品として提供するもので、組み立ては各社が自分の要件に合わせて行います。標準で大量の完成品を入れると、使わないものが残ります。

    入っている1件は見本として読むのがよさそうです。Execute UI action and redirect という名前のとおり、既存の UI Action を実行してから画面を移す、という典型的な流れを4ステップで表現しています。

    作り方を知りたいときは、この1件の steps を読むのが近道でしょう。バインディングの書き方、遷移キーの付け方、外部から受け取る引数の定義。必要な要素が一通り入っています。


    画像

    40という数をどう見るか

    多いのか少ないのか、判断が分かれるところです。

    Client Script でできることを全部並べたら40では収まりません。DOM操作も、任意のAPI呼び出しも入りません。表現力という意味では明確に狭い範囲です。

    一方で、実際の案件で書く Client Script の大半は単純な表示制御です。値を見て出す、隠す、必須にする、メッセージを出す。この範囲なら40件で足ります。

    よく使う処理を先に部品化した、という設計に見えます。カバー率で言えば高く、表現力で言えば限定的。その割り切りが40という数に出ています。


    画像

    step_type で分けると Form が21件で最多でした。toolbox_category の9分類とは別の切り口で、どのコンポーネントに効くかを表しています。

    従来のフォーム制御と何が違うのか

    同じことをする手段は前からありました。並べて考えると位置づけがはっきりします。

    UI Policy は条件と結果を宣言的に書く仕組みです。「優先度が1なら、この項目を必須にする」という形で、順番を意識せずに書けます。

    Client Script は処理をコードで書きます。何でもできる代わりに、いつ動くかを自分で選ぶ必要があります。onLoad / onChange / onSubmit のどれで動かすかも、動作の順序も自分で管理する形です。

    UI Interaction はその中間に見えます。処理の順序を明示的に繋ぐ点は Client Script 寄り。ひとつひとつの操作が用意された部品である点は UI Policy 寄りです。

    順序を持つことの意味

    UI Policy で難しいのは、複数の条件が絡む処理です。条件Aで項目を出し、条件Bで消す。両方が成り立ったときにどちらが勝つのかは、実行順に依存します。

    UI Interaction は繋がりを自分で書くので、順序が図として見えます。読んで追える形になっているのは、保守の面で扱いやすい性質です。

    代わりに、宣言的に書けば済む単純な制御まで手順として書くことになります。簡単な要件には UI Policy のほうが速い、という関係は変わらないでしょう。

    既存の資産をどう扱うか

    Execute UI action と Execute client script があるので、移行は段階的にできます。

    いま動いているものを全部作り直す必要はありません。新しい画面から既存の処理を呼び、少しずつ部品に置き換えていく進め方が取れます。

    外部データの取り込みでも、既存の仕組みを段階的に載せ替える考え方が使われていました。ServiceNowの外部データ取込はなぜ2段階?で扱った構造と、発想は近いものがあります。

    40件をどう調べたか整理しておく

    この記事で見たテーブルは3つでした。関係を整理しておきます。

    sys_ui_interaction_step_definition は部品のカタログです。ここに無いことはできません。40件という数は、この画面基盤で表現できる操作の上限を表しています。

    sys_ui_interaction_type は使える場所の分類でした。Generic はどこでも、Form はフォーム、List は一覧。部品側の associated_types と対応しています。

    sys_ui_interaction が実際に使う単位です。部品を並べ、繋ぎ、外から引数を受け取る形になっていました。

    部品を探すときの順番

    自分の要件で使えるかを調べるとき、順番があります。

    まず toolbox_category で当たりを付けます。項目を触りたいなら Field action、画面を移りたいなら Navigation。9つしかないので絞るのは簡単です。

    次にその中の label と description を読みます。説明は1行なので、40件全部読んでも時間はかかりません。

    最後に input_definitions を開いて、渡せる値を確認します。ここまで見れば、要件を満たせるかが判断できます。

    無い操作をどうするか

    40件で足りないときは Execute client script か Server script を使うことになります。

    ただし、そこに逃げる前に確認したいことがあります。近い部品を組み合わせて表現できないか、という点です。If/else があるので条件分岐は作れますし、部品を繋ぐ順序も自由に決められます。

    スクリプトを入れると、その部分だけ図から中身が見えなくなります。組み立てで済むなら、そちらを選ぶ理由があります。


    画像

    Modal の5件はこの画面で全部読めます。用途ごとに部品が分かれている様子が確認できます。

    用語

    UI Interaction:画面上の操作を、部品を並べて組み立てる仕組み。実体は sys_ui_interaction。

    ステップ定義:組み立てに使う部品1つぶんの定義。sys_ui_interaction_step_definition に40件入っている。

    toolbox_category:部品を分類する見出し。編集画面のツールボックスに出る区分だと考えられる。

    モードレスダイアログ:開いている間も背面の画面を操作できるダイアログ。閉じるまで他を操作できないモーダルと対になる。

    バインディング:ステップに値を渡す方法の指定。参照(DATA_OUTPUT_BINDING)と固定値(JSON_LITERAL)がある。

    実機を見て気づいたこと

    「消す部品」が最初から用意されている

    メッセージを出す部品と、消す部品が対になっていたのが目を引きました。しかも消すほうが2種類あります。

    自分で仕組みを作るとき、出す処理は真っ先に作りますが、消す処理は後回しになりがちです。条件が変わってメッセージが残り続ける不具合は、実際によく見ます。

    最初から対で用意してあるのは、その手戻りを設計側で潰しているということです。40件のうち3件をメッセージの出し入れに割いているのは、意識的な配分だと考えています。

    スクリプトを呼ぶ部品が入っている

    ノーコードの仕組みなのに、Execute client script と Server script が部品として入っていました。

    最初は「せっかくスクリプト不要にしたのに」と思いましたが、逆でした。全部を部品で表現しようとすると、部品の数が際限なく増えます。どうしても足りないところにスクリプトの出口を1つ置いておけば、部品カタログを小さく保てます。

    40件という数が現実的なのは、この逃げ道があるからでしょう。処理を書く場所の選び方はServiceNowで処理を書くならどこ? Business Rule・Client Script・ACLの使い分けでも扱いました。

    遷移のキーに画面イベントの名前が生で出ている

    MODELESS_FORM#SECONDARY_BUTTON_CLICKED という文字列がそのまま入っていたのは意外でした。

    抽象化された条件式は使わず、コンポーネントが発火するイベント名を直に置いています。読む側からすると分かりやすい反面、部品の内部実装に近い名前が定義データに露出していることになります。

    編集画面ではおそらく選択肢として出るのでしょう。ただ、レコードとして中身を読むと、この仕組みがコンポーネントのイベントに直結していることがはっきり分かります。

    実務では何に使えるか

    既存の Client Script を棚卸しする材料になる

    いま動いている Client Script のうち、どれがこの40件で置き換えられるかを見る使い方ができます。

    置き換えやすいのは、単純な表示制御です。値を見て項目を出す、必須にする、読み取り専用にする。この手の処理は Field action の11件でほぼ表現できます。

    置き換えにくいのは、外部を呼ぶものや複雑な計算をするものです。そこはスクリプトのまま残します。入力チェックをどこに書くかの判断はServiceNowの入力チェックはClient ScriptとBusiness Ruleのどちらに書く?にまとめています。

    ワークスペース側の話であることに注意

    step_type に Page や List が出てくること、Navigation に「Close Workspace tab」があることから、この仕組みは新しい画面基盤に紐づくものだと読めます。

    従来のフォームと新しいワークスペースで、どちらを直せば画面が変わるのかは別の問題です。ServiceNowのワークスペースは従来のフォームと何が違う?で切り分けを扱いました。

    自分の環境がどちらを使っているかを確かめてから検討する順番になります。

    まず読むだけでも価値がある

    40件のラベルと説明を眺めるだけで、この画面基盤で何ができるかの見取り図になります。

    たとえば「一覧を絞り込む」は List action の Set query で表現されます。「確認ダイアログを出す」は Modal の Confirm。実装方法を調べる前に、そもそも用意されているかを確かめられます。

    項目が画面に出ない原因の切り分けと同じで、手段の一覧を先に持っておくと調査が速くなります。切り分けの手順はServiceNowで項目が画面に出ないのはなぜ?に書きました。

    自分の環境で確認するときのURL

    自分のインスタンス名を先頭に付けると、同じ画面が開けます。

    • 部品をカテゴリ別に見る:/sys_ui_interaction_step_definition_list.do?sysparm_query=GROUPBYtoolbox_category

    • 項目操作の部品だけ見る:/sys_ui_interaction_step_definition_list.do?sysparm_query=toolbox_category%3DField%20action

    • 使える場所の分類:/sys_ui_interaction_type_list.do

    • 組み立て済みの動作:/sys_ui_interaction_list.do

    • UI Action の一覧:/sys_ui_action_list.do

    引用した公式説明を自分で開く

    この記事で引用した説明文は、ServiceNow が製品に同梱しているフィールドのドキュメントです。次のURLを自分のインスタンスで開けば、引用元の原文にあたれます。

    • フィールドの公式説明(引用元):/sys_documentation_list.do?sysparm_query=nameINsys_ui_interaction,sys_ui_interaction_step_definition^hintISNOTEMPTY

    検証範囲とおことわり

    Australia の PDI(OOTB)で 2026-08-10 に確認しました。件数はこの環境の実測値です。

    確認していないことがあります。UI Interaction を新規に作っていません。組み立て済みの1件を実行してもいません。読み取りだけで、レコードの中身から構造を追いました。

    ワークスペース上で実際にどう見えるか、編集画面がどうなっているかも見ていません。テーブルのデータから読み取れる範囲に絞っています。

    Zurich 側に同等の仕組みが別の名前で存在するかも調べていません。3つのテーブル名が Australia の新規テーブル一覧に入っていた、という事実だけが確認できたことです。

    関連記事

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

    あなたへのおすすめ