Sheet
A pre-loaded list with a few blanks to fill in. A clipboard on a phone — not a spreadsheet.
What it is
You already know the list — who registered and what they owe, which dishes the potluck needs, who is in the class. What you don't know yet is what happens at the door: which check came in, who signed up for the salad, who showed up. A sheet is that list, pre-loaded, with the blanks you want filled.
Staff make the sheet once. Collectors open a link, enter a PIN, tap a name, fill the blanks. Everything typed lands in one place, and staff read it back as a table or CSV and do whatever comes next by hand — match payments to registrations, count the dishes, mark the roll. Nothing is computed, nothing is synced anywhere; it replaces the paper form and the retyping, not your judgement.
The same definition also prints as a paper form, for the people who would rather have paper.
Collecting — the phone side
- Open the link you were given. Enter the PIN. It is kept for this browser tab; tick Remember this PIN on this device for 7 days to skip it next time. Change or forget PIN at the bottom wipes it.
- Find the row — scroll, or type part of a name in the search box.
- Tap it. Fill in what you have. Blanks are fine. Tap Save.
- The row turns green with a ✓ and shows what you entered. Tap it again to correct, or Clear entry to erase what was entered — the row itself stays on the list.
- Someone not on the list? If the sheet allows it, + Add someone not on the list is at the bottom. You will have to type every column for them.
Several people can collect on the same sheet at once; the list refreshes when you come back to it. One row holds one entry — if two phones save the same row, the later save wins, and nothing is lost that was not overwritten on purpose.
The Entered by box is optional. Put your name in it once and it stays; it tells staff who to ask if something looks odd.
Staff — making a sheet
- Sign in at admin with your usual store account. Click + New sheet.
- Pick a program — the group of sheets that share a PIN (one retreat, one class). No program yet? Choose + New program… right there and give it a name and a PIN. Programs and their PINs live under Programs in the header.
- Give it a title, and a one-line note if collectors need one ("Checks payable to CCIC").
- Paste from a spreadsheet (CSV or TSV, header row first): copy the cells straight out of Excel or Google Sheets and click Load. Every header with data under it becomes a column; every header whose cells are all empty becomes an input; the first column whose values are all unique (a
reg_no) becomes therow_id, so each entry carries that number — so a spreadsheet laid out like the paper form (names and amounts filled, "Check #" and "Note" blank) is the whole definition. Types are guessed from the header:Amount/$→ money,Date→ date,Paid?→ checkbox,Method (Check|Cash|Zelle)→ dropdown;reg_no,badge_idand other id-like headers stay text.snake_caseheaders become readable labels, and the first name-like column becomes the bold headline on the phone. Or edit the JSON directly. - Inputs: check what was guessed. Everything is optional unless you mark it
"required": true. The Examples button loads a whole sheet to start from. - Optionally set Available from / until — see Availability.
- Save. Copy the collector link and the PIN and hand them out. Or click Print.
Come back any time to see the Entries table, download a CSV, clear all entries, or close the sheet. A closed sheet stays readable to everyone who has the PIN; it just stops accepting changes.
row_id. Loading a new paste regenerates the ids and the admin will warn you. Adding rows at the end with fresh ids is fine.JSON reference
columns — what each row shows
[
{ "key": "name", "label": "Name 姓名", "type": "text" },
{ "key": "amount", "label": "Amount 金額", "type": "money" }
]
The column with "headline": true (else the first) is the bold headline on the phone. Types: text, number, money, date.
rows — the pre-loaded data
[
{ "row_id": "r001", "name": "張三", "amount": 150, "ref": "abc123" },
{ "row_id": "r002", "name": "李四", "amount": 300 }
]
Keys match columns[].key. Anything extra (like ref) is kept and shown nowhere — handy for a registration id you will match against later.
inputs — what collectors fill in
[
{ "key": "check_no", "label": "Check #", "type": "text", "placeholder": "e.g. 1042" },
{ "key": "paid_amount", "label": "Paid", "type": "money", "placeholder": "only if different" },
{ "key": "method", "label": "Method", "type": "select", "options": ["Check", "Cash", "Zelle"] },
{ "key": "present", "label": "Present", "type": "checkbox" },
{ "key": "note", "label": "Note", "type": "text", "required": false }
]
| type | on the phone | stored as |
|---|---|---|
text | text box | string |
number | numeric keypad | number |
money | numeric keypad with $ | number (dollars) |
date | date picker | YYYY-MM-DD |
select | dropdown of options | the chosen string |
checkbox | big checkbox | true, or omitted |
placeholder is the grey hint inside the box; the importer always writes the key, defaulting it to the label, for you to refine. Labels are plain strings — write both languages in one if your collectors read both. Blank inputs are simply omitted from what is stored; a blank "Paid amount" means "paid what the row says" and that is for you to interpret when you process it.
Availability
Three independent switches decide whether collectors can write. Any one of them off means view only; the list and everything entered stay visible.
- Status — Open / Closed. Flip it by hand.
- Available from — collectors see "opens on …" until then.
- Available until — collectors see "closed on …" afterwards. Picking a day sets 23:59 that day, so "until Sunday" includes Sunday.
Set the window when you make the sheet and you never have to remember to close it. The phone shows the window under the title so collectors know.
Paper
Print on the admin page (or print.html?id=…) renders the same sheet as a table: the columns, then one blank column per input, then "Entered by". Tick Show entered values to print what was collected instead — a tidy record for the file.
PIN and safety
A sheet is a list of names and amounts, or dishes, or a roll — the kind of thing that is already on a clipboard by the door. The protection is sized to that:
- The link contains a random 15-character id that cannot be guessed or listed. The PIN is a second lock for a forwarded link.
- The PIN can read one sheet and write entries on it. It can never change the sheet itself — the rows, the amounts, the inputs. Only a signed-in staff account can.
- The worst a leaked PIN allows is bogus entries, which staff clear in one click — and the plan was always to process entries by hand within a day.
- PINs belong to the program, not the sheet, and the program record is staff-only — so nobody with a PIN can read any PIN. Change one any time; collectors will be asked for the new one. An optional Manager PIN opens the sheets the same way — give it to the person in charge so rotating the collectors' PIN never locks them out.
Do not put anything in a sheet that a stranger must never see. Put an opaque id in ref instead and look it up staff-side.
FAQ
Can two people collect at once? Yes. Each row holds one entry; the last save wins.
Someone paid part of the amount. Give the sheet a paid_amount input. Collectors fill it only when it differs from the row. You reconcile.
Someone paid twice / on two days. One entry per row — write it in the note, or process the first one and clear the entry.
Can I reuse a sheet next year? Better to make a new one from the new list. Old sheets can stay closed forever; storage is nothing and "what did the list say at the time" is exactly the question you will ask.
Where does the data go? Nowhere on its own. Read it in the admin, download the CSV, and do the next step yourself — that is the point.
表單
一份預先填好的名單,加上幾個要填的空格。手機上的記錄板——不是試算表。
是什麼
名單您已經有了——誰報了名、該繳多少,聚餐需要哪些菜,班上有誰。還不知道的是門口發生的事:收到哪張支票、誰認領了沙拉、誰來了。表單就是那份名單,預先載入,加上您想填的空格。
工作人員建立一次。收集人打開連結、輸入密碼、點名字、填空格。所有輸入的內容集中在一處,工作人員以表格或 CSV 讀回,接下來的事手動處理——把收款對上報名、算菜的數量、點名。不做任何計算,不同步到任何地方;它取代的是紙本表格和重新打字,不是您的判斷。
同一份定義也能印成紙本表格,給偏好紙本的人。
收集——手機端
- 打開收到的連結,輸入密碼。密碼只保留在這個瀏覽器分頁;勾選「在此裝置記住密碼 7 天」下次就不用再輸入。底部的「更換或清除密碼」會清掉它。
- 找到那一行——捲動,或在搜尋框輸入名字的一部分。
- 點它。填上您手上的資料,空著也沒關係。點儲存。
- 該行變綠並打勾,顯示您填的內容。再點一次可修改;清除記錄會清掉填寫的內容——名單上的這一行會保留。
- 名單上沒有的人?若表單允許,底部有「+ 新增名單上沒有的人」。您需要替他填每一欄。
多人可以同時在同一份表單收集;回到列表時會自動更新。每行只有一筆記錄——若兩支手機儲存同一行,後儲存的會蓋掉先前的。
記錄人是選填。填一次就會記住;有疑問時工作人員知道該問誰。
工作人員——建立表單
- 用平常的店家帳號登入管理頁,點「+ 新表單」。
- 選一個計畫——共用密碼的一組表單(一個營會、一個班級)。還沒有計畫?就地選「+ 新計畫…」,填名稱和密碼。計畫和密碼在頁首的「計畫」管理。
- 填標題;如果收集人需要,加一行說明(「支票抬頭 CCIC」)。
- 從試算表貼上(CSV 或 TSV,第一行是標題):直接從 Excel 或 Google 試算表複製儲存格,按「載入」。有資料的標題成為顯示欄;整欄空白的標題成為填寫欄位;第一個值全部不重複的欄(如
reg_no)作為row_id,每筆記錄就帶著那個編號——所以像紙本表格那樣排的試算表(姓名、金額填好,「支票號」「備註」留空)就是完整定義。類型由標題判斷:金額/$→ 金額,日期→ 日期,結尾「?」→ 勾選框,方式 (支票|現金|Zelle)→ 下拉選單;reg_no、badge_id等編號類標題維持文字。snake_case標題會轉成可讀的標籤,第一個名字類的欄成為手機上的粗體標題。也可以直接編輯 JSON。 - 填寫欄位:檢查判斷結果。除非標示
"required": true,否則都是選填。「範例」按鈕可載入整份表單作為起點。 - 可設定開放開始 / 截止——見開放時間。
- 儲存。複製收集連結和密碼交出去;或點「列印」。
隨時回來查看記錄表格、下載 CSV、清除全部記錄,或關閉表單。關閉的表單對持有密碼的人仍可查看,只是不再接受修改。
row_id。重新貼上會重新產生編號,管理頁會提醒。在末尾加上新編號的行沒有問題。JSON 參考
columns——每行顯示什麼
[
{ "key": "name", "label": "Name 姓名", "type": "text" },
{ "key": "amount", "label": "Amount 金額", "type": "money" }
]
標有 "headline": true 的欄(否則第一欄)是手機上的粗體標題。類型:text、number、money、date。
rows——預先載入的資料
[
{ "row_id": "r001", "name": "張三", "amount": 150, "ref": "abc123" },
{ "row_id": "r002", "name": "李四", "amount": 300 }
]
鍵對應 columns[].key。其他屬性(如 ref)會保留但不顯示——適合放之後要對照的報名編號。
inputs——收集人要填什麼
[
{ "key": "check_no", "label": "支票號", "type": "text", "placeholder": "例如 1042" },
{ "key": "paid_amount", "label": "實收", "type": "money", "placeholder": "與名單不同時才填" },
{ "key": "method", "label": "方式", "type": "select", "options": ["支票", "現金", "Zelle"] },
{ "key": "present", "label": "出席", "type": "checkbox" },
{ "key": "note", "label": "備註", "type": "text" }
]
| 類型 | 手機上 | 儲存為 |
|---|---|---|
text | 文字框 | 字串 |
number | 數字鍵盤 | 數字 |
money | 數字鍵盤,帶 $ | 數字(美元) |
date | 日期選擇 | YYYY-MM-DD |
select | options 下拉選單 | 選中的字串 |
checkbox | 大勾選框 | true,或省略 |
placeholder 是欄位裡的灰色提示;匯入時一定會寫上這個鍵,預設為標籤,供您修改。標籤是純文字——若收集人讀雙語,把兩種語言寫在同一個標籤裡。空白的欄位不會儲存;「實收」留空代表「照名單上的金額」,如何解讀由您處理時決定。
開放時間
三個獨立的開關決定收集人能否填寫。任一關閉即為僅供查看;名單和已填內容仍可見。
- 狀態——開放 / 已關閉。手動切換。
- 開放開始——在此之前收集人看到「將於 … 開放」。
- 開放截止——在此之後看到「已於 … 截止」。選日期即為當天 23:59,所以「到週日」包含週日。
建立時就設好時間,就不必記得回來關閉。手機在標題下顯示開放時間。
紙本
管理頁的「列印」(或 print.html?id=…)把同一份表單排成表格:各欄,然後每個填寫欄位一個空白欄,最後「記錄人」。勾選「顯示已填內容」則印出收集結果——歸檔用。
密碼與安全
表單是名字和金額、菜色或點名單——本來就放在門口記錄板上的東西。保護程度與此相稱:
- 連結含 15 字元隨機編號,無法猜測或列舉。密碼是連結被轉傳時的第二道鎖。
- 密碼可以讀一份表單並寫記錄。永遠無法更改表單本身——行、金額、欄位。只有登入的工作人員帳號可以。
- 密碼外洩最壞的結果是假記錄,工作人員一鍵清除——而且本來就打算一天內手動處理。
- 密碼屬於計畫而不是表單,而計畫記錄只有工作人員能讀——所以持有密碼的人讀不到任何密碼。隨時可以換;收集人會被要求輸入新密碼。可另設負責人密碼,同樣能打開表單——交給負責人,更換收集人密碼時就不會把負責人鎖在外面。
不要在表單裡放陌生人絕對不能看的東西。改放不透明的 ref 編號,在工作人員端查。
常見問題
可以多人同時收集嗎?可以。每行一筆記錄,後儲存的為準。
有人只付了部分金額。給表單加一個 paid_amount 欄位,收集人只在與名單不同時填。您來對帳。
有人付了兩次 / 分兩天付。每行一筆記錄——寫在備註,或先處理第一筆再清除記錄。
明年可以重用嗎?最好用新名單建新表單。舊表單可以永遠關著放;儲存不花錢,「當時名單是什麼」正是您以後會問的問題。
資料會去哪裡?哪裡都不去。在管理頁讀、下載 CSV,下一步自己做——這正是重點。