wet-to-dry’s blog

京大大学院生の備忘録ブログ

実験マウスを管理するための専用フォームを開発する4

概要

以前から「マウス管理システム」なるものをちょくちょく作っています。

wet-to-dry.hatenablog.com

wet-to-dry.hatenablog.com

wet-to-dry.hatenablog.com

これを、さらに変更しました。

変更点としては、

一番てこずりました。。。コツはwithSuccessHandlerの使い方でしたね。

  • マウスが生まれた際の入力ページに、0から10の選択肢を作成する関数をjavascriptで作成した

0から10までoptionタグ作ってるのがダサかったので。

  • index.htmlを「マウスが生まれた」と「マウスを屠殺した」に分岐させるだけのページにして、遷移先のページで実際の値を入力するようにした

これでやれることが一気に増えます。

できたもの

以下のサイトを参考にしました。

qiita.com

スプレッドシートは引き続き以下のものを使用している(URL共有済み)

docs.google.com

コードもいっそ共有してしまおう!

script.google.com

一応コードを下に書きます

main.js

var id = "1HuaAdg-xdo6n_JJXCYgyzD8bAHjl09ngtJbVwF8SXNw";

// htmlからhtmlへの遷移用。"https://surleconomiejp.blogspot.com/2017/02/google-apps-script-htmlhtml.html"を参考にした。
function doGet(e) {
  if (!e.parameter.page) {
    return HtmlService.createTemplateFromFile('index').evaluate();
  }
  return HtmlService.createTemplateFromFile(e.parameter['page']).evaluate();
}

// htmlからhtmlへの遷移用。"https://surleconomiejp.blogspot.com/2017/02/google-apps-script-htmlhtml.html"を参考にした。
function getScriptUrl() {
  var url = ScriptApp.getService().getUrl();
  return url;
}

// cssやjavascriptの外部ファイルを読み込むための関数。"https://qiita.com/taromorimotohf/items/5e52cb9062600e8ccac3"を参考にした。
function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename).getContent();
}

//スプレッドシートのデータを格納。"https://qiita.com/non-programmer/items/e822dbeb7b3ab6e403b3"を参考にした。
function loading(sheetname) {
  var ss = SpreadsheetApp.openById(id);
  var listss = ss.getSheetByName(sheetname);
  //最終行を調べる
  var lastrow = listss.getLastRow();
  //2行1列目最終行3列目までを二次元配列に入れています。
  var list = listss.getRange(2, 1, lastrow-1, 3).getValues();
  //時間要素をplane textに直す
  for (var i=0; i<list.length; i++){
    var date = list[i][1];
    var dateString = Utilities.formatDate(date,"JST","yyyy/MM/dd");
    list[i].splice(1, 1, dateString); 
  }
  return list;
}

// spreadsheetからデータを削除するための関数。
function delete_from_sheet_gs(sheetname, value) {
  var ss = SpreadsheetApp.openById(id);
  var listss = ss.getSheetByName(sheetname);
  listss.deleteRows(Number(value) + 2);
}

// spreadsheetにhtmlから直接書き込むための関数。"https://www.pre-practice.net/2017/10/web.html"を参考にした。
function input_to_sheet_gs(sheetname, value) {
  // 日時をYYYY//MM//DDの形式に変更
  var dt = new Date();
  var y = dt.getFullYear();
  var m = ("00" + (dt.getMonth() + 1)).slice(-2);
  var d = ("00" + dt.getDate()).slice(-2);
  var time = y + "/" + m + "/" + d;
  
  var ss = SpreadsheetApp.openById(id)
  var sh = ss.getSheetByName(sheetname);
  
  var lastRow = sh.getLastRow() + 1;
  sh.getRange(lastRow, 1, 1, 2).setValues([[value, time]]);
  sh.getRange(lastRow, 3).setFormulaR1C1("=ROUNDDOWN((TODAY()-R" + lastRow + "C2)/7)");
}

index.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <base target="_top" />
    <?!= include('css'); ?>
    <!---html間の遷移用--->
    <?var url = getScriptUrl();?>
  </head>
  <body>
    <h1>マウス管理フォーム</h1>
    <button onclick="window.top.location.href='<?!=url?>?page=born_mouse'">生まれた</button><br>
    <button onclick="window.top.location.href='<?!=url?>?page=slaughter_mouse'">屠殺した</button>
  </body>
</html>

