スポンサーリンク

【pleasanter】$p.apiGetをやってみた~複数データを取得してプルダウンリストを作成する

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

2023.8.26.3(2)の記載を修正しています。

前回殴り書きで$p.apiGetについて手探りでもじょもじょやってみたことを書きました。
【pleasanter】$p.apiGetについての覚書

単一データの取得も後日やったこちらをどうぞ
【pleasanter】$p.apiGetをやってみた~単一レコードの取得

今回はさらに、もじょもじょやってみようと思います。

参考にさせていただいたサイトは前回と同じ下の3つです。

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

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

1.そもそも$p.apiGetとは

そもそも$p.apiGetってなんだ?というと、$p.apiGetはプリザンターの方で用意してくれている、値をゲットするためのメソッドです。

AjaxのPOSTリクエストによる値の取得が行えるスクリプト機能になります。 レコードの情報などを取得したいときに使用してください。

引用元;公式マニュアル https://pleasanter.org/manual/script-api-get

よくわからないけど、自身のテーブルや、ほかのテーブルからなにか持ってきたいときに使えるらしい!という感じでしょう。

apiってなに?Ajaxってなに?となると、自分、ふんわりとしか理解してなくて、説明できないのでネットで調べてみてくださいっ!
わたしはわからない用語はいつもわわわ辞典さんに教えてもらっています。ちょっとわかったような気になれるのでおすすめです!
https://wa3.i-3-i.info/word12428.html
https://wa3.i-3-i.info/word12672.html

(2)$p.apiGet の基本

公式マニュアルより

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

プリザンターさんが親切に用意してくれたメソッドなので、わからんけど、idのところにはゲットしたサイトのID、dataの後にはとってきたいデータの条件、daneの後にはデータ取得に成功したらやりたいこと、等()内のところに自分のしたいことを当てはめて書いていけばいいのだろうと。やってみます。

2.$p.apiGet 理解するためにすこしずつやってみる

(1)使うサンプルサイトの仕様

まず、ここで使っているサイトはこんな感じですよ、というのを簡単に書いておきます。

元テーブル。ここからデータを取り出したい、というテーブル。ここではサイトIDは256です。
分類Aでは選択肢100文具、200食品と2つの区分から選択します。
タイトルは分類Aの「商品区分(文具/食品)」と説明Aの「商品名称」を連結してタイトルとしています。タイトルは重複しないものとしています。

つぎに、ここに持ってきたいよ、というテーブル。子テーブルということにします。
商品区分(分類B)には元データテーブルと同じように選択肢を100文具、200食品とし、選択するようにしています。

商品区分

これからチマチマやっていきますが、最終的にやりたいことは、
持ってきたい方のテーブルで「商品区分」を選択すると(たとえば文具)、「商品」の欄で文具の商品がプルダウンリストで選択できるようになる!ということをやりたいと思っています。

(2)まずデータ取得ができるか

ちょっとずつそろーりそろーりとやってみる戦法で。
とにかく結果だけ知りたいという場合は読み飛ばしてください。

以下のコードを、子テーブルの方のスクリプトに記述します。
id256のサイトからデータを取得します。データの取得が成功したらdoneの処理に進みます。
doneに進むとそこに書いてある function(関数)を実行します。(サイトIDは適宜変更してください)
function(data)と書いてあるのは関数(function)にGETしてきたdataを渡す、ということです。
dataを引数にして{}内の処理を実行します。
{}内の console.log(data) はコンソールにdataの内容を出力する、ということです。

つまり、とってきたデータを試しにコンソールに書き出ししてみて中身を見てみよう、とそれだけのことです。

failにはデータ取得に失敗したときの処理を書いておきます。errorとコンソールに出力する、という処理を書いています。

$p.apiGet({
        id: 256,
        done: function(data) { console.log(data); },
        fail: function(err) { console.log("error"); }
    });

