I. GASーjavascript入門
まずはGoole App Scriptでの演習から。
Googleサーバ上でGAS環境で試す場合と、クライアントのchrome上で試す場合の微妙な差を区別しておくと良い。
まずはGoogleサーバ上のGAS環境で試す。
1.変数
let name = 'John'; // 文字列型の変数
let age = 25; // 数値型の変数
let isStudent = true; // 真偽値型の変数
Logger.log(`名前: ${name}`);
Logger.log(`年齢: ${age}`);
Logger.log(`学生: ${isStudent ? 'はい' : 'いいえ'}`);
2. 演算子と制御構文
let num = 10;
// 条件分岐
if(num % 2 === 0) {
Logger.log(`${num} は偶数です`);
} else {
Logger.log(`${num} は奇数です`);
}
// ループ
for(let i = 0; i < 5; i++) {
Logger.log(`現在の値: ${i}`);
}
3. 配列と繰り返し
let fruits = ['apple', 'banana', 'cherry'];
// 配列の要素数を表示
Logger.log(`配列の要素数: ${fruits.length}`);
// 配列の各要素を表示
for(let i = 0; i < fruits.length; i++) {
Logger.log(`フルーツ${i+1}: ${fruits[i]}`);
}
II. GASとGoogle SpreadSheetの連携
a) まず基本のGASでのdoGet()
まず、単なるdoGet()メソッドを作り、変数の中身をHTMLで表示させてみる。
HTMLは文字列であることに注意。
function doGet() {
// ダミーの最新メッセージを作成
const dummyMessages = [
["Hello"],
["World"],
["How are you?"]
];
// HTML 文字列を作成
let output = '<html><head><title>メッセージ一覧</title></head><body>';
output += '<h1>メッセージ一覧</h1>';
output += '<ul>';
dummyMessages.forEach(function(message) {
output += '<li>' + message[0] + '</li>';
});
output += '</ul></body></html>';
return HtmlService.createHtmlOutput(output);
}
b) 演習
Google SpreadsheetのデータをHTMLを使ってクライアント側で表示できるようにしよう。
ヒントのプログラム
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0]; // 最初のシートを取得
const range = sheet.getRange("A1:A" + sheet.getLastRow()); // A列のデータ範囲
const messages = range.getValues(); // 二次元配列で取得
HTMLのliタグ部分を生成するヒント
messages.forEach(function(row) {
const message = row[0];
if (message) {
output += '<li>' + message + '</li>';
}
});
III. HTMLのフォームで入力を行う
a) google側に置くHTMLファイル(form.html)
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function showAlertAndSubmit(event) {
event.preventDefault();
alert('ボタンが押されました');
document.getElementById('myForm').submit(); // 手動で送信
}
</script>
</head>
<body>
<div class="container">
<h2>送信フォーム</h2>
<form id="myForm" method="POST" action="****ここに注意*****" onsubmit="showAlertAndSubmit(event)">
<button type="submit" name="confirm" value="true">送信</button>
</form>
</div>
</body>
</html>
b) GASのdoPost()
form.htmlを一部変更が必要
<form method="POST" action="****ここに注意*****">
<input type="text" name="inputData" placeholder="データを入力">
<button type="submit" name="confirm" value="true">送信</button>
</form>
GAS側のプログラム
function doPost(e) {
const id = "あなたのSpreadsheet ID";
const spreadsheet = SpreadsheetApp.openById(id);
const sheet = spreadsheet.getSheetByName('シート1');
if (!sheet) {
return HtmlService.createHtmlOutput("エラー: シート 'シート1' が見つかりません。");
}
const inputData = e.parameter.inputData;
if (!inputData) {
return HtmlService.createHtmlOutput("エラー: inputData が空です。");
}
const lastRow = sheet.getLastRow();
sheet.getRange(lastRow + 1, 1).setValue(inputData);
return HtmlService.createHtmlOutput("データをスプレッドシートに追加しました。");
}
IV. 少しだけアプリっぽくしゅうせい
a) form.htmlの修正
少しCSSで見た目を変えたform.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MEMOアプリ</title>
<style>
body {
background-color: #f8f9fa;
font-family: sans-serif;
margin: 0;
padding: 20px;
}
.container {
max-width: 600px;
margin: 0 auto;
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
h1 {
text-align: center;
color: #17a2b8;
margin-bottom: 20px;
}
form {
margin-bottom: 20px;
}
input[type="text"] {
width: 100%;
padding: 12px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
button {
margin-top: 10px;
width: 100%;
padding: 12px;
font-size: 16px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
ul {
list-style-type: none;
padding-left: 0;
}
li {
padding: 10px;
border-bottom: 1px solid #ddd;
color: #6c757d;
}
</style>
</head>
<body>
<div class="container">
<h1>MEMO</h1>
<form id="form">
<input type="text" id="memoinp" name="memo" placeholder="Memoを入力" autocomplete="off" />
<button type="submit">追加</button>
</form>
<ul id="ul"></ul>
</div>
<script>
const form = document.getElementById("form");
const memoinp = document.getElementById("memoinp");
const ul = document.getElementById("ul");
form.addEventListener("submit", function (event) {
event.preventDefault();
const text = memoinp.value.trim();
if (text !== "") {
const li = document.createElement("li");
li.textContent = text;
ul.appendChild(li);
fetch("https://script.google.com/macros/s/【あなたのWebアプリURL】/exec", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: "memo=" + encodeURIComponent(text)
}).then(response => response.text())
.then(msg => console.log("GAS応答:", msg))
.catch(err => console.error("送信失敗:", err));
memoinp.value = "";
}
});
</script>
</body>
</html>
b) doPost()の修正
一応doGet()の定義も載せておきます。
function doGet() {
return HtmlService.createHtmlOutputFromFile("form");
}
function doPost(e) {
const id = "あなたのスプレッドシートID";
const spreadsheet = SpreadsheetApp.openById(id);
const sheet = spreadsheet.getSheetByName('シート1');
if (!sheet) {
return HtmlService.createHtmlOutput("シートが見つかりません。");
}
const memo = e.parameter.memo;
if (!memo) {
return HtmlService.createHtmlOutput("memoが送信されていません。");
}
const timestamp = new Date();
sheet.appendRow([timestamp, memo]);
return HtmlService.createHtmlOutput("メモが追加されました。");
}
Chrome上のdocumentオブジェクトの確認
ChromeのDevToolのConsoleからdocumentオブジェクトを確認する。
document
さらに、メソッド、プロパティを確認
document.getElementById("memoinp")
document.getElementById("memoinp").value
X. 予備:HTMLベースのjavascriptプログラム
Canvas環境のプログラム
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="500" height="500" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
let canvas = document.getElementById('myCanvas');
let ctx = canvas.getContext('2d');
ctx.fillStyle = "#FF0000";
ctx.fillRect(0, 0, 150, 75);
</script>
</body>
</html>
svgを使った描画
<!DOCTYPE html>
<html>
<body>
<svg width="400" height="180">
<rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
</svg>
</body>
</html>