スポンサーリンク

【pleasanter】$p.apiGetをやってみた~単一レコードの取得

プリザンター
スポンサーリンク
※当サイトは広告を含みます

前回は$p.apiGetでサイトのデータを取得する&取得したプルダウンリストを設定する、をやりました。
【pleasanter】$p.apiGetをやってみた~複数データを取得してプルダウンリストを作成する

今回は単一レコードを取得する、をやってみたいと思います。

参考とさせていただいたサイト

公式マニュアル
https://pleasanter.org/manual/script-api-get
https://pleasanter.org/manual/api-view

具体的な書き方を参考にさせていただいたサイト
https://imageinformationsystem.hatenablog.com/entry/2018/10/26/095113
https://imageinformationsystem.hatenablog.com/entry/2018/12/14/170000

1.$p.apiGet における複数データ取得と単一データ取得の違い

そもそも$p.apiGetとは? 前回も書いていますが、プリザンターの方で用意してくれている、値をゲットするためのメソッドです。自身のテーブルや、ほかのテーブルからなにか持ってきたいときに使えるらしい!というものらしい。

公式マニュアルよりコピペさせていただいたコード。

$p.apiGet({
    id: (サイトID),
    data: {
        (取得条件)
    },
    done: (任意の処理),
    fail: (任意の処理),
    always: (任意の処理)
});

$p.apiGetにおける複数データの取得と単一データの取得は、id: の部分に指定する値が、サイトのIDだとサイトごと持ってくる、レコードのIDだとそのレコードを持ってくる、ということだと理解しています。
ま、サイトIDで取得しても、取得条件が1つしかマッチしない条件であれば単一データの取得ということにもなりますが。。。

レコードを指定したいときはこのサイトのこのレコードっていう指定方法じゃなくていいの???サイトを指定しなくてもいいの???とえええっと思いましたが、「タイトルとはなんぞや」の記事で書きましたが、プリザンターのIDは、(同一サーバー内の)プリザンターの中で一つ 

なので、指定したIDがサイトIDだったらサイトごと取得しに行くし、レコードIDだったらそのレコードを取得しに行く、ということですな。

2.やってみる $p.apiGet でレコードを取得する

試してみるサイトは前回の記事と同じものを使います。

(1)前回のおさらい 利用するテーブルの仕様 前回のコード

親サイト:データテーブル(ID:256)

子サイト 売り上げ表(サイトID:255)

前回やったコードで、子サイト「売り上げ表」で商品区分(分類B)を指定すると、指定した区分に応じた商品が「商品」(分類A)にプルダウンリストとしてセットされ、親サイトにある商品を選択できるようになっています。
プルダウンリストの値には親サイトのレコードのID、表示名にはレコードのタイトルがセットされます。なので、リストから選択すると、「商品」(分類A)のにはレコードIDがセットされることになります。

const siteID = 256;

$p.on('change', 'ClassB', function () {
    const selectVal = $("#Results_ClassB").val();

    $p.apiGet({
        id: siteID,
        data: {
            'ApiKey': '',
            'Offset': 0,
            'View': {
                'ColumnFilterHash': {
                    'ClassA': '["' + selectVal + '"]'
                }
            }
        }, 
        done: function(data) { 
            $("#Results_ClassA").children().remove();
            $('#Results_ClassA').append($('<option>').val("").text(""));
            for (let i = 0; i < data.Response.Data.length; i++){
                $('#Results_ClassA').append($('<option>').val(data.Response.Data[i].ResultId).text(data.Response.Data[i].ItemTitle));
            }
         },
        fail: function(err) { console.log("error"); }
    });
})

(2)今回やりたいこと

さて、それを踏まえて今回やりたいことは!

「商品」を選択したら、「単価」に親テーブル情報から単価を持ってきてセットする、ということをやりたいと思います。

3.すこしずつやってみる

(1)商品の値の取得

ええと、だから、分類A「商品」を選択したら、分類Aの値にはResultID、つまり選択した商品のレコードIDが入るはず。
そしたらそのIDをapiGetすればいい、ということに違いない。

少しずつ確認しながらやってみます。前回のコードの後ろに(前でもいいです)以下のコードを追加します。

