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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Google Apps Script

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

JavaScript

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

Q&A

解決済

3回答

2745閲覧

GASのデータベースから値を所得して二段階のメニューを作ったときにプルダウンの値が増え続けてしまう

tarataia

総合スコア17

Google Apps Script

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

JavaScript

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

0グッド

0クリップ

投稿2019/06/07 04:51

編集2019/06/07 06:52

実現したいこと

 Google Apps Scriptのwebアプリを作ることを通じて学習を進めています。
その中で選択肢をGAS側のデータベースから参照し、一段階目の選択肢を選ぶとシートの名前を参照して自動的に二段階目の選択肢がでるような二段階のプルダウンメニューを製作している所で、選択肢を所得する所まではできているのですが、一段階目のプルダウンメニューを変更したときに二段階目の値が残ったまま新しい選択肢が増えてしまう現象が発生して困っています。

(例)一段階目の選択肢 果物・野菜・魚・肉・飲み物
二段階目の果物の選択肢 イチゴ・リンゴ・モモ・メロン・ナシ
二段階目の野菜の選択肢 キャベツ・ピーマン・かぼちゃ

 一段階目で果物を選択したが、野菜を選ぼうとして選択肢を変えたときに本来であれば
野菜の選択肢が一段目にあって、二段目にはキャベツ・ピーマン・かぼちゃがくる想定をしているが、実際は一段目が野菜に野菜に変更した時に、二段目のメニューはイチゴ・リンゴ・モモ・メロン・ナシ・キャベツ・ピーマン・ナシとなってしまうのを前の選択肢を消すことで解決したいと考えています。

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

GASのデータベースから値を所得して二段階のメニューを作ったときにプルダウンの値が増え続けてしまう

該当のソースコード

【コード.gs】

function doGet(e) { var tpl = HtmlService.createTemplateFromFile('index'); return tpl.evaluate(); } function loading() { var ss = SpreadsheetApp.openById("xxxxxxxxxxxxxxxxx"); var listss = ss.getSheetByName("分類"); var lastrow = listss.getLastRow(); var list = listss.getRange(2, 1, lastrow-1, 3).getValues(); return list; } function myloading(){ var ss = SpreadsheetApp.openById("xxxxxxxxxxxxxxxxx"); var listss = ss.getSheetByName("果物"); var lastrow = listss.getLastRow(); var list = listss.getRange(2, 1, lastrow-1, 3).getValues(); return list; }//これが複数あります function resetdata(){ var select=document.getElementById("list2"); while(0< select.childNodes.length){ select.removeChild(select.childNodes[0]); }  }

【javascript.HTML】

<!DOCTYPE html> <html> <head> <base target="_top"> <?!= HtmlService.createHtmlOutputFromFile('css').getContent();?> <title>食べ物の分類</title> </head> <body> <form action="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" method="post"> <header> <h1 class="A">食べ物の分類</h1> <h2 class="B"><input type="data"></h2> <div id="information"> <select id="list" name="list" class="mainselect" onchange="addElement(this);formreset()" ; required><br> <option value=""></option> </select> </div> <div id="information!"> <select id="list2" name="list2" class="subbox" ; required><br> <option value=""></option> </select> </div> <script> function preventFormSubmit() { var forms = document.querySelectorAll('index'); for (var i = 0; i < forms.length; i++) { forms[i].addEventListener('submit', function(event) { event.preventDefault(); }); } google.script.run.withSuccessHandler(ListBack).loading(); } window.addEventListener('load', preventFormSubmit); //リスト読み込み function ListBack(data) { listdata = data; var list = document.getElementById('list'); for (var i=0; i<data.length; i++){ var option = document.createElement('option'); option.setAttribute('value', data[i][0]); option.innerHTML = data[i][0]; list.appendChild(option); } } function addElement(select) { for(var i=0; i<listdata.length; i++){ if(select.value ==listdata[i][0]){ break; } } var element = document.createElement('div'); var obj = document.getElementById("information"); var division = obj.getElementsByTagName('div'); if(division.length > 0){ obj.removeChild(division[0]); } element.class = "information"; obj.appendChild(element); mybotton(); formreset();  } function mybotton(){ var score=document.getElementById("list").value; for(var i=0; i<score.length; i++){ if(score == "果物"){ google.script.run.withSuccessHandler(ListBacks).myloading(); break; }//}閉じかっこが必要 else if(score == "野菜"){ google.script.run.withSuccessHandler(ListBacks).myloading2(); break; } else if(score == "魚"){ google.script.run.withSuccessHandler(ListBacks).myloading3(); break; } else if(score == "肉"){ google.script.run.withSuccessHandler(ListBacks).myloading4(); break; } else if(score == "炭水化物"){ google.script.run.withSuccessHandler(ListBacks).myloading5(); break; } }  } //リスト読み込み function ListBacks(data) { listdata = data; var list = document.getElementById('list2'); for (var i=0; i<data.length; i++){ var option = document.createElement('option'); option.setAttribute('value', data[i][0]); option.innerHTML = data[i][0]; list.appendChild(option); } } function formreset(){ google.script.run.withSuccessHandler(ListBacks).resetdata(); resetButtonElement = document.getElementById('list2'); } resetButtonElement.onchange = function() { formElement.reset(); } </script> <script type="text/javascript"> </script> </header> </table><input type="submit" value="送信" name="送信" > <input type="reset" value="リセット" name="リセット" id="reseter" onclick="formreset()">  </form> </body> </html>

