iT邦幫忙

2024 iThome 鐵人賽

DAY 17
0
自我挑戰組

用 ODK 和 Access VBA 打造行動化資料收集流程系列 第 17

Day17:表單邏輯(Form Logic) Part 2

  • 分享至 

  • xImage
  •  

必填項目(Requiring responses)

預設情況下,使用者可以跳過表單中的問題。若要提出必填問題,請在必填 (required )欄位中輸入「yes」。
必填問題在問題標籤左側標有小星號。您可以選擇填寫必填說明訊息欄(required_message),該訊息將顯示給嘗試推進表單而不回答問題的使用者。

type name label required required_message
text name 請問如何稱呼? yes 請務必回答此問題.

設定預設回應(Setting default responses)

若要提供問題的預設答案,請在預設(default )欄位中輸入預設值。預設值是在首次從表單定義建立記錄時設定的。預設值可以是固定值(靜態預設值)或某些表達式的結果(動態預設值)。

注意
媒體問題類型不支援預設值。唯一的例外是圖像(image)可以具有靜態預設值。這對於註釋(annotate)很有用。

靜態預設值

問題內的default (預設)欄位,即可填寫預設值,內容不需使用引號,除非您希望這些引號出現在預設回答中。
在下面的範例中,當問題首次顯示時,將填上預設的「Phone_call」選項,回答問題時,可以保留或更改它。

XLSForm 選擇「Phone_call」作為預設聯絡方式

survey

type name label default
select_one contacts contact_method 我們該如何聯絡您? phone_call

choices

list_name name label
contacts phone_call 打電話
contacts text_message 簡訊
contacts email 電子郵件

動態預設值

如果您將表達式放入問題的default (預設)欄位中,則首次從表單定義建立記錄時,將計算該表達式一次。這允許您使用表單外部的值,例如目前日期或伺服器使用者名稱。
XLSForm 將目前日期設定為預設日期
survey

type name label default
date fever_onset 什麼時候開始發燒的? now()

在下面的範例中,如果在伺服器配置或元資料設定中設定了 username(使用者名稱),則該使用者名稱將用作text問題的預設值。

XLSForm 確認username元數據
survey

type name label default
username username
text confirmed_username 請輸入username ${username}

重複項目中的動態預設值

新增新的重複問題時,將評估重複中的動態預設值。
此技術是使用先前重複實例的值,作為目前重複實例的預設值。例如,您可以使用為上次紀錄的樹,資料內的[樹種]欄位值,作為下一棵樹的[樹種]預設值。

如果您正在收集有關多個實體(例如樹)的數據,則可以選擇使用重複或每個實體使用一個表單記錄。有關做出該決定的更多訊息,請參閱重複問題的內容。如果每個實體使用一個表單記錄,則可以使用上次儲存來獲得與本節中所述相同的行為。

XLSForm 根據最後一個重複實例設定預設值

type name label default
begin_repeat tree Tree
text species 樹種 ${tree}[position() = position(current()/..) - 1]/species

在上面的預設表達式中,${tree} 是對重複的引用。括號中的表達式 [position() =position(current()/..) - 1] 表示過濾可能的樹重複實例列表,僅包含位置比當前重複位置減1的實例。最後,/species 指定應使用重複中的物種問題。這是用於指定問題名稱的 XLSForm 的 ${} 快速語法和原始 XPath 語法的混合搭配。

從表單數據中設置動態預設值

使用調查員填寫的某個值,作為另一個問題的預設值可能會很有幫助,而這個問題將由調查員在稍後填寫。由於動態預設值是在表單或重複項目創建時產生的,而此時尚未填寫任何數據,因此上述動態預設值不能用於這種情況。
您也不能單獨使用計算欄(calculation)來實現這一點,因為計算中的表達式會在表單保存時被評估,並取代調查員所做的任何更改。相反,您需要結合使用計算欄位和觸發欄位(trigger)。觸發欄中的問題引用將確保您的計算只在該引用更改時進行評估。

