質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

950閲覧

GASで動的なボタンにvueを設定したい

yamadaman_q

総合スコア22

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2022/09/19 01:22

編集2022/09/19 02:26

前提

プログラミング初心者です。
現在GASを使ってスプレッドシートの値を取得した後、レコードごとに表示ボタンを設置して、そのボタンが押されたらモーダル画面を出してからデータを修正させるというアプリを作成しています。

動的に取得したデータのボタンにvueを設定してみたのですが、反応しません。

html += "<td class='col-xs-1 col-ms-1 col-md-1 col-lg-1'><button v-on:click='openModal'>test</button></td>"
document.getElementById("add").innerHTML = html;

自分なりに調べてみるとinnerHTMLで差し込んだものは純粋なHTMLテキストとして追加されるため、vueのインスタンスとして読み込まれないというのがなんとなく理解でき、手動でマウントすれば良いのかぁというところまではなんとなく理解できたんですが、実際にどのように記載していいのかわからず質問させて頂きました。

実現したいこと

・動的に埋め込んだボタンを押したらvueで指定した動作をするようにしたい

該当のソースコード

HTML

1<body> 2<label>【氏名】</label> 3   <select class="form-control" id="id3"></select> 4<div id="add"></div> 5<div id="overlay" v-show="showContent"> 6 <div id="content"> 7 <p>これがモーダルウィンドウです。</p> 8 <button v-on:click="closeModal">Close</button> 9 </div> 10 </div> 11</body>

javascript

1 2new Vue({ 3 el: '#app', 4 data: { 5 showContent: false 6 }, 7 methods:{ 8 openModal: function(){ 9 this.showContent = true 10 }, 11 closeModal: function(){ 12 this.showContent = false 13 } 14 } 15}) 16 17/*----------------------------------------------------------------------------------------------------------------------- 18 sendData : データテーブルの作成 19 -------------------------------------------------------------------------------------------------------------------------*/ 20 //セレクトボックスのリストを取得 21 function sendData(){ 22 23 var data1 = document.getElementById("id3").value; 24 25 google.script.run.withFailureHandler(fail).withSuccessHandler(data_table).search(data1); 26 27 } 28 29 //表示データ取得成功時の処理 30 function data_table(result) { 31 32 var json = JSON.parse(result); 33 var datalength = json.length; 34 35 36 //ラベルを入れる 37 var html2 = "<h4>test情報</h4>" 38 39 //tableをを設置する 40 var html2 = "<table class='table table-striped table-bordered table-condensed newline'>" 41 html2 += "<thead>" 42 html2 += "<tr style='font-size: 80%'>" 43 html2 += "<th class='col-xs-1 col-ms-1 col-md-1 col-lg-1'>名前</th>" 44 html2 += "<th class='col-xs-1 col-ms-1 col-md-1 col-lg-1'>ボタン</th>" 45 html2 += "</tr>" 46 html2 += "</thead>" 47 if(datalength > 1){ 48 html2 += "<tbody>" 49 for(var i=1; i<datalength; i++){ 50 html2 += "<tr>" 51 html2 += "<td class='col-xs-1 col-ms-1 col-md-1 col-lg-1'>"+json[i][1]+"</td>" 52 html2 += "<td class='col-xs-1 col-ms-1 col-md-1 col-lg-1'><button v-on:click='openModal'>test</button></td>" 53 html2 += "</tr>" 54 } 55 html2 += "</tbody>" 56 } 57 html2 += "</table>" 58 html2 += "</div>" 59 60 document.getElementById("add").innerHTML = html2; 61 62 } 63 64

gas