スクリプトの入れ方は
子テーブルを開いた状態で、テーブルの管理→スクリプトタブで「新規作成」をクリック。
上記のコードをコピーしたものをスクリプトに貼り付けします。(サイトIDは適宜変更してください)

タイトルはなんでもいいのでなにかしら入力します。

「出力先」は「全て」のチェックを外し、「新規作成」「編集」にチェックを入れます。
そうすることで、新規作成をクリックして新規文書を開いたとき、または作成済文書をエディタ画面で開いたときに、コードが実行されることになります。

「変更」ボタンをクリックして、スクリプト入力画面を閉じ、「更新」ボタンで変更を反映させます。

では、一覧画面に戻って、グーグルの開発者ツールを開いておきます。(GoogleChromeでやっている前提で書いてます。すみません)
右クリックで「検証」をクリックするか、Google Chromeの設定ボタンから、その他ツール→デベロッパーツールを選択します。

さて、そうしたら「新規作成」をクリックして新規入力画面にしましょう。

開発者ツールの「Console」を見てみます。

元データテーブルのデータは8個なので、すべてのデータがとれたみたいですね!やったーー!

(3)データの絞り込みをしてみる

次に、もう一歩踏み込んで、データの絞り込みをしてみたいと思います。

元テーブルの商品区分(分類A)が「文具」のデータだけ取得したいと思います。

コードを書き換えます。

$p.apiGet({
    id: 256,
    data: {
        'ApiKey': '',
        'Offset': 0,
        'View': {
            'ColumnFilterHash': {
                'ClassA': '[\"100\"]'
            }
        }
    }, 
    done: function(data) { 
        console.log(data);
        console.log("id:" + data.Response.Data[0].ResultId);
        console.log("タイトル:" + data.Response.Data[0].ItemTitle);
        console.log("商品区分:" + data.Response.Data[0].ClassHash.ClassA);
        console.log("商品名:" + data.Response.Data[0].DescriptionHash.DescriptionA);
        console.log("単価:" + data.Response.Data[0].NumHash.NumA);
     },
    fail: function(err) { console.log("error"); }
});

コードの説明です。

先ほどはなにも指定せず全部のデータを取得しました。先ほどは指定しなかった「data」の部分に絞り込み条件を書いていきます。

data: {
        'ApiKey': '',
        'Offset': 0,
        'View': {
            'ColumnFilterHash': {
                'ClassA': '[\"100\"]'
            }
        }
    }, 

data: の後の{}内に 〇〇:×× という形で 〇〇は××ね と指定していきます。

‘ApiKey’: ”
ApiKeyは指定しなくても良さそうなので空文字を指定しています。

‘Offset’: 0,
何のことやらわからないのでコピペしました。

‘View’: { }の中に条件を書いていきます。
‘View’の中にさらに’ColumnFilterHash’: { }で項目の絞り込み条件を書きます。

条件は ’ClassA’: ‘[\”100\”]’ としました。
分類Aが100、つまり「商品区分」が「文具」を指定しています。
元テーブルで分類Aの選択肢は 値,表示名 の形で指定してあるので ‘[\”文具\”]’と表示名で指定するのではなく値の方で'[\”100\”]’指定します。
(100,文具/200,食品の選択肢としている)
ちなにみ\はエスケープ文字です(多分)そのあたりは前回の記事でゴニョゴニョ書いています。
このような条件の指定の仕方は公式マニュアルにいろいろ例が書いてあります。
https://pleasanter.org/manual/api-view

データ取得に成功した後に行う done の後の記述も変えています。

まずdata全体を出力し、そのあとで配列のDataのインデックス0の内容を出力しています。

出力したいモノの書き方がですね。data.Response.Data・・・となんだか長いですが、コンソールに出力したデータと見比べてみると、数珠つなぎにどんどん下っていく感じ。。。って言ってることわかりますかね。。。?

大元がdataで、次はResponseで、次がDataの配列でインデックスを指定して、個々の配列の中身のClassHashの中のClassA・・・とか。
data.Response.Data[0].Classhash.ClassA ってピリオドでつないで出したいところまでたどっていく感じ。

