0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

GASでWebアプリ「映画鑑賞記録」を作る⑪ / Vue.js用のセレクトボックス「vue-select」を使用する

Last updated at Posted at 2021-05-14

今回やること

 ダイアログボックスの「映画館」の入力項目を、プルダウンリストに変更します。
 プルダウンリストに表示するデータは、スプレッドシートの[映画館]シートを使用します。
 また、プルダウンリストについては、Vue.js に対応した高機能な部品(「vue-select」)がありましたので、これを使用します。
  ◆参考サイト 高機能なセレクトボックス「vue-select」の使い方

 「鑑賞種別」については、[映画館]シートのデータを利用して自動更新する様に変更します。
 これに伴って、ダイアログボックスの「鑑賞種別」を削除します。

「vue-select」の導入

Index.html

 ライブラリをCDNで取得します。

  <!-- vue-select -->
  <script src="https://unpkg.com/vue-select@latest"></script> 
  <link rel="stylesheet" href="https://unpkg.com/vue-select@latest/dist/vue-select.css">

javascript.html

 ライブラリを呼び出します。

<script>
  const vueSelect = VueSelect.VueSelect;
    
</script>

Vuejs.html

 子コンポーネント(ダイアログボックス)のcomponentsに、'vue-select': vueSelectを追加します。

Vue.component("modal", {
    
  components: {
    'vuejs-datepicker': vuejsDatepicker,
    'vue-select': vueSelect
  }
});

ダイアログボックスの「映画館」と「鑑賞種別」を変更

modalScript.html

 「映画館」の<input>タグを削除して、<vue-select>タグを追加します。
 プルダウンリストに表示するデータを、:options="vueselect.options"で参照します。(下記の Vuejs.html を参照)
 プルダウンリストで選択された値を、v-model="cond.theaterName"で格納します。(初期値の設定も同様)

 「鑑賞種別」(全体、<div class="form-group">タグから全て)を削除します。

  <transition name="modal"><div class="form-group">
                <label for="theater-name" class="col-form-label">映画館:</label>
                <!-- <input type="text" class="form-control" id="theater-name" v-model="cond.theaterName"> -->
                <vue-select id="theater-name" :options="vueselect.options" v-model="cond.theaterName"></vue-select>
              </div><!-- <div class="form-group">
              <div class="input-group">
                <label for="viewing-type" class="col-form-label">鑑賞種別:</label>
                <input type="text" class="form-control" id="viewing-type" v-model="cond.viewingType">
              </div>
              </div> -->
            </form>
          </div></transition>
</script>

Vuejs.html

 プルダウンリストの映画館名をセットする変数(options: [])を、子コンポーネント(ダイアログボックス)と親コンポーネントに追加します。
 options: []には、リストに表示する文字列を1次配列としてセットします。
 → ex.['川越スカラ座', '池袋シネマ・ロサ', '深谷シネマ',…]

Vue.component("modal", {
  template: "#modal-template",
  props: {
      
    vueselect: {
      options: [] 
    }
  },
    
});

