catalog client scriptで別のカタログアイテムの値を取得する方法

ayaka_u
Kilo Contributor

こんにちは。

catalog client scriptを使い、
「再申請対象」欄が入力された際に、入力されたRequested Itemの情報を
それぞれ反映させようとしております。

find_real_file.png

 

現在、下記のようなScriptを実装しているのですが、
「now_GR.variables.getElements is not a function」というエラーが発生しているため、
値がそもそも取得できていません。

ですので、catalog client scriptでの
他レコードからの値の取得方法をご教示いただきたいです。

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }

    //Type appropriate comment here, and begin script below
	
    var now_GR = new GlideRecord('sc_req_item');
	if (now_GR.get(newValue)) {
		var variables = now_GR.variables.getElements();
		for (var i=0;i<variables.length;i++) { 
			var question = variables[i].getQuestion(); 
			g_form.setValue(question.getLabel(),question.getValue());
		} 
	}
}
1 ACCEPTED SOLUTION

iwai
Giga Sage
//now_GR.variables.getElements is not a function
var variables = now_GR.variables.getElements();

Catalog Client Script の Variables は ドットウォークができません。そのためvariablesの先のfunctionもありません。GlideRecordの仕様も Client Script は、Server側と違います。制約が多いので多くのデータを取得する場合はGlideAjaxを使ってServer側に処理を移行して結果をClient側に返す処理を行います。

詳しくはDOCSなどを参照してみてください。

参考に同じように処理が出来るScriptを書いてみました。

Client Script

//Catalog Client Script
//再申請対象 Reference type
function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }
    // Server側に値を取得する処理 GetRequestItem (新規作成した処理)
    var ga = new GlideAjax('GetRequestItem');
    //Server側のクラスのfunctionの名前
    ga.addParam('sysparm_name', 'get');
    //Server側に渡す値
    ga.addParam('sysparm_request_item_sys_id', newValue);
    //Server側に処理を移行する、非同期で処理が戻ってくる。
    ga.getXML(function(response) {
        //Server側からの値を取得する
        var jsonResponse = response.responseXML.documentElement.getAttribute('answer');
        if (jsonResponse) {
            //今回はJSON形式の文字で値を格納したのでObjectに変換する。
            var objResponse = JSON.parse(jsonResponse);
            for (var name in objResponse) {
                //同じ名前のFieldに値を設定する
                g_form.setValue(name, objResponse[name].getValue);
            }
        }
    });
}

 

Script include

// Script include
// Client Callable: True
// Name: GetRequestItem 
var GetRequestItem = Class.create();
GetRequestItem.prototype = Object.extendsObject(AbstractAjaxProcessor, {
	get : function(){
		// Client側の値を取得
		var reqItemSysid =this.getParameter('sysparm_request_item_sys_id');
		if(reqItemSysid){
			//CatalogItemを検索
			var gr = new GlideRecord('sc_req_item');
			if(gr.get(reqItemSysid)){
				//Variablesが持つElementの一覧を取得
				var items = gr.variables.getElements();
				var objResponse = {};
				for(var i = 0;i < items.length;i++){
					//フィールド名や値など変数に格納する。
					objResponse[items[i].getName()] = {
						'getLabel': ''+items[i].getLabel(),
						'getDisplayValue': ''+items[i].getDisplayValue(),
						'getValue': ''+items[i].getValue()
					};
				}
				//Client側に値を戻す
				return JSON.stringify(objResponse);
			}
		}
	},

    type: 'GetRequestItem'
});

View solution in original post

3 REPLIES 3

Ikeda1
Mega Guru

ayakaさん

 

カタログクライアントスクリプトはクライアントサイドのスクリプトとなり他のレコードの問い合わせはできません。

カタログクライアントスクリプトでサーバサイドのスクリプトを処理するためには、スクリプトインクルードを使用して、カタログクライアントスクリプトから作成したスクリプトインクルードを呼び出す必要があります。

スクリプトインクルードの使い方は以下を参考にしてみてください。

ズンドコキヨシ with ServiceNow - ServiceNowアプリの作り方 - Qiita

ServiceNow - 複数のレコードを取得するAjax呼び出し - Qiita

iwai
Giga Sage
//now_GR.variables.getElements is not a function
var variables = now_GR.variables.getElements();

Catalog Client Script の Variables は ドットウォークができません。そのためvariablesの先のfunctionもありません。GlideRecordの仕様も Client Script は、Server側と違います。制約が多いので多くのデータを取得する場合はGlideAjaxを使ってServer側に処理を移行して結果をClient側に返す処理を行います。

詳しくはDOCSなどを参照してみてください。

参考に同じように処理が出来るScriptを書いてみました。

Client Script

//Catalog Client Script
//再申請対象 Reference type
function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }
    // Server側に値を取得する処理 GetRequestItem (新規作成した処理)
    var ga = new GlideAjax('GetRequestItem');
    //Server側のクラスのfunctionの名前
    ga.addParam('sysparm_name', 'get');
    //Server側に渡す値
    ga.addParam('sysparm_request_item_sys_id', newValue);
    //Server側に処理を移行する、非同期で処理が戻ってくる。
    ga.getXML(function(response) {
        //Server側からの値を取得する
        var jsonResponse = response.responseXML.documentElement.getAttribute('answer');
        if (jsonResponse) {
            //今回はJSON形式の文字で値を格納したのでObjectに変換する。
            var objResponse = JSON.parse(jsonResponse);
            for (var name in objResponse) {
                //同じ名前のFieldに値を設定する
                g_form.setValue(name, objResponse[name].getValue);
            }
        }
    });
}

 

Script include

// Script include
// Client Callable: True
// Name: GetRequestItem 
var GetRequestItem = Class.create();
GetRequestItem.prototype = Object.extendsObject(AbstractAjaxProcessor, {
	get : function(){
		// Client側の値を取得
		var reqItemSysid =this.getParameter('sysparm_request_item_sys_id');
		if(reqItemSysid){
			//CatalogItemを検索
			var gr = new GlideRecord('sc_req_item');
			if(gr.get(reqItemSysid)){
				//Variablesが持つElementの一覧を取得
				var items = gr.variables.getElements();
				var objResponse = {};
				for(var i = 0;i < items.length;i++){
					//フィールド名や値など変数に格納する。
					objResponse[items[i].getName()] = {
						'getLabel': ''+items[i].getLabel(),
						'getDisplayValue': ''+items[i].getDisplayValue(),
						'getValue': ''+items[i].getValue()
					};
				}
				//Client側に値を戻す
				return JSON.stringify(objResponse);
			}
		}
	},

    type: 'GetRequestItem'
});

ayaka_u
Kilo Contributor

iwaiさん、返信ありがとうございます。

頂いたサンプルプログラムを試してみたところ、問題なく動きました。
ありがとうございました。