iT邦幫忙

2021 iThome 鐵人賽

DAY 18
1
Modern Web

來自 GAS 的香氣~跟鳳黃酥一起享受 Google Apps Script 的午茶時光系列 第 18

Day 18 — To Do List (5) 新增 To Do Event

昨天我們快樂 (?) 的把資料 render 到網頁上(雖然會有點 Delay,對 UX 不好…不過那可以靠其他東西稍微彌補的。有空才處理)

那麼下一步我們就來做「新增」的功能吧!

對了,今天一樣有點忙,所以我會比較快帶過,之後會補上原理。


首先我們來看 GAS 的部分。

因為我們要新增一筆資料到試算表 DB 中,因此我們又要開始翻呀翻找呀找,看看有什麼適合的函式可以使用了。

根據經驗,只要有 append 這種東西,就能夠把資料附加在某種序列後面,而剛好 GAS 提供了 appednRow 這個方法,著實好用! (註一)

根據範例,我們可以知道這個方法是存在於 Sheet 物件中的,因此使用上要稍微注意:

function doGet() {
  return HtmlService.createHtmlOutputFromFile('index');
}

function showToDoListData() {
  const datas = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0].getDataRange().getValues();
  return JSON.stringify(datas.slice(1));
}

+function createToDoEvent({timestamp, event}) {
+  let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
+  let nextKey = sheet.getDataRange().getLastRow();
+  sheet = sheet.appendRow([timestamp, nextKey, event]);
+  sheet.getRange(sheet.getDataRange().getLastRow(), sheet.getDataRange().getLastColumn()).insertCheckboxes();
+  return JSON.stringify(sheet.getDataRange().getValues().slice(1));
+}

我們這邊傳入一個 object 資料,然後讓他去 append 到試算表資料的最後一行,接下來重新 return 全部的資料到前端去 render。


接下來來到網頁的部分。

網頁因為不是我們要琢磨的重點,因此我這邊就不特別琢磨畫面。

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      function showData(datas) {
        const tbody = document.querySelector('#items');
        datasFormat = []
        JSON.parse(datas).forEach(data => {
          datasFormat.push([data[2], data[3]])
        });
        datasFormat.forEach((data, index) => {
          const tr = document.createElement('tr');
          const count = document.createElement('td');
          count.innerText = index;
          tr.appendChild(count)
          data.forEach(item => {
            const td = document.createElement('td');
            td.innerText = item;
            tr.appendChild(td)
          });
          tbody.appendChild(tr);
        });
      }

      function submitCreate(event) {
        event = JSON.stringify(event);
        google.script.run.withSuccessHandler(showData).createToDoEvent(event);
      }

      google.script.run.withSuccessHandler(showData).showToDoListData();

      window.addEventListener('load', function() {
        document.querySelector('#update').addEventListener('click', function() {
          let addEvent = prompt("要增加的待辦事項")
          let events = {
            timestamp: new Date(),
            event: addEvent
          };
          submitCreate(events);
        });
      });

      
    </script>
  </head>
  <body>
    <div id="app">
      <p><button id="update">新增</button></p>
      <table>
        <thead>
          <tr>
            <th>編號</th>
            <th>事情</th>
            <th>是否完成</th>
          </tr>
        </thead>
        <tbody id="items"></tbody>
      </table>
    </div>
  </body>
</html>

弄完之後,我們重新部署一下,看一下結果:

咦咦咦?為什麼重複了!?

原因是因為我們在 render 的部分採用 += 的方式附加上去,所以我們要先把原本紀錄都清除乾淨,才會顯示的是正常的內容:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      function showData(datas) {
        const tbody = document.querySelector('#items');
+        tbody.innerHTML = '';
        datasFormat = []
        JSON.parse(datas).forEach(data => {
          datasFormat.push([data[2], data[3]])
        });
        datasFormat.forEach((data, index) => {
          const tr = document.createElement('tr');
          const count = document.createElement('td');
          count.innerText = index;
          tr.appendChild(count)
          data.forEach(item => {
            const td = document.createElement('td');
            td.innerText = item;
            tr.appendChild(td)
          });
          tbody.appendChild(tr);
        });
      }

      function submitCreate(event) {
        event = JSON.stringify(event);
        google.script.run.withSuccessHandler(showData).createToDoEvent(event);
      }

      google.script.run.withSuccessHandler(showData).showToDoListData();

      window.addEventListener('load', function() {
        document.querySelector('#update').addEventListener('click', function() {
          let addEvent = prompt("要增加的待辦事項")
          let events = {
            timestamp: new Date(),
            event: addEvent
          };
          submitCreate(events);
        });
      });

      
    </script>
  </head>
  <body>
    <div id="app">
      <p><button id="update">新增</button></p>
      <table>
        <thead>
          <tr>
            <th>編號</th>
            <th>事情</th>
            <th>是否完成</th>
          </tr>
        </thead>
        <tbody id="items"></tbody>
      </table>
    </div>
  </body>
</html>

然後我們再重新部署,看一下結果:

成功!


今天就到這裡囉!

我們明天來做刪除的部分喔~

那就明天見啦~

今日作業:

好好休息!


關於兔兔們:


我: 哎…時間真的好趕…可惡的開會…

註一:Sheet.appendRow(RowContents)


上一篇
Day 17 — To Do List (4) 讓網頁呈現試算表資料
下一篇
Day 19 - To Do List (6) 刪除 To Do Event
系列文
來自 GAS 的香氣~跟鳳黃酥一起享受 Google Apps Script 的午茶時光23

尚未有邦友留言

立即登入留言