var app = new Vue({
  el: '#app',
  data: {
      
    vueselect: {
      options: []
    }, 
    
});

Index.html

 Vuejs.html で追加した変数(options: [])を連携する為に、<modal>タグにv-bind:vueselect="vueselect"を追加します。

    <modal v-if="showModal" v-on:close-modal="doHideModal" v-on:add-data="doAddData" v-bind:message="message" v-bind:subject="subject" v-bind:cond="cond" v-bind:datepicker="datepicker" v-bind:vueselect="vueselect">
      <h3 slot="header">custom header {{ processingType }}</h3>
    </modal>

プログラム(処理)の変更

ViewingRecord.gas

 先ず、サーバ側の処理を変更します。

  • getTheaters(year) ※追加
    • 処理概要:[映画館]シート(スプレッドシート)から「映画館名」と「鑑賞種別」を取得する。
    • 引数  :yeat: 年を示す文字列。ex.'2021年'[映画館]シートは、年毎にファイルが分かれ
           ている。
    • 返値  :「映画館名」と「鑑賞種別」を2次配列で返す。
function getTheaters(year) {
  var fileId = getFileIdFromYearSettings(year);
  var sheet = SpreadsheetApp.openById(fileId).getSheetByName('映画館');
  var lastRow = sheet.getLastRow();
  var theaters = sheet.getRange(3, 3, (lastRow - 2), 2).getValues();  //[映画館]シートの「映画館名」列 と「鑑賞種別」列 を取得。

  return theaters;
}
  • getViewingType(theaterName, year) ※追加
    • 処理概要:「映画館名」から[映画館]シートを検索して該当する「鑑賞種別」を取得する。     
    • 引数  :theaterName:「映画館名」。
           year: 年を示す文字列。ex.'2021年'[映画館]シートは、年毎にファイルが分かれ
           ている。
    • 返値  :「鑑賞種別」。1:映画館, 2:DVD, 3:配信, 4:テレビ, 9:その他
function getViewingType(theaterName, year) {
  var theaters = getTheaters(year);

  for(var i = 0; i < theaters.length; i++) {
    if(theaters[i][0] === theaterName) {
      return theaters[i][1];
    }
  }

  return false;
}

 addData()の[鑑賞履歴]シートにデータをセットする部分を修正します。
 「鑑賞種別」の値は、従来ダイアログボックスからの入力で設定していましたが、getViewingType()で取得した値を設定する様に変更します。

function addData(cond) {
    
  //sheet.getRange(targetRow, 2, 1, 6).setValues([[cond.id, cond.viewingDate, cond.movieName, cond.firstLook, cond.viewingType, cond.theaterName]]);
  var viewingType = getViewingType(cond.theaterName, cond.year);
  sheet.getRange(targetRow, 2, 1, 6).setValues([[cond.id, cond.viewingDate, cond.movieName, cond.firstLook, viewingType, cond.theaterName]]);
}

javascript.html

 クライアント側の処理を変更します。

  • getTheaters(year) ※追加
    • 処理概要:サーバ側のgetTheaters()の呼出し。
           取得したデータ(「映画館名」「鑑賞種別」)から、プルダウンリスト用の配列を作成
           する。
    • 引数  :year: 年を示す文字列。ex.'2021年'[映画館]シートは、年毎にファイルが分かれ
           ている。
  function getTheaters(year) {
    google.script.run.withSuccessHandler(
      function(v, element) {
        var theaters = [];
        for(let theater of v) {
          theaters.push(theater[0]);
        }
        app.vueselect.options = theaters;
      })
      .withFailureHandler(
        function(msg, element) {
          showError(msg);
        })
      .withUserObject(this)
      .getTheaters(year);
  }

Vuejs.html

 Vue.js の処理(クライアント側の処理)も変更します。
 mounted:(インスタンスがマウントされた後の処理)とmethods:doChangeYear:(どちらも処理の一番最後)に、getTheaters()javascript.html )の呼出しを追加します。

var app = new Vue({
  el: '#app',
    
  mounted: function() {
      
    getTheaters(this.selectedYear);
  },
  methods: {
      
    doChangeYear: function() {
        
      getTheaters(this.selectedYear);
    }
  }
});

結果

 〔記録追加〕ボタンをクリックすると、ダイアログボックスが表示されます。
 「映画館」がプルダウンリストに変更され「鑑賞種別」が削除されています。
vue-select1.png
 「映画館」を選択すると、映画館名のリストが表示されます。
vue-select2.png
 「映画館」に新宿と入力すると、リストの表示が絞り込まれます。
vue-select3.png

 一覧表の行をクリックする(更新)と、既に入力していた「映画館名」が正しく表示されます。
vue-select4.png

◆前の記事 GASでWebアプリ「映画鑑賞記録」を作る⑩
◆次の記事 GASでWebアプリ「映画鑑賞記録」を作る⑫

◆索引 GASでWebアプリ「映画鑑賞記録」を作る《索引》

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?