Segmentの中にあるwidgetにデータを渡し表示させる方法

#目次
1. はじめに
2. 実装方法
3. まとめ
4. 参考

#はじめに
多くのデータをリストにして表示させる、という場面はアプリを作っていて多くあると思います。
そのリストも文字だけでなくアイコンで表示したり、データによってSkinを変更させたい！などもあるでしょう。
この記事はデータをKony WidgetのSegmentに渡し表示させる方法について書いていきます。

#実装方法
######1. 画面作成
例として以下のような連絡帳アプリを作ってみましょう！

1. 連絡先を一覧表示する
1. データの有無によってアイコンの色を変化させる
1. アイコンをクリックする
    1. データがある場合は、メールアイコンをタップするとメールアドレスが、電話アイコンをタップすると電話番号が表示される
    1. データがない場合は、メール・電話アイコンボタンを押しても何も起こらない




最初にリストにして表示させるSegmentを配置しましょう。
まずTemplateに`segRowAddress`を作成します。
![segRowAddress.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/f9ed02db-66b1-0683-1a2f-e1579349d263.png)
今回アイコンにはDefault LibraryにあるLabelを使用します。
このDefault Libraryを使用する時は、
使用したいアイコンをドラックアンドドロップしてフォームに設置してください。
![使用アイコン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/cf90b53d-36ab-27aa-5971-cde414232368.png)

電話のアイコン(lblCall)をクリックできるようにしたいため、同位置にボタン(btnCall)も配置します。
メールのアイコンも同様に配置します。
この時Skinは薄いグレー(sknLblIconGray)にしていますが、連絡先が登録されている場合色付きのアイコンにさせたいのでそれぞれのSkinを作成します。

まず連絡先が登録されている時のSkinを作成します。
SkinタブのLabelからNew Skin > Skinを選択、Skin名を`sknLblIconGreen`にします。
Font Colorを`#3e493e`に設定します。
Font Familyは`FontAwesome`に設定してください。他のFontに設定すると文字化けしてしまう可能性があります。
![createSkin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/0cb4ddca-4e4d-426b-d9c6-f860135adfcc.png)