$p.on('change', 'ClassA', function () {
    const trgID = $("#Results_ClassA").val();
    console.log(trgID);
})

$p.on は前回も使いました。
指定した項目(今回は分類A(ClassA))が変わったら(change)、functionに書いてあることを実行する、ということです。

const trgID = $(“#Results_ClassA”).val();
は、分類Aの値を取得し、trgIDに代入します。
次の行でtrgIdをコンソールに出力する処理を書いています。

コードを追加し、新規作成→「区分」選択→プルダウンリストから商品を指定、してみました。
※上記コードだけでなく、前回のコードも入れておいてください!でないとプルダウンリストが表示されません。

コンソールに 283 と表示されています。
親テーブルで確認してみると、はさみのレコードIDは 283 ですね。
よかった!とれてる!

(2)レコードの取得

$p.apiGet でレコードのデータを取得しましょう。

コードを書き換えます。

$p.on('change', 'ClassA', function () {
    const trgID = $("#Results_ClassA").val();
    
    $p.apiGet({
        id: trgID,
        data: {
            'ApiKey': '',
            'Offset': 0,
        }, 
        done: function(data) { 
	    console.log(data);
         },
        fail: function(err) { console.log("error"); }
    });
})

id には分類A商品から取得したレコードIDをセットします。
前回はViewで取得条件を設定しましたが、単純にレコードを取ってくるだけなので、Viewは指定しません。
dane で、取得したデータをコンソールに出力する処理を書いています。

結果を見てみます。コンソールに取得したDataが書き出しされています。

ふむふむ。単一レコードでも配列(Array)の形でDataが返ってくるのですね。

(3)取得したレコードから単価(数値A)を取得

取得したデータから単価(数値A)の値を取得して、コンソールに出力する、という処理にコードを書き換えます。

done の処理だけ書き換えます

done: function(data) { 
    const price = data.Response.Data[0].NumHash.NumA;
    console.log(price);
},

data.Response.Data[0].NumHash.NumA で、取得したデータから数値Aの値を取得します。
注意するのはとってきたデータは一つでも、レスポンスデータは配列なのでdata.Response.Data[0]と配列インデックス[0]を指定するところです。

コンソールを見てみましょう。
指定した「はさみ」の単価 700 円が出てますね!よかった。

(4)作成中レコードの単価に取得した値を入れ込む

さて!取得して生きた値をこのレコードの「単価」欄に入れ込みたいと思います。

プリザンターのメソッド $p.set を使います。
https://pleasanter.org/manual/script-set

以下、公式マニュアルより

概要
画面上の値変更と$p.dataへの格納を同時に行うことが出来るメソッドの説明をします。スクリプトでテキストボックスなどの値を変更する場合は$(‘#Results_ClassA’).val(‘変更後の値’);のように値を変えても更新されません。これはプリザンターのクライアント側の変数である「$p.data」にユーザが変更した値のみが格納され、postする仕様となっている為です。

使い方
Javascript
$p.set($(‘変更したいフォームのid名’), ‘変更後の値’)

引用元;https://pleasanter.org/manual/script-set

よくわからないけど、値を変更してくれるらしい。

done: の部分を書き換えます。

done: function(data) { 
    const price = data.Response.Data[0].NumHash.NumA;
    $p.set($('#Results_NumA'), price);
},

$p.set($(‘#Results_NumA’), price)

$(‘#Results_NumA’) 数値Aのidを設定し、変更したい要素を指定しています。

変更後の値には price 、つまりゲットしたデータのNumAの値を指定しています。

今度はコンソール出力していないので、画面を見てみましょう。

動画じゃなくてごめんなさい。でも、単価に値が表示されましたよ!
商品を変更すると、単価も変更されます。

ちなみに、変数priceに一度値を代入していますが、変数を経由しなくても大丈夫です。

$p.set($('#Results_NumA'),  data.Response.Data[0].NumHash.NumA);

このへんはお好みで。

4.コード全文

ちまちまとやってきましたが、コード全文です。

const siteID = 256;
$p.on('change', 'ClassB', function () {
    const selectVal = $("#Results_ClassB").val();

    $p.apiGet({
        id: siteID,
        data: {
            'ApiKey': '',
            'Offset': 0,
            'View': {
                'ColumnFilterHash': {
                    'ClassA': '["' + selectVal + '"]'
                }
            }
        }, 
        done: function(data) { 
            $("#Results_ClassA").children().remove();
            $('#Results_ClassA').append($('<option>').val("").text(""));
            for (let i = 0; i < data.Response.Data.length; i++){
                $('#Results_ClassA').append($('<option>').val(data.Response.Data[i].ResultId).text(data.Response.Data[i].ItemTitle));
            }
         },
        fail: function(err) { console.log("error"); }
    });
})
//ここからが今回追加したコード
$p.on('change', 'ClassA', function () {
    const trgID = $("#Results_ClassA").val();
    
    $p.apiGet({
        id: trgID,
        data: {
            'ApiKey': '',
            'Offset': 0,
        }, 
        done: function(data) { 
	    const price = data.Response.Data[0].NumHash.NumA;
            $p.set($('#Results_NumA'), price);
         },
        fail: function(err) { console.log("error"); }
    });
})

5.定義したfunctionを利用する

上のコードでは $p.on(‘change’, ‘ClassB’, function () { }) として、function部分を直接書いています。関数を名前を付けて定義して、関数を呼び出す形でも同じことが実現できます。
以下コードではfunctionに続けて記述していた部分をsetList、setPriceという関数を定義し、ClassB、ClassAの値が変わったときに呼び出すようにしています。
関数に名前を付けて定義するのは、
function 関数名 ( 引数 ) { 実行するコード }
と書きます。

const siteID = 256;

$p.on('change', 'ClassB', setList);
$p.on('change', 'ClassA', setPrice) ;

function setList(){
    const selectVal = $("#Results_ClassB").val();
    $p.set($('#Results_NumA'), "")

    $p.apiGet({
        id: siteID,
        data: {
            'ApiKey': '',
            'Offset': 0,
            'View': {
                'ColumnFilterHash': {
                    'ClassA': '["' + selectVal + '"]'
                }
            }
        }, 
        done: function(data) { 
            $("#Results_ClassA").children().remove();
            $('#Results_ClassA').append($('<option>').val("").text(""));
            for (let i = 0; i < data.Response.Data.length; i++){
                $('#Results_ClassA').append($('<option>').val(data.Response.Data[i].ResultId).text(data.Response.Data[i].ItemTitle));
            }
         },
        fail: function(err) { console.log("error"); }
    });
}

function setPrice() {
    const trgID = $("#Results_ClassA").val();
    $p.set($('#Results_NumA'), "");
    
    $p.apiGet({
        id: trgID,
        data: {
            'ApiKey': '',
            'Offset': 0,
        }, 
        done: function(data) { 
            const price = data.Response.Data[0].NumHash.NumA;
            $p.set($('#Results_NumA'), price);
         },
        fail: function(err) { 
            console.log("error");
            $p.set($('#Results_NumA'), "");
        }
    });
}

分類Aの値を一度セットして、再度変更しようとしたときに一瞬数値Aの単価が残ってしまうので、
$p.set($(‘#Results_NumA’), “”);
と、数値Aを空欄にするコードも追加しています。データ取得に失敗した場合も数値Aを空欄にするコードも追加しています。(数値Aは「Null許容」にしています)

どちらがいいかは好みでしょうね。私は関数を定義するほうが好きです。

function の方が呼び出しするほう($p.on)より下でいいのか?とちょっと不思議だったのですが、javaScriptは「巻き上げ」というのがあるらしく、functionが後ろに書かれていても、後ろまで探しに行ってくれるみたいです。(言い方は正しくないのかもしれませんが、そんなイメージ)
こちらのサイトで勉強させていただきました。
https://magazine.techacademy.jp/magazine/35133

関数を変数に代入することもできるようです。その場合は実行するコードより上に書かないとダメだそうです。
https://magazine.techacademy.jp/magazine/35133

const siteID = 256;

const setList = function (){
    //関数の中は上のコードと同じなので割愛
}

const setPrice = function() {
    //関数の中は上のコードと同じなので割愛
}

$p.on('change', 'ClassB', setList);
$p.on('change', 'ClassA', setPrice);

コメント

タイトルとURLをコピーしました