1/*-----新規データ---------------------------------------------------------------*/ 2function search(data){ 3 4 //60_施設管理DBシステム_施設マスタ 5 var ss = SpreadsheetApp.openById('***'); 6 var sh = ss.getSheetByName("施設DB"); 7 8 //全データ取得 9 var mst = sh.getDataRange().getValues(); 10 11 //フロントから取得した施設名でフィルタリング 12 var inv = mst.filter(function(e){return e[2] === data}); 13 14 15 Logger.log(inv); 16 return JSON.stringify(inv); 17}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2022/10/15 03:29 編集

data_table(result) の result を設定している部分が不明です。data_table 関数はどこから呼び出しているのでしょうか。(GAS側でしょうか?) data_table 関数を呼び出している部分も含めて、省略せず全部記載してください.
yamadaman_q

2022/09/19 02:28

ご連絡ありがとうございます。省略していた部分を記載致しました。
guest

回答1

0

ベストアンサー

変更を最小限にするならば、下記の方法で行うことは一応可能です。

① Vue を適用したい部分を、<div id="app"></div> で囲みます。

HTML

1<body> 2<div id="app"> 3<label>【氏名】</label> 4   <select class="form-control" id="id3"></select> 5<div id="add"></div> 6<div id="overlay" v-show="showContent"> 7 <div id="content"> 8 <p>これがモーダルウィンドウです。</p> 9 <button v-on:click="closeModal">Close</button> 10 </div> 11 </div> 12</div> 13</body>

② vue に変数を設定します。

js

1var vueapp = new Vue({ 2 el: '#app', 3.... 4})

③ 動的に構築する HTML 内のボタンのクリックイベントを、②で設定した変数(vueapp)経由で設定します。
このとき v-on:click ではなく onclick を使用します。

js

1 html2 += "<td class='col-xs-1 col-ms-1 col-md-1 col-lg-1'><button v-on:click='openModal'>test</button></td>" 2 ↓ 3 ↓ 4 ↓ 5 html2 += "<td class='col-xs-1 col-ms-1 col-md-1 col-lg-1'><button onclick='vueapp.openModal()'>test</button></td>"

Vueを活用する

上記でも一応期待通りの動作にはなると思いますが、せっかくVueを使用しているので、DOMを直接いじってTableを構築したり、Vueの外からボタンのクリックイベントをハンドリングしたりするのではなく、可能な限りVueの世界で完結させた方が良いとは思います。(table の構築や、プルダウンから選択した変数とボタンのイベント処理の連携等)

コード例を示す前に、下記のようなユースケースを考えます。
【スプレッドシート】

  • Webアプリに表示する元データ。C列に担当者氏名、B列に施設名が記入されている。

イメージ説明

【WEBアプリ】

  • セレクトボックスから担当者氏名を選んで「SEND」ボタンをクリックすると、

その担当者が担当する施設名の一覧が、スプレッドシートから読み込まれて、下部のテーブルに表示される。

  • 各行の「test」ボタンをクリックすると、モーダルウィンドウが表示される。

(※ 下記のコードは質問文と同じように簡便的に showContent の切り替えで代用しています)

イメージ説明

上記のユースケースでできる限り Vue を活用したコードはたとえば下記になります。
【コード】
index.html

html

1<!DOCTYPE html> 2<html> 3 4<head> 5 <base target="_top"> 6 <meta charset="utf-8"> 7 <meta name="viewport" content="width=device-with, initial-scale=1, shrink-to-fit=no"> 8 <meta http-equiv="content-type" content="text/html; charset = UTF-8"> 9 <title>施設DB</title> 10 <link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css" /> 11 <link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css" /> 12</head> 13 14<body> 15 <div id="app"> 16 <label>【氏名】</label> 17 <select class="form-control" v-model="selected" style="width: 50%"> 18 <option value="田中 太郎"> 田中 </option> 19 <option value="鈴木 一郎"> 鈴木 </option> 20 <option value="佐藤 次郎"> 佐藤 </option> 21 </select> 22 <input type="button" v-on:click="this.sendData" value="SEND"/> 23 <div id="add"></div> 24 25 <h4>test情報</h4> 26 <table class='table table-striped table-bordered table-condensed newline'> 27 <thead> 28 <tr style='font-size: 80%'> 29 <th class='col-xs-1 col-ms-1 col-md-1 col-lg-1'>名前</th> 30 <th class='col-xs-1 col-ms-1 col-md-1 col-lg-1'>ボタン</th> 31 </tr> 32 </thead> 33 <tbody> 34 <tr v-for="row in rowdata"> 35 <td class='col-xs-1 col-ms-1 col-md-1 col-lg-1'> {{ row[1] }}</td> 36 <td class='col-xs-1 col-ms-1 col-md-1 col-lg-1'><button v-on:click='openModal'>test</button></td> 37 </tr> 38 </tbody> 39 </table> 40 41 <div id="overlay" v-show="showContent"> 42 <div id="content"> 43 <p>これがモーダルウィンドウです。</p> 44 <button v-on:click="closeModal">Close</button> 45 </div> 46 </div> 47 </div> 48 49 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.7.10/vue.min.js"></script> 50 <script src="https://unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script> 51 <script src="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script> 52 <script> 53 new Vue({ 54 el: '#app', 55 data: { 56 showContent: false, 57 rowdata: [], 58 selected: '', // プルダウン初期値 59 }, 60 methods:{ 61 openModal: function(){ 62 this.showContent = true 63 }, 64 closeModal: function(){ 65 this.showContent = false 66 }, 67 sendData: function() { 68 google.script.run 69 .withFailureHandler(this.fail) 70 .withSuccessHandler(this.data_table) 71 .search(this.selected) 72 }, 73 data_table: function(result) { 74 var json = JSON.parse(result) 75 this.rowdata.splice(0) 76 this.rowdata.push(...json) 77 }, 78 fail:function(e) { 79 console.log("Error"+e) 80 } 81 } 82 }) 83 </script> 84</body> 85 86</html>

code.gs

js

1function doGet() { 2 return HtmlService.createHtmlOutputFromFile('index'); 3} 4 5function search(data) { 6 var ss = SpreadsheetApp.openById('スプレッドシートID'); 7 var sh = ss.getSheetByName('施設DB'); 8 9 // 全データ取得 10 var mst = sh.getDataRange().getValues(); 11 // フロントから取得した氏名でフィルタリング 12 var inv = mst.filter(function(e){return e[2] === data}); 13 return JSON.stringify(inv); 14}

① セレクトボックスにv-model を使うことで、セレクトボックスの選択した要素を Vue内の指定した変数(selected)に紐付けています。

html

1 <select class="form-control" v-model="selected" style="width: 50%"> 2...略... 3 data: { 4 showContent: false, 5 rowdata: [], 6 selected: '', // プルダウン初期値 7 },

② テーブルの表示は、htmlタグを文字列で構築するのではなく、v-forを使っています。

html

1 <tbody> 2 <tr v-for="row in rowdata"> 3 <td class='col-xs-1 col-ms-1 col-md-1 col-lg-1'> {{ row[1] }}</td> 4 <td class='col-xs-1 col-ms-1 col-md-1 col-lg-1'><button v-on:click='openModal'>test</button></td> 5 </tr> 6 </tbody>

③ 呼び出す関数をすべて methods に閉じ込めています。

js

1 methods:{ 2 openModal: function(){ 3 this.showContent = true 4 }, 5 closeModal: function(){ 6 this.showContent = false 7 }, 8 sendData: function() { 9 google.script.run 10 .withFailureHandler(this.fail) 11 .withSuccessHandler(this.data_table) 12 .search(this.selected) 13 }, 14 data_table: function(result) { 15 var json = JSON.parse(result) 16 this.rowdata.splice(0) 17 this.rowdata.push(...json) 18 }, 19 fail:function(e) { 20 console.log("Error"+e) 21 } 22 }

投稿2022/09/19 12:59

編集2022/09/20 15:05
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問