WEBアプリでスプレッドシートのデータを表示とカスタマイズについて

前提

この記事を参考にし、スプレッドシートのでまとめているデータをWEBアプリにてデータ表示を実装しています。
下記2点について教えていただきたいです。

実現したいこと

①右側のフィルタのフリーテキスト以外に、プルダウンでの選択したい
例)「性別」カラムにあらかじめ「男」「女」をプルダウンで表示 など

②右側の一覧表示に出ている項目=フィルタ項目となっているが、フィルタを限定したい
例)「生年月日」は右の一覧には表示するが、左のフィルタには不要 など

該当のソースコード

const ss = SpreadsheetApp.getActiveSpreadsheet(); function doGet() { const htmlTemplate = HtmlService.createTemplateFromFile('index'); const title = ss.getName(); htmlTemplate.title = title; return htmlTemplate.evaluate().setTitle(title); } function getSheetData() { const sh = ss.getSheetByName("data"); const response = JSON.stringify(sh.getDataRange().getValues()); return response }
<!DOCTYPE html> <html style="overflow-y:hidden"> <head> <base target="_top"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css"> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <style> ::-webkit-scrollbar { background: transparent; height: 10px; width: 8px; } ::-webkit-scrollbar-thumb { border: none; background: #bbb; -webkit-border-radius: 8px; border-radius: 8px; min-height: 40px; } thead th { position: -webkit-sticky; position: sticky; top: -1px; background-color: #ddd; } .btn { position: fixed; width: 50px; height: 50px; color: white; border-radius: 50px; display: flex; justify-content: center; align-items: center; opacity: 0.4; box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3); transition: 200ms; user-select: none; } .btn:hover { opacity: 0.9; } .btn:active { opacity: 1; } </style> </head> <body> <div id="app"> <div style="display: flex;"> <div style=" width: 300px; height: 100vh; background-color: #fafafa; padding: 0 30px; overflow: auto; "> <h1 class="title is-4" style="margin-top: 50px;"> <span class="material-icons">filter_list</span> フィルタ </h1> <template v-for="(key, index) in keys"> <div style="margin-bottom: 1em;"> <label class="label is-small">{{ key }}</label> <input v-model="conditions[index]" type="text" class="input is-small"> </div> </template> <div @click="clearConditions()" class="btn" style="bottom: 30px; left: 220px; background-color: #e85a5a;" > <span class="material-icons">clear</span> </div> </div> <div style=" max-width: calc(100% - 300px); height: 100vh; padding: 0 50px; overflow: auto; "> <h1 class="title is-4" style="margin-top: 50px;"> <span class="material-icons">description</span> <?= title ?> </h1> <table class="table is-striped is-hoverable" style="white-space: nowrap; position: relative;"> <thead> <tr> <th v-for="key in keys">{{ key }}</th> </tr> </thead> <tbody> <template v-for="record in records"> <tr v-if="checkCondition(record)"> <td v-for="item in record">{{ item }}</td> </tr> </template> </tbody> </table> <div @click="downloadCSV()" class="btn" style="bottom: 30px; right: 30px; background-color: #3a93e8;" > <span class="material-icons">file_download</span> </div> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script> <script> var app = new Vue({ el: '#app', data: { keys: [], records: [], conditions: [] }, mounted: function(){ google.script.run.withSuccessHandler(function(text) { const response = JSON.parse(text) app.keys = response[0]; app.records = response.slice(1); app.records.splice(); }).getSheetData(); }, methods: { checkCondition: function(record){ for (let i = 0; i < this.keys.length; i++){ if ( this.conditions[i] && !record[i].includes(this.conditions[i]) ) return false; } return true; }, clearConditions: function(){ this.conditions.splice(0); }, downloadCSV: function(){ const filename = "data.csv"; let data = '\"' + this.keys.join('\",\"') + '\"\r\n'; for (const record of this.records){ if ( this.checkCondition(record) ){ data += '\"' + record.join('\",\"') + '\"\r\n'; } } const bom = new Uint8Array([0xef, 0xbb, 0xbf]); const blob = new Blob([bom, data], { type: "text/csv" }); const url = (window.URL || window.webkitURL).createObjectURL(blob); const download = document.createElement("a"); download.href = url; download.download = filename; download.click(); (window.URL || window.webkitURL).revokeObjectURL(url); } } }) </script> </body> </html>

以上、お手数をおかけしますが、よろしくお願い申し上げます。

コメントを投稿

0 コメント