では!スクリプトを書き換えて、新規作成して入力画面にして、コンソールの内容を見てみましょう。

でました!文具のデータを取得したのでデータが5個。合ってる!

(4)ループでひとつづつ出してみる

前項でData配列から一つだけ出力しましたが、今度は配列をループして、ひとつずつコンソールに出力してみようと思います。
javaScriptのループにはいろいろあるようですが、一番簡単そうなfor文でやってみようと思います。
for文についての詳しい説明は割愛します。
こちらのサイト等わかりやすかったです。
https://www.javadrive.jp/javascript/for/index2.html
javaScript ループ や javaScript for文 などで検索すると色々出てきます。

コードを書き換えます。

$p.apiGet({
    id: 256,
    data: {
        'ApiKey': '',
        'Offset': 0,
        'View': {
            'ColumnFilterHash': {
                'ClassA': '[\"100\"]'
            }
        }
    }, 
    done: function(data) { 
        for (let i = 0; i < data.Response.Data.length; i++){
            console.log(data.Response.Data[i].ResultId);
            console.log(data.Response.Data[i].ItemTitle);
        }
     },
    fail: function(err) { console.log("error"); }
});

書き換えたのはdoneのfounction内の部分だけです。

for (let i = 0; i < data.Response.Data.length; i++){
    console.log(data.Response.Data[i].ResultId);
    console.log(data.Response.Data[i].ItemTitle);
}

forでループします。()内にループの条件を書いています。

let i = 0 で、変数iを宣言と同時に初期値の0を入れています。

i < data.Response.Data.length はループを続ける条件の部分です。data.Response.Dataは配列です。lengthで配列の個数を取得します。つまりiが配列の要素数より小さい間はループを続け、iが配列の要素数以上になったらループをやめます。

i++ はループごとに変数iを1ずつ増やす、ということです。

ループ内の処理で、ループするごとに取得したデータのidとタイトルを出力するようにしています。

さて、スクリプトを書き換えて「新規作成」して、コンソールを見てみましょう。

出ましたね!

(5)子テーブルの分類Bの値が変わったらデータを取得する $p.on change

さて、いよいよ。。。

子テーブルで新規作成し、商品区分(分類B)を選択したら、選択した商品区分に応じたデータを取得する、ということをやってみたいと思います。

そこで使えるのがプリザンターのメソッド $p.on です。
公式マニュアルはこちら
https://pleasanter.org/manual/script-on

公式マニュアルよりコードの記述例

$p.on('change', 'ClassA', function () {
    [任意の処理]
})

なんとなく雰囲気でわかる感じ。
ClassAが変わったら(change)functionに書いてあることを実行するよ、ということでしょう。

公式マニュアルにはもっと難しいことが書いてありますが、雰囲気で、理解するにとどめる。。

コードを書き換えます。分類Bが変わったら、分類Bで指定した値でデータを取得して、コンソールに出力するよ、という内容に書き換えます。ついでに、サイト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) { 
            console.log(selectVal);
            for (let i = 0; i < data.Response.Data.length; i++){
                console.log(data.Response.Data[i].ResultId);
                console.log(data.Response.Data[i].ItemTitle);
            }
         },
        fail: function(err) { console.log("error"); }
    });

})

const siteID = 256;
siteID に元データテーブルのid256を代入しています。

