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

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

新規登録して質問してみよう
ただいま回答率
85.31%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

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

JavaScript

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

Q&A

1回答

239閲覧

指定したdivタグとその子要素をJavaScriptで生成し、スプレッドシートに書き込まれた内容を反映させたい

nyon65

総合スコア0

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

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

JavaScript

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

0グッド

0クリップ

投稿2023/08/25 09:41

編集2023/08/25 09:46

実現したいこと

  • <div class="container">内に<div class="menu-item" >とその子要素を、Googleスプレッドシートに書き込まれた内容に応じて生成したい
  • スプレッドシートの内容が空の時は増減するようにしたい。
  • h3やpタグのmeta-name属性はをスプレッドシートに対応して、menu1,menu2,menu3というように数が増えるようにしたい

前提

JavaScriptとGASでGoogleスプレッドシートに書き込まれた内容をWeb上に自動で反映させるシステムを作成しています。
現在HTML上に下記のコード(HTMLのソースコード)がある状態だと自動で反映できるのですが、HTMLに上記のコードが無い場合は反映されず、スプレッドシートに書き込まれた量に応じて手作業で上記のコードを書き足している状況です。
スプレッドシートの内容が書き込まれたら自動で上記のコードを生成するプログラムに修正したいです。

発生している問題・エラーメッセージ

該当のソースコード

HTML
<div class="container"> <div class="menu-item"> <h3 class="menu" id="menu1" data-name="menu1" ></h3> <p class="price" data-name="price1"></p> </div>
JavaScript
fetch('GASのURL') .then(response => response.json()) .then(data => { const object = data; // タグを生成または削除する関数 function updateTags() { // 各menu-itemごとに処理 const menuItems = document.querySelectorAll('.menu-item'); menuItems.forEach((menuItem, index) => { let imgName = 'img${index + 1}'; // 画像のURLを示すデータ名 // スプレッドシートのデータが存在する場合 if (object[0][imgName]) { let itemImg = menuItem.querySelector('.item-img');//最初にマッチしたCSSセレクタを指定 if (!itemImg) { itemImg = document.createElement('img'); itemImg.classList.add('item-img'); //要素にクラス名を付与 menuItem.prepend(itemImg); //先頭に要素を追加する } itemImg.src = object[0][imgName]; } // スプレッドシートのデータが存在しない場合 else { const itemImg = menuItem.querySelector('.item-img'); if (itemImg) { menuItem.removeChild(itemImg); } } }); } updateTags(); // 要素ごとの処理 const elements = document.querySelectorAll('h1, h2.kinds1, h3.menu, p.price'); elements.forEach(element => { const dataName = element.getAttribute('data-name'); if (object[0][dataName]) { element.textContent = object[0][dataName]; } }); });
GAS
const SPREAD_SHEET_ID = 'スプレッドシートのID'; const SHEET_NAME = 'シート1'; // GETリクエスト時に呼び出される関数 function doGet(e) { const data = getDataFromSpreadsheet(SPREAD_SHEET_ID, SHEET_NAME); const jsonResponse = createJsonResponse(data); return jsonResponse; //スプレッドシートからデータを取得し、JSONレスポンスを生成して返す } // スプレッドシートからデータを取得する関数 function getDataFromSpreadsheet(spreadsheetId, sheetName) { const app = SpreadsheetApp.openById(spreadsheetId);//スプレッドシートを開き、指定されたシート名のシートを取得 const sheet = app.getSheetByName(sheetName); const values = sheet.getDataRange().getValues();//セルの値を2次元配列として取得 const data = []; for (let i = 1; i < values.length; i++) { const param = {}; for (let j = 0; j < values[i].length; j++) { param[values[0][j]] = values[i][j]; }//各行のデータをオブジェクトにまとめ、配列に追加 data.push(param); } return data; } // JSONレスポンスを作成する関数 function createJsonResponse(data) { const result = ContentService.createTextOutput();//テキスト出力オブジェクトを生成 result.setMimeType(ContentService.MimeType.JSON);//MimTypeをJSONに設定 result.setContent(JSON.stringify(data));//JSON文字列に変換したデータをセット return result; }

試したこと

JavaScriptでdiv.menu-itemをcreateElementし、appendChildで子要素を追加しようとしたが、途中でエラーが出てしまい、表示されなくなった。上記のコードは違う手法ではあるが、一応表示はできている状態。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

最終的に欲しいDOM構造は下記のような感じでしょうか?

html

1 <div class="container"> 2 <div class="menu-item"> 3 <img class="item-img" src="xxxxx.jpg"> 4 <h3 class="menu" id="menu1" data-name="menu1">メニュー名1</h3> 5 <p class="price" data-name="price1">xxx円</p> 6 </div> 7 <div class="menu-item"> 8 <img class="item-img" src="yyyyy.jpg"> 9 <h3 class="menu" id="menu2" data-name="menu2">メニュー名2</h3> 10 <p class="price" data-name="price2">yyy円</p> 11 </div> 12 <!-- 3件目以降は略 --> 13 </div>

であれば、シートの内容というか通信内容はこう?

json

1[ 2 { "imgName":"xxxxx.jpg", "menu":"メニュー名1", "price":"xxx円" } 3 ,{ "imgName":"yyyyy.jpg", "menu":"メニュー名2", "price":"yyy円" } 4 // 3件目以降略 5]

スプレッドシートの内容が空の時は増減するようにしたい

これは「空の時は増減」というよりは、「スプレッドシートの内容に一致するテーブル表示したい」という意味でしょうか?

もしそうであれば、正直今の処理は一旦忘れて
通信毎に containerの中を全部消す → 通信内容の行数(=スプレッドシートの行数)にあわせて、1行ごとにmenu-itemを生成してcontainerに入れる
が良さそうです。

現状ではmenuItemsをforEachで繰り返してitemImgだけ自力でcreateElementしていますが、
通信内容の行ごとの繰り返しにしてその行データに基づきmenu-item以下の全要素を組み立てることになります。

投稿2023/08/25 10:24

編集2023/08/25 10:26
pecmm

総合スコア760

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

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

nyon65

2023/08/27 11:41

pecmmさん返信遅れてしまい申し訳ありません。 コメントありがとうございます。 >これは「空の時は増減」というよりは、「スプレッドシートの内容に一致するテーブル表示したい」という意味でしょうか? おっしゃる通りです。表示したいHTML、スプレッドシートの内容をその通りです。 >通信内容の行ごとの繰り返しにしてその行データに基づきmenu-item以下の全要素を組み立てることになります。 まとめて一つのfor文で生成することばかり考えていました...ありがとうございます。試してみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問