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 19 : Linux - 如何用virtualBox安装Linux的VM虚拟机?

>>:  110/18 - Android 7到Android 9图片剪裁

Day 26. F2E-完善选择帐户

今天这篇也是被遗忘的xD 赶快把他补起来哈哈 #接上真实资料 在 Day 08. F2E-选择帐号...

【D15】当大盘涨的时候,跟台积电有关系吗?

前言 取得众多资料後,接下来就要分析,我们来看看台积电与加权指数有关系吗? d15_2330AndT...

2D transform Continued

大家好,我是西瓜,你现在看到的是 2021 iThome 铁人赛『如何在网页中绘制 3D 场景?从 ...

企划实现(14)

GOOGLE登入 第八步:宣告 GoogleSignInClient mgoogleSignInCl...

Day4 官方 Demo 说明

今天我们要藉由官方所提供的 Demo,来介绍几个关键实体与流程的运作。再开始本篇 Demo 安装前,...