XLSForm使用當前年齡作為預設診斷年齡

type name label calculation trigger
text name 兒童名稱
integer current_age 兒童年紀
select_one gndr gender 性別
integer diagnosis_age 瘧疾診斷年齡 ${current_age} ${current_age}

在上述例子中,觸發列中的兒童年紀「${current_age}」數值, 意味著當調查員更改「current_age」 問題的值時,「diagnosis_age」 問題的計算將被更新。在這種情況下,這意味著 「current_age」的新值將替換 「diagnosis_age」的值。如果調查員隨後更改 「diagnosis_age」 的值,則該值將被保留,除非 「current_age」 的值再次被更改。

XLSForm如果更新目前年齡,則清除診斷年齡

type name label required calculation trigger
text name 兒童名稱
integer current_age 兒童年紀
select_one gndr gender 性別
integer diagnosis_age 瘧疾診斷年齡 true() '' ${current_age}

在上面的範例中,每當「current_age」問題的值發生變更時,「diagnosis_age」 都會被清除。
如果正在填寫有關已經有一些知識的實體的表單,則這種預設值特別有用。例如,如果您有一份要採訪的人員名單,並且您知道他們的電話號碼,您可能想要使用已知的電話號碼作為預設號碼,並允許普查員根據需要進行更新。

XLSForm 根據選擇查找預設值
survey

type name label calculation trigger choice_filter
select_one participants participant 參與者 true()
text phone_number 電話號碼 instance('participants')/root/item[name=${participant}]/phone_number ${participant}

choices

list_name name label phone_number
participants kwame_onwuachi Kwame Onwuachi +1-850-555-0168
participants sophia_roe Sophia Roe +36 55 562 079

在上面的範例中,當選擇參與者時,他(或她)的電話號碼將作為預設值填入,並且可以根據需要進行更新。如果選定的參與者發生變化,電話號碼將被替換。

注意
上例中 select_one 的 choice_filter 欄位中的 true() 對於能夠找到參與者的電話號碼是必要的。

值變化時觸發計算(Triggering calculations on value change)

只要表達式中的值之一發生變化,就會重新計算計算。例如,如果您的表單包含計算 ${q1} + ${q2},則每當 ${q1} 或 ${q2} 的值發生變更時都會重新計算。
當不參與計算的值發生變化時,也可以觸發計算。這使用與表單資料預設值相同的觸發(trigger )列。它對於觸發涉及非隨機數或時間形式的值的計算特別有用。

輕量級時間戳(Lightweight timestamping)

了解普查員回答問題所花費的時間有助於品質控制和訓練。 ODK Collect 提供審計日誌(audit log,https://docs.getodk.org/form-audit-log/),其中包含有關普查員如何瀏覽表單的豐富資訊。該日誌被捕獲為單獨的文件,分析起來可能很複雜。一個更簡單的替代方案是在特定問題的值發生變化時紀錄時間戳,這類似於開始和結束時間戳的元資料類型。
紀錄上次更新時間戳

type name label calculation trigger
string name 姓名
dateTime name_last_update_time now() ${name}
string life_story 人生故事
dateTime life_story_last_update_time now() ${life_story}

在上面的範例中,只要變更name問題的值,name_last_update_time 欄位就會填入目前時間。
您也可以在計算中使用 if 來記錄第一次被輸入值的時間,爾後再次變更時,時間不會異動:
只記錄首次更新的時間

type name label calculation trigger
string name 姓名
dateTime name_first_update_time if(${name_first_update_time}='', now(), ${name_first_update_time}) ${name}
string life_story 人生故事
dateTime life_story_first_update_time if(${life_story_first_update_time}='', now(), ${life_story_first_update_time}) ${life_story}

上一篇
Day16:表單邏輯(Form Logic) Part 1
下一篇
Day18:表單邏輯(Form Logic) Part 3
系列文
用 ODK 和 Access VBA 打造行動化資料收集流程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言