次に登録されていない時のSkinを作成します。
同様の手順で作成し、Skin名を`sknLblIconGray`に命名、Font Colorを`#d9d9d9`に設定します。
こちらのFont Familyも`FontAwesome`に設定してください。
Skinには[こちらの記事](https://qiita.com/Kony_Team/items/2239d4bcb1d4bace8da3#3skin%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3)を参考にしてください！

WidgetからSegmentを配置しpropertiesのRow Templateから作成した`segRowAddress`を選択します。
![frmAddressList.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/1b472a38-a4a1-5b17-48d7-90d56d30133d.png)

Templateに作成しておくと、他にSegmentを使う時に毎回widgetを配置する必要はなくなるのでオススメです
Segmentについては[こちらの記事](https://qiita.com/Kony_Team/items/edd2f5daf74c88aa0634)を参考にしてみてください！

######2. マッピングをする

関数`onPreShow`の中に以下のコードを書きます。

```frmAddressListController1.js
  onPreShow : function(){
    // ウィジェットとデータのマッピングを行う
    this.view.segAddressList.widgetDataMap = {
      lblName : "name",
      lblCall : "telNum",
      lblMail : "mail",
      btnCall : "btnCall",
      btnMail : "btnMail"
    }; 
```

`widgetDataMap`ではSegmentのwidgetとそれに紐づくデータのマッピングを行います。

######3. データの用意
次にSegmentにセットするデータを準備します。
APIなどのデータでも良いですが、今回はデータを作ります。
データなしの場合は空文字とし、5人分の連絡先を作成します。
関数`onPreShow`の外に書いてください。

```frmAddressListController2.js
define({
  // 連絡帳リスト
  address : [
    {
      "name" : "田中　花子",
      "telNum" : "090-1234-5678",
      "mail" : ""
    },
    {
      "name" : "佐藤　太郎",
      "telNum" : "080-2222-5555",
      "mail" : "sample@test.co.jp"
    },
    {
      "name" : "鈴木　美咲",
      "telNum" : "",
      "mail" : "misaki@eiyuu.co.jp"
    },
    {
      "name" : "伊藤　一",
      "telNum" : "090-1122-3344",
      "mail" : "wan@dokodoko.co.jp"
    },
    {
      "name" : "山田　五郎",
      "telNum" : "",
      "mail" : "test@zofban.co.jp"
    }
  ],
```

######4. アイコンクリック処理
電話アイコン・メールアイコンをクリックされた時、ポップアップにそれぞれの登録された連絡先が表示される処理を追加します。

```frmAddressListController3.js
    // 電話アイコンをクリック
    const onClickCall = function(call){
      kony.ui.Alert(
        {
          message : call,
          alertType : constants.ALERT_TYPE_INFO
        },{}
      );
    };

    // メールアイコンをクリック
    const onClickMail = function(mail){
      kony.ui.Alert(
        {
          message : mail,
          alertType : constants.ALERT_TYPE_INFO
        },{}
      );
    };
```
`alertType`は表示されるポップアップのタイプを指定できます。それぞれのタイプは3つあります。
今回は`ALERT_TYPE_INFO`を使用して表示させます。

| alertType | 説明 | 表示されるポップアップ |
| ----- | ----- | ----- |
| ALERT_TYPE_INFO | ユーザーに情報を表示するために使用されます。<br>このタイプはデフォルトに設定されています。<br>ALERT_TYPE_CONFIRMATIONと異なりボタンはOKのみです。 | ![info.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/e489cdba-106c-b22d-e005-45b9495c27c6.png) |
| ALERT_TYPE_CONFIRMATION | ユーザーに何かを確認または承認してもらいたい場合に使用されます。<br>YESボタンとNOボタンがあり、ユーザーはYESまたはNOボタンをクリックして続行または終了する必要があります。<br>(例)個人情報登録画面の確認時 | ![confirm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/88d24d06-c8e2-bdaa-3a74-1d28a2214098.png) |
| ALERT_TYPE_ERROR | ユーザーが誤った値を入力したときに表示するために使用されます。<br>ALERT_TYPE_CONFIRMATIONと異なりボタンはOKのみです。<br>(例)ログイン画面のユーザー名またはパスワードを間違った時 | ![error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/df97aacd-ffd4-4a8a-8176-e80d1c0e80da.png)|

######5. アイコンの表示処理
アイコンのSkin処理(色付きorグレー)とボタンのクリック処理を書きます。

```frmAddressListController4.js
    var i = 0;
    while(i < this.address.length){
      if(this.address[i].telNum === ""){
        this.address[i].telNum = {skin : "sknLblIconGray"};
      } else {
        this.address[i].btnCall = {onClick : onClickCall.bind(this, this.address[i].telNum)};
        this.address[i].telNum = {skin : "sknLblIconGreen"};
      }

      if(this.address[i].mail === ""){
        this.address[i].mail = {skin : "sknLblIconGray"};
      } else {
        this.address[i].btnMail = {onClick : onClickMail.bind(this, this.address[i].mail)};
        this.address[i].mail = {skin : "sknLblIconGreen"};
      }
      i++;
    }
```
whileにすることで連絡先の数だけ繰り返します。
`bind()`は関数に対してthisや引数を指定することができるメソッドです。
今回は登録された電話番号とメールアドレスをポップアップに表示したいので、それぞれの値を引数として指定し`onClickCall`と`onClickMail`に渡します。

######6. Segmentにデータをセットする
最後に`setData()`でマッピングされたwidgetにそれぞれのデータをセットします。

```frmAddressListController5.js
    // データをSegmentにセットする
    this.view.segAddressList.setData(this.address);
  }
});
```

######7. Actionの紐づけ
次に関数(onPreShow)と画面(frmAddressList)をActionで紐付けます。
紐づけたいFormを選択しpropertiesのActionからpreShowのEditを選択します。
InvokeFunctionを選択しドロップダウンからonPreShowを選択すれば紐づけ完了です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/d50ff62b-5949-437a-e071-e1cb04425b40.png)

######8. ソースコード全体
```frmAddressListController.js
define({
  // 連絡帳リスト
  address : [
    {
      "name" : "田中　花子",
      "telNum" : "090-1234-5678",
      "mail" : ""
    },
    {
      "name" : "佐藤　太郎",
      "telNum" : "080-2222-5555",
      "mail" : "sample@test.co.jp"
    },
    {
      "name" : "鈴木　美咲",
      "telNum" : "",
      "mail" : "misaki@eiyuu.co.jp"
    },
    {
      "name" : "伊藤　一",
      "telNum" : "090-1122-3344",
      "mail" : "wan@dokodoko.co.jp"
    },
    {
      "name" : "山田　五郎",
      "telNum" : "",
      "mail" : "test@zofban.co.jp"
    }
  ],

  onPreShow : function(){
    // ウィジェットとデータのマッピングを行う
    this.view.segAddressList.widgetDataMap = {
      lblName : "name",
      lblCall : "telNum",
      lblMail : "mail",
      btnCall : "btnCall",
      btnMail : "btnMail"
    }; 

    // 電話アイコンをクリック
    const onClickCall = function(call){
      kony.ui.Alert(
        {
          message : call,
          alertType : constants.ALERT_TYPE_INFO
        },{}
      );
    };

    // メールアイコンをクリック
    const onClickMail = function(mail){
      kony.ui.Alert(
        {
          message : mail,
          alertType : constants.ALERT_TYPE_INFO
        },{}
      );
    };

    var i = 0;
    while(i < this.address.length){
      if(this.address[i].telNum === ""){
        this.address[i].telNum = {skin : "sknLblIconGray"};
      } else {
        this.address[i].btnCall = {onClick : onClickCall.bind(this, this.address[i].telNum)};
        this.address[i].telNum = {skin : "sknLblIconGreen"};
      }

      if(this.address[i].mail === ""){
        this.address[i].mail = {skin : "sknLblIconGray"};
      } else {
        this.address[i].btnMail = {onClick : onClickMail.bind(this, this.address[i].mail)};
        this.address[i].mail = {skin : "sknLblIconGreen"};
      }
      i++;
    }

    // データをSegmentにセットする
    this.view.segAddressList.setData(this.address);
  }
});
```


実際にどうなっているのか確認してみましょう
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/cPbofsRFhp">pic.twitter.com/cPbofsRFhp</a></p>&mdash; Kony (@Kony12763790) <a href="https://twitter.com/Kony12763790/status/1338755694854504448?ref_src=twsrc%5Etfw">December 15, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

5人分の連絡先がリスト表示され、登録されていない連絡先はアイコンがグレーになっていると思います。
またグレーのアイコンをクリックしてもポップアップは表示されません。

#まとめ
今回はデータによってSkinやActionを変更する方法をご紹介しました。
ぜひご活用ください！


#参考
Skinについて：
https://qiita.com/Kony_Team/items/2239d4bcb1d4bace8da3#3skin%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3
Segment Widgetについて：
https://qiita.com/Kony_Team/items/edd2f5daf74c88aa0634
widgetDataMapについて：
https://docs.kony.com/konyonpremises/Subsystems/Widget_User_Guide/Content/Segment_Basic_Properties.htm#widgetDa
Alertについて：
https://docs.kony.com/konylibrary/visualizer/viz_api_dev_guide/content/kony.ui_functions_alert.htm
setDataについて：
https://docs.kony.com/konyonpremises/Subsystems/Widget_User_Guide/Content/Segment_Methods.htm#setData