$p.on(‘change’, ‘ClassB’, function () { }
分類B(商品区分)が変わったらfunctionを実行するよ、ということです。
functionの後ろの{}内に前項でやったコードをコピーして貼り付けし、内容をちょこっと修正します。

const selectVal = $(“#Results_ClassB”).val();
分類Bの値をselectVal に代入しています。
$(“#Results_ClassB”).val() はjQueryの書き方で、$(“#Results_ClassB”)で idがResults_ClassBを取得し、val() でその値を取得しています。

$p.apiGet の後ろの部分はほとんど変えていませんが、id の部分を256から siteID に変更しています。

ColumnFilterHash の ClassA の条件指定を取得した変数で指定するように書き換えています。
‘[“‘ + selectVal + ‘”]’
シングルクォーテーションとダブルクォーテーションの使い方がややこしいですが、たぶんシングルクォーテーションで挟んだ部分を文字列認識してね、と。つまりシングルクォーテーションで囲んだ [“ は文字列ですよとパソコンに訴えているのだと思います。
ちなみに ‘[“‘ + selectVal + ‘”]’ も ‘[\”100\”]’ も、コンソールに出力してみると [“100”] となっていました。

for文のループに入る前に、selectValに何が入っているのか確かめたかったのでselectValをコンソール出力するコードも追加しています。

スクリプトを書き換えて、新規作成します。
商品区分を選択して、コンソールを見てみましょう。
できましたね!

3.取得したデータでプルダウンリストを作成する

さて、ちょこまかやって、$p.onと$p.apiGetがなんとなく使えるようになったような気がします。

で、次に、分類B「商品区分」を選択すると、分類A「商品」で元テーブルのタイトルをプルダウンで選択できるようにしたいと思います。
たとえば子テーブルで「商品区分」で「食品」を選択すると、「商品」欄に元テーブルで商品区分が「食品」の商品がプルダウンリストで選択できるようになる、ということです。

(1)プルダウンリストの作成

プルダウンリストの作成方法はこちらのサイトを参考にさせていただきました。
https://imageinformationsystem.hatenablog.com/entry/2018/10/26/095113
https://imageinformationsystem.hatenablog.com/entry/2018/05/21/114408

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"); }
    });
})

1行ずつ解説していきます。

const siteID = 256;
変数siteIdに元テーブルのid256を代入しています。

$p.on(‘change’, ‘ClassB’, function () {・・・
分類Bが変わったら、functionに書いてある処理を実行するよ、ということです。

const selectVal = $(“#Results_ClassB”).val();
分類B(商品区分)の値をselectValに代入しています。

$p.apiGet({ ・・・
で元テーブルから分類Aの値=子テーブル分類Bで選択した値のデータを取得します。

以下、doneの中の処理では分類A(商品)に取得したデータからプルダウンリストを作成しています。

$(“#Results_ClassA”).children().remove();
分類Aの下のhtml要素をいったんクリアしています。

$(‘#Results_ClassA’).append($(‘<option>’).val(“”).text(“”));
appendでプルダウンリストの中身を作成します。
val(値)、text(表示されるテキスト)どちらも空のプルダウンリストをはじめに追加します。

$(‘#Results_ClassA’).append($(‘<option>’).val(data.Response.Data[i].ResultId).text(data.Response.Data[i].ItemTitle));
長くなってしまいました。for文の中で取得したデータのidとタイトルをそれぞれプルダウンの値とテキストに追加しています。

(2)プルダウンリストを設定する分類項目に選択肢を設定しておく

つっかかりポイント。
上記コードでプルダウンは作成されてるっぽいのに、「商品」のところが「商品区分」みたいにプルダウンにならない???
なんで?と思ったところ、インプットボックスがドロップダウン形式になっているか、テキスト入力形式になっているかの違いらしい。
入力画面でドロップダウン形式になっているものはへのさかさまみたいなやつが右端についているが、単なる入力ボックスはそれがついていない。その形式の違いですね。

分類Aに、サイトIDを設定しておくことで解決できました。
(2023.8.26.記載を修正。選択肢一覧に適当な選択肢、999,未設定と設定しておくと書いていましたが、それではいったんプルダウンが作成できても、「作成」ボタンを押したときに、?になってしまうことが判明)

(3)プルダウンリストができた

エディタで分類Aに選択肢を設定して、再度やってみます。
商品区分で「食品」を選択すると・・・

できたっ!

きょうはここまで。

コメント

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