result.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <?!= include('css'); ?>
    <?var url = getScriptUrl();?>
  </head>
  <body>
    <h1>マウス管理フォーム</h1>
    送信が完了しました。<br><br>
    
   <!---別のhtmlへの遷移は"https://surleconomiejp.blogspot.com/2017/02/google-apps-script-htmlhtml.html"を参考にした--->
   <button onclick="window.top.location.href='<?!=url?>?page=index'">もう一度回答する</button>
  </body>
</html>

born_mouse.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <base target="_top" />
    <?!= include('css'); ?>
    <?var url = getScriptUrl();?>
  </head>
  <body>
    <h1>マウス管理フォーム</h1>
    オスの匹数
    <select id="male">
    </select>
    <br>
    メスの匹数
    <select id="female">
    </select>
    <br>

    <button onclick="input_to_sheet();window.top.location.href='<?!=url?>?page=result'">送信する</button>
  </body>
  <?!= include('js_input_to_sheet'); ?>
</html>

slaughter_mouse.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <base target="_top" />
    <?!= include('css'); ?>
    <?var url = getScriptUrl();?>
  </head>
  <body>
    <h1>マウス管理フォーム</h1>
    使用したマウス
    <select id="sheetname" name="sheetname" onchange="loadsheet(this);" required>
      <option value="オス">オス</option>
      <option value="メス">メス</option>
    </select>
    <div id="information">
      <select id="list" name="list"></select>
    </div>
    <button id="submit" onclick="delete_from_sheet();window.top.location.href='<?!=url?>?page=result'">送信する</button>
  </body>
  <?!= include('js_list_from_sheet'); ?>
</html>

js_input_to_sheet.html

<script>
  function input_to_sheet() {
    let list = ["male", "female"];
    let sheetname = "";
    for (let i = 0; i < 2; i++) {
      if (i < 1) {
        sheetname = "オス";
      } else {
        sheetname = "メス";
      }
      let value = document.getElementById(list[i]).value;
      //valueが0の場合は入力しない
      if (value != 0){
        google.script.run.input_to_sheet_gs(sheetname, value);
      }
    }
    alert("スプレッドシートに入力しました!");
  }
  
  //selectの要素内に0から10までの選択肢を作成する関数。
  function add_options() {
    let list = ["male", "female"];
    for (let i = 0; i < list.length; i++) {
      let select = document.getElementById(list[i]);
      for (let j = 0; j <= 10; j++) {
        let option = document.createElement('option');
        option.setAttribute('value', j);
        option.innerHTML = j;
        select.appendChild(option);
      }
    }
  }
  
  add_options();
  
</script>

js_list_from_sheet.html

<script>
  //スプレッドシートの値をselectの要素に導入する関数。"https://qiita.com/non-programmer/items/e822dbeb7b3ab6e403b3"を参考にした。
  function loadsheet() {
    let sheetname = document.getElementById("sheetname").value;
    //.gs内のloading()を呼び出し、読み込み後にListBack()でselect要素に選択肢を設定します。
    google.script.run.withSuccessHandler(ListBack).loading(sheetname);
  }

  window.addEventListener('load', loadsheet());
 
  //リスト読み込み
  function ListBack(data) {
    let select = document.getElementById('list');
    //選択を変えたときに前回の情報が残らないようにする
    while (select.firstChild) {
      select.removeChild(select.firstChild);
    }
    for (let i=0; i<data.length; i++){
      let option = document.createElement('option');
      option.setAttribute('value', i);
      option.innerHTML = data[i][1] + "生まれ, " + data[i][0] + "匹, " + data[i][2] + "週齢";
      select.appendChild(option);
    }
  }

  function delete_from_sheet(){
    let sheetname = document.getElementById("sheetname").value;
    let value = document.getElementById("list").value;
    google.script.run.delete_from_sheet_gs(sheetname, value);
    alert("スプレッドシートから削除しました!");
  }
</script>

css.html

<style>
body{
background:#000;
color:#fff;
}
</style>

あとがき

コードが死ぬほど増えました。githubに移るべきか??

あとやりたいこととしては、屠殺したマウスをデータとして残すために、「処分マウス」シートを作りたいなあ。

交配をかけるためのページもつくりたい。

データの受け渡しなどの土台になることはほとんど調べ切ったと思うので、あとは地道に書くだけです!

頑張ろう!

2020/12/03追記

記事をまとめました。

wet-to-dry.hatenablog.com