実現したいこと
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/ツールのバージョンなど)
今回初めてこのような形で質問させていただくのとプログラミングも初めてまだ一月程度しか学習できておらず質問文・コード文ともに稚拙で申し訳ないです。
また、本題に関係ない文章はできるだけ削除しているつもりですが余分な文章が大量にあると思われますので、そちらも申し訳ないです。
回答3件
あなたの回答
tips
プレビュー