試したこと

https://teratail.com/questions/10374
の質問者様と回答者様のやりとりを拝見して
【コード.gs】

function resetdata(){ var select=document.getElementById("list2"); while(0< select.childNodes.length){ select.removeChild(select.childNodes[0]);// } }

【javascript.HTML】

function formreset(){ google.script.run.withSuccessHandler(ListBacks).resetdata() resetButtonElement = document.getElementById('list2'); } resetButtonElement.onchange = function() { formElement.reset(); }

という内容のコードを入れてonchangeでフォームの中身が変化した時にformreset関数を実行して非同期でGAS側のresetdata関数を引き起こしてListBacks関数の中に入れるようにしたつもりだったが、動かず代替案としてもう一つボタンを作ってそのボタンを押せばresetdata関数が実行されるようにもテストしてみたがこちらもうまくいきませんでした。

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

今回初めてこのような形で質問させていただくのとプログラミングも初めてまだ一月程度しか学習できておらず質問文・コード文ともに稚拙で申し訳ないです。
また、本題に関係ない文章はできるだけ削除しているつもりですが余分な文章が大量にあると思われますので、そちらも申し訳ないです。

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

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

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

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

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

tarataia

2019/06/07 05:37

大変失礼いたしました。 インデントの方は修正できたかと思うのですが、マークダウンの記載についてはまだ駄目な部分があると思うので大変恐縮ですが漏れなどございましたら追記していただけると幸いです。
guest

回答3

0

ベストアンサー

GAS

1function resetdata(){ 2 var select=document.getElementById("list2"); 3 while(0< select.childNodes.length){ 4 select.removeChild(select.childNodes[0]); 5 } 6}

これ、GAS側に実装していますが、GASはサーバーサイド処理なので、getElementByIdとかやっても要素とれないですよ。サーバー側でやる必要が全く無いです。

投稿2019/06/07 07:09

macaron_xxx

総合スコア3191

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

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

tarataia

2019/06/07 07:49

回答ありがとうございます。 サーバーサイドとフロントサイドの違いについてまだ理解が浅かったです・・・ 回答を元にコードの微変更を行ったところうまく機能させることができたので、回答の所に自分で行った解決策を示した後にベストアンサーとさせていただきます。
guest

0

resetdata 関数内の removechild => removeChild が原因ではないでしょうか?

投稿2019/06/07 06:32

YukiYamashina

総合スコア1011

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

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

tarataia

2019/06/07 06:49

素早い回答ありがとうございます。質問文の部分も訂正させていただきます。 しかし、スペルミスを修正した後でもまだコードは機能していないようです。
guest

0

変更後
【コード.GS】

 function doGet(e) { var tpl = HtmlService.createTemplateFromFile('index'); return tpl.evaluate(); } function loading() { var ss = SpreadsheetApp.openById("xxxxxxxxxxxxxxxxx"); var listss = ss.getSheetByName("分類"); var lastrow = listss.getLastRow(); var list = listss.getRange(2, 1, lastrow-1, 3).getValues(); return list; } function myloading(){ var ss = SpreadsheetApp.openById("xxxxxxxxxxxxxxxxx"); var listss = ss.getSheetByName("果物"); var lastrow = listss.getLastRow(); var list = listss.getRange(2, 1, lastrow-1, 3).getValues(); return list; }//これが複数あります

【javascript.HTML】

<!DOCTYPE html> <html> <head> <base target="_top"> <?!= HtmlService.createHtmlOutputFromFile('css').getContent();?> <title>食べ物の分類</title> </head> <body> <form action="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" method="post"> <header> <h1 class="A">食べ物の分類</h1> <h2 class="B"><input type="data"></h2> <div id="information"> <select id="list" name="list" class="mainselect" onchange="addElement(this); resetdata()"; required><br> <option value=""></option> </select> </div> <div id="information!"> <select id="list2" name="list2" class="subbox" ; required><br> <option value=""></option> </select> </div> <script> function preventFormSubmit() { var forms = document.querySelectorAll('index'); for (var i = 0; i < forms.length; i++) { forms[i].addEventListener('submit', function(event) { event.preventDefault(); }); } google.script.run.withSuccessHandler(ListBack).loading(); } window.addEventListener('load', preventFormSubmit); //リスト読み込み function ListBack(data) { listdata = data; var list = document.getElementById('list'); for (var i=0; i<data.length; i++){ var option = document.createElement('option'); option.setAttribute('value', data[i][0]); option.innerHTML = data[i][0]; list.appendChild(option); } } function addElement(select) { for(var i=0; i<listdata.length; i++){ if(select.value ==listdata[i][0]){ break; } } var element = document.createElement('div'); var obj = document.getElementById("information"); var division = obj.getElementsByTagName('div'); if(division.length > 0){ obj.removeChild(division[0]); } element.class = "information"; obj.appendChild(element); mybotton();  } function mybotton(){ var score=document.getElementById("list").value; for(var i=0; i<score.length; i++){ if(score == "果物"){ google.script.run.withSuccessHandler(ListBacks).myloading(); break; }//}閉じかっこが必要 else if(score == "野菜"){ google.script.run.withSuccessHandler(ListBacks).myloading2(); break; } else if(score == "魚"){ google.script.run.withSuccessHandler(ListBacks).myloading3(); break; } else if(score == "肉"){ google.script.run.withSuccessHandler(ListBacks).myloading4(); break; } else if(score == "炭水化物"){ google.script.run.withSuccessHandler(ListBacks).myloading5(); break; } }  } //リスト読み込み function ListBacks(data) { listdata = data; var list = document.getElementById('list2'); for (var i=0; i<data.length; i++){ var option = document.createElement('option'); option.setAttribute('value', data[i][0]); option.innerHTML = data[i][0]; list.appendChild(option); } }     function resetdata(){    var select=document.getElementById("list2");    while(0< select.childNodes.length){ //セレクトボックスの子要素を取得しつつループ    select.removeChild(select.childNodes[0]);//セレクトボックスから子要素を削除    }    } </script> <script type="text/javascript"> </script> </header> </table><input type="submit" value="送信" name="送信" > <input type="reset" value="リセット" name="リセット" id="reseter" onclick="formreset()">  </form> </body>

変更点だけをうまく切り取ることができなかったので全文貼りましたが変更点は
・【コード.GS】にあったresetdata関数を【javascript.HTML】側に移した
・id listのonchangeの中にresetdata関数を追加
・その際にコメントアウトで不要だと思われる文章をいくつか削除

とても初歩的なことで何かのためになるとは思えませんが、自分の学習のメモも兼ねて対応策を記しておきました。

投稿2019/06/07 08:09

tarataia

総合スコア17

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問