本篇要解決的問題
前陣子朋友遇到一個問題,就是在填 Google 表單時,有沒有可能我們只要輸入學生的學號,其它像姓名、電話等等的欄位就自動帶出?因為需要很多人填這張表,每個人要填很多的學生,如果資料可以自動帶入,大家填表單就輕鬆多了。
August 看了一下 Google Forms events 後,發現由於預設的事件只有打開、提交這二個,並沒有編輯事件,因此要解決這個問題我們就要用自己客製 Google 表單的方法,而不能直接用 Google 表單。
這篇算是過去幾篇筆記文的整合應用,以下將整合這些筆記文,可以點進去看當時寫的比較詳細的部份:
- 完全客製 Google 表單,美化表單樣式
- 用 Google Apps Script 取得 Google Sheets / Excel 資料
- Google Apps Script 基本使用:跨網域 AJAX、接 Firebase
本篇做出的 Demo 頁面在這:
https://letswritetw.github.io/letswrite-google-forms-id-data/
1 建立比對用的原始資料
第一步,我們要先有一份原始的資料,這樣當使用者輸入完學號後,才能有一份資料去比對出學號,然後把這個學號下的資料給拋回來。
因為這篇是範例用,所以資料全部都從 fakenamegenerator.com 這個網站上抓的假資料,欄位幾乎都是英文也是很正常的事。
我們在 Google 雲端硬碟新增一份 Google 試算表,把資料給填上,記得「共用」設定的部份,要設成「任何知道這個連結的網際網路使用者都能查看」,這樣我們之後在 Google Apps Script 上抓資料時才抓得到:
這篇設定的原始資料是這樣:
因為有設成知道連結的都可以看,所以也可以 點擊這個連結 來看。
考量到也許會有編碼問題,所以表頭的部份 August 習慣用英文,這樣抓資料時比較精準。
原始資料建立完了,下一步我們就來製作 Google 表單。
2 製作填資料用的 Google 表單
在 Google 雲端硬碟上新增一個 Google 表單後,在上面設定好我們要問的題目。
這邊 August 除了把題目設成跟我們原始資料欄位一模一樣的題目外,最後再多一題「備註」,模擬使用者除了在輸入完學號後可以看到該學生的資料,也可以額外加上這次填表要新增的資料。
為了可以抓到表單上我們需要的 name
值,建議每一題不論題型,回答的方式都一律選擇「簡答」,不然像是複選的話,會發現不好抓到 name
。
另外要注意,如果是選用「必填」,到時我們用 POST 的方式傳值,那題就一定要有值,不然會傳不出去。
本篇建的 Google 表單如下:
這一步我們製作完表單了,下一步就是要抓 Google 表單的 URL、name。
3 抓 Google 表單的 URL、name
因為我們無法用程式去修改 Google 表單的值,因此只能把提交資料的部份改用我們自己發 POST。
POST 需要有一個 URL,跟要送出的 data。
URL
在 Google 表單上點滑鼠右鍵,按「檢查」,會出現一塊可以看到原始碼的面版,隨便點原始碼的地方,Mac 電腦按「cmd + F」,Windows 電腦按「control + F」,會出現一條搜尋框,我們搜尋「<form
」,就會看見原始碼移到 form 的標籤上:
<form>
裡面有一個 action
開頭的值,那個值就是我們需要的 URL,像這邊的值就是:
https://docs.google.com/forms/u/0/d/e/1FAIpQLSeNBnd-yVJ7_-tMq5xaQrvt0j18UtabCFBTM0Eu2O3ivDecuQ/formResponse
之後我們 POST 時,這個值就是要 POST 的 URL。
name
Google 表單這幾天發現有一點修改,為了方便抓到各題的 name
,我們先把表單上的欄位都先填個值上去。
填完後,一樣在剛剛面版那邊的搜尋框,我們搜尋「entry.
」,就會看見原始碼跳到有一排:
<input type="hidden" name="entry.XXXXXXX" value="剛剛填的值">
這一排就是我們要抓的各題的 name
:
因為我們都有先在題目的作答欄上填了值,因此原始碼上可以看到哪一題是哪一個 input
,我們把各題的 name
給記下來,在 POST 時需要把這些 name
當 key
。
本篇範例把 name
存下來就是這樣:
var data = { 'entry.1815052017': id, 'entry.1543576845': 姓名, 'entry.892230025': 性別, 'entry.1003128242': 電話, 'entry.260985931': 地址, 'entry.1782841550': 備註 }
4 製作一個表單頁面
這一步我們要製作一個自己的表單頁面出來。
很多 UI framework 都有設計表單的部份,像是 Bootstrap、Skeleton、Bulma 等等,可以直接使用這些框架來製作。
這邊 August 在表單的部份直接 copy Bootstrap 的 CSS(對就是懶 XD),做一個簡單的頁面出來:
頁面檔案的部份,最後會附上原始碼,這段就不貼上了。
有了自己的表單,下一步就來接資料吧。
5 程式碼:GAS 上篩原始資料
標題的 GAS 就是 Google Apps Script 的簡寫,可以在雲端上直接寫程式的工具。
我們在第一步的時候,建立了一個有原始資料的 Google 試算表出來。
這一步要處理的,就是我們可以發 POST 給試算表,並且帶入我們要查的學生 ID 後,試算表篩出這個 ID 有的資料再傳資料回來。
進到我們建立的原始資料的試算表,點擊「工具 > 指令碼編輯器」:
點擊後就會進到 GAS 的編輯器頁面。
GAS 上接 POST 的部份在以前的筆記文中有詳細說明了,這邊就不重覆寫,這段我們要做的就是 doPost
時,要抓我們原始的試算表資料進來,用迴圈比對出 ID,再把資料傳回來。
寫在 GAS 的原始碼如下,都有加上註解:
6 程式碼:接表單資料
程式碼的部份,因為需要接 input
的值,又要改 input
的值,我們就直接用 Vue.js,因為雙向綁定實在是太方便了,直接用 Vue.js 省事省時間(對就是懶 XD)。
要改用原生 JavaScript 或是改用可以再戰 10 年的 jQuery 都行,主要原理不變,就是拿 ID 值去發 POST,然後把 POST 回來的資料丟回到頁面的 input
上。
整個原始碼都貼出來會太長太像在搏版面,原始碼的部份最後會附上連結。
這邊就寫 August 在 Demo 中處理了哪些事情:
- 當表單發 POST 到 GAS 時,把 loading 的效果給用出來,避免因讀取時間長,使用者以為壞掉了又再按「送出」
- 當沒抓到資料時,所有
input
的欄位設成 disabled 禁止輸入 - submit 的這個 method,在 submit 被觸發時再檢查一次是不是真的有從 GAS 上收到資料回來,避免有人手動刪除 disabled
- 表單 ID 的部份,限制只能填 4 碼,超過的會自動截斷
- 性別的部份,直接用圖示代替文字
嗯啊,這段是寫給行銷、企劃看的,有時工程師們在收到你們的提案時,我們就是會想到這些有的沒的防呆跟防惡意,所以不要再一直以為我們有半夜跑出來寫 code 小精靈,你們提完的隔天就可以收到頁面,隔天你們會收到的只會有客訴(指)。
注意事項:Goolge 表單會永遠報錯
這邊有一個注意事項,有高手解決過的話歡迎留言提供。
由於我們是在自己製作的表單上發 POST 給 Google 表單送出資料,我們的網域跟 Google 表單的網域不同,因此在 POST 後一定都會在 console 上看到報錯。
但不用擔心,即便報錯,資料還是收得到,我們還是可以在 Google 表單的回覆或是試算表上收到結果。
只是要注意的是,因為 POST 的結果都會是 Error,我們要判斷使用者送出資料沒,也只能用 catch(error)
來處理,就變成如果使用者是真的遇到錯誤時,我們判斷不出來。
所以,在前端表單驗證的部份一定要寫好,只要是使用者按下送出,就一定要是正確的格式,以免因為格式不對 Google 表單拒收。
或是在設定 Google 表單的問題時,全部都設「簡答 + 非必填」,這樣可以確保資料會收到,但就是資料格式可能會遇到千奇百怪的狀況。
範例、原始碼
本篇實作出來的 Demo 在這:
https://letswritetw.github.io/letswrite-google-forms-id-data/
在 Demo 上提交後,可以從這邊看到提交結果:
https://docs.google.com/spreadsheets/d/1RkC-S29kN1Js-aK-g3DbvKPYQk3PpRWmqeSfYa_-YNE/edit?usp=sharing
原始碼也整理到 GitHub 上了:
https://github.com/letswritetw/letswrite-google-forms-id-data
您好,像您這樣的設計如果放在wordpress上面,是否可行呢?
例如,對方將資料以excel檔寄過來之後,我們再轉到”phpmyadmin” ,我們以自己的內網開啟網頁去抓對方的檔案。
會使用wordpress設計是因為要架一台nas自用,每日的檔案量大概有3000~10000件左右。
wordpress的話可以找看有沒有外掛可以直接使用。
畢竟WP強大的地方就在很多人寫好了外掛可以套。
收到。感謝。您的教學很詳細!感謝您的分享!
作為一個新手看到很多不一樣的東西都叫ID有點難懂
請問是否有可能第一頁載入基本資料後,並按下提交之後,開始一般的 google forms 問卷作答?
主要是想要讓第一頁載入基本資料…後面會有題目要做答的需求
請問下載範例使用,抓不到excel資料?
查看Response (F12) 沒有抓到資料 只顯示{}
請問哪邊設定有誤
您好,因為新手不懂程式碼,請問github要複製哪幾個檔案內容貼在appscript呢?我複製一個index.html但無法出現您這篇的功能,想讓同事可以輸入id就帶出部門等資料在回覆後續表單🤣,不確定我的做法是否正確,感謝
Google Apps Script 上要貼的是這一段後面的程式碼:「5 程式碼:GAS 上篩原始資料」。
不好意思,我把「5 程式碼:GAS 上篩原始資料」,有修改試算表的 ID,但還是無法成功QQ,請問是否還有哪些欄位是需要修改的呢?
另外請問「3 抓 Google 表單的 URL、name」的URL、name那些數值要放在哪裡呢? 感謝!
請問網頁中dist/main.min.js 要如何儲存
嗯?看不太懂問題,main.min.js是在GitHub上的檔案,GitHub目前只能整包下載,可以下載後再獨立把js給拿出來用。
請問有提供程式教練(家教)的服務嗎?我想應用google java script 在網頁,若有,麻煩告知費用,謝謝!
沒有喔,平常假日還有其他事情在忙,現在一個免費的家教就是:ChatGPT
您好,
我複製GAS scripts,測試時出現沒有doGet,請問要如何驗證GAS scripts?
可以用url?id =0101測試嗎
這篇筆記文沒有用到 doGet,都是用 doPost。如果單純要驗證,可以用 Postman,直接 GET 產生出的網址。
請教大大~我按圖索驥弄好後,我把ID長度限制改成7碼。但輸入ID後沒帶出資料~不知哪個環節沒弄好?哈
測試:https://terry0927.direct.quickconnect.to/new3/
感謝大大釋疑~感恩
程式碼的部份有寫錯嗎,我看目前的 Demo 頁都還可以用,代表 Google 表單沒有改動這一塊。你可以讓 GPT 幫你檢查一下程式碼。