| name | field-service-data-capture-reference-configure |
| description | Build, edit, and deploy Salesforce Data Capture Flows (processType DataCaptureFlow) — Field Service mobile / offline forms. Use when authoring flow-meta.xml with runtime_service_fieldservice:dc* components, Repeater loops (.AllItems), master-detail child record persistence, visual polish (gradient banners, progress bars, callouts), supporting objects with FLS/permsets, debugging DataCaptureFlow deploy errors, or troubleshooting why a deployed form doesn't appear on the FSL Mobile Forms tab (DDC/WorkPlan OWD + AssignedResource sharing prerequisites). |
| user-invocable | false |
| metadata | {"version":"1.0","domains":["Field Service"],"cliTools":[{"tool":"[Truncated]","semver":">=3.9.0"},{"tool":"[Truncated]","semver":">=2.0.0"}]} |
Querying Fs Data Capture Reference
When to Use This Skill
Build, edit, and deploy Salesforce Data Capture Flows (processType DataCaptureFlow) — Field Service mobile / offline forms. Use when authoring flow-meta.xml with runtime_service_fieldservice:dc* components, Repeater loops (.AllItems), master-detail child record persistence, visual polish (gradient banners, progress bars, callouts), supporting objects with FLS/permsets, debugging DataCaptureFlow deploy errors, or troubleshooting why a deployed form doesn't appear on the FSL Mobile Forms tab (DDC/WorkPlan OWD + AssignedResource sharing prerequisites).
Workflow
Salesforce Data Capture Flow Skill
Build, edit, and deploy Salesforce Flows with processType: DataCaptureFlow (Field Service mobile / offline forms).
Required metadata (every flow)
<processType>DataCaptureFlow</processType>
<areMetricsLoggedToDataCloud>false</areMetricsLoggedToDataCloud>
<environments>Offline</environments>
Optional IsLlmTargetable custom property — if you include it, it must be a JSON string, not a boolean:
<customProperties>
<name>IsLlmTargetable</name>
<value><stringValue>{"value":"false"}</stringValue></value>
</customProperties>
The <booleanValue>false</booleanValue> form deploys but blocks activation — error: The value of the IsLlmTargetable custom property's value field must be a string in JSON format. Omitting the property entirely is also fine.
XML structure rules
Salesforce's Flow schema enforces grouping — all elements of the same type must appear in a single contiguous block. Deploy fails with Element X is duplicated at this location when violated.
Group order doesn't matter, but within each group elements must be adjacent:
- all
<choices> together
- all
<dynamicChoiceSets> together
- all
<screens> together
- all
<decisions> together
- all
<recordLookups> together
- all
<recordCreates> together
- all
<recordUpdates> together
- all
<loops> together
- all
<assignments> together
- all
<variables> together
Connector references determine execution order, not XML order.
Component reference
All extensions: prefix runtime_service_fieldservice:
| Component | Extension | fieldType |
|---|
| Short Text | dcTextInput | ComponentInstance |
| Long Text | dcLongText | ComponentInstance |
| Email | dcEmail | ComponentInstance |
| Phone | dcPhone | ComponentInstance |
| Name | dcName | ComponentInstance |
| Numeric | dcNumeric | ComponentInstance |
| Counter | dcCounter | ComponentInstance |
| Date | dcDate | ComponentInstance |
| Date & Time | dcDateTime | ComponentInstance |
| Checkbox | dcCheckbox | ComponentInstance |
| Toggle | dcToggle | ComponentInstance |
| Address / GPS | dcAddress | ComponentInstance |
| Lookup | dcLookup | ComponentInstance |
| Static image | dcFileView | ComponentInstance |
| Upload image (mobile) | dcUpImage | ComponentInstance |
| Upload file (mobile) | dcUpFile | ComponentInstance |
| Signature (mobile) | dcSignature | ComponentInstance |
| Picklist single | dcPicklist | ComponentChoice |
| Picklist multi | dcPicklist | ComponentMultiChoice |
| Radio buttons | dcRbGroup | ComponentChoice |
| Checkbox group | dcCbGroup | ComponentMultiChoice |
| Matrix | dcMatrix | ComponentMultiChoice |
| Display text | (none) | DisplayText |
| Section | (none) | RegionContainer + Region |
| Repeater | (none) | Repeater |
Note: <fieldType>Range</fieldType> is NOT a valid slider fieldType in DataCaptureFlow (despite "Range/Slider" appearing in Builder UI lists). Sliders aren't available as pure metadata in this process type — use dcNumeric or dcCounter. forceContent:repeater (Lightning generic) ≠ <fieldType>Repeater</fieldType> (FSL offline). They share a concept, not XML.
Setting the label
| fieldType | How |
|---|
ComponentInstance | <inputParameters><name>label</name><value><stringValue>…</stringValue></value></inputParameters> |
ComponentChoice / ComponentMultiChoice | <fieldText>Label</fieldText> |
DisplayText | <fieldText>HTML</fieldText> |
All ComponentInstance extensions (including dcAddress and dcToggle) accept the label inputParameter — no wrapping DisplayText needed.
Required flag
Every input field needs <isRequired>true/false</isRequired> at field level. That single flag is sufficient for every dc* component — no extra required / isRequired inputParameter is needed.
dcLookup additionally accepts an isRequired inputParameter (boolean), but the field-level <isRequired> drives enforcement.
dcCheckbox and dcToggle accept <isRequired>true</isRequired> syntactically but don't enforce it at runtime.
Every input field must also have
<inputsOnNextNavToAssocScrn>UseStoredValues</inputsOnNextNavToAssocScrn>
<storeOutputAutomatically>true</storeOutputAutomatically>
<styleProperties>
<verticalAlignment><stringValue>top</stringValue></verticalAlignment>
<width><stringValue>12</stringValue></width>
</styleProperties>
Exception: <fieldType>Repeater</fieldType> explicitly rejects storeOutputAutomatically ("the storeOutputAutomatically field isn't supported"). Repeater output is always available as .AllItems — no opt-in needed.
Screen rules
Every screen needs ALL THREE of these or the Next/Finish button won't render:
<allowFinish>true</allowFinish> (even on non-final screens)
<showFooter>true</showFooter>
<nextOrFinishButtonLabel>Next</nextOrFinishButtonLabel>
Plus:
- First element after
<start> must always be a <screens> element
- All
<screens> elements must be grouped together in the XML
Repeater — iterating rows and creating child records
The Repeater's output collection is exposed as .AllItems. Confirmed working on API v66.
<fields>
<name>MyRepeater</name>
<fieldType>Repeater</fieldType>
<fields>
<name>Row_PartName</name>
<extensionName>runtime_service_fieldservice:dcTextInput</extensionName>
<fieldType>ComponentInstance</fieldType>
<storeOutputAutomatically>true</storeOutputAutomatically>
</fields>
<fields>
<name>Row_PartQty</name>
<extensionName>runtime_service_fieldservice:dcCounter</extensionName>
<fieldType>ComponentInstance</fieldType>
<storeOutputAutomatically>true</storeOutputAutomatically>
</fields>
<isRequired>false</isRequired>
</fields>
<loops>
<name>Loop_Parts</name>
<collectionReference>MyRepeater.AllItems</collectionReference>
<iterationOrder>Asc</iterationOrder>
<nextValueConnector>
<targetReference>Create_Part</targetReference>
</nextValueConnector>
</loops>
<recordCreates>
<name>Create_Part</name>
<object>CustomFormPart__c</object>
<connector>
<targetReference>Loop_Parts</targetReference>
</connector>
<inputAssignments>
<field>PartName__c</field>
<value>
<elementReference>Loop_Parts.Row_PartName.value</elementReference>
</value>
</inputAssignments>
<inputAssignments>
<field>Quantity__c</field>
<value>
<elementReference>Loop_Parts.Row_PartQty.value</elementReference>
</value>
</inputAssignments>
<storeOutputAutomatically>true</storeOutputAutomatically>
</recordCreates>
Don'ts:
<collectionReference>MyRepeater</collectionReference> → Element "MyRepeater" doesn't exist
<collectionReference>MyRepeater.items</collectionReference> → generic server error
<collectionReference>MyRepeater.data</collectionReference> → generic server error
- Inside the loop body,
MyRepeater.Row_PartName.value won't work — must use the loop's name, not the repeater's name.
Cross-row validation does NOT compile. Formula refs like r_GR4.AllItems[$Items].field.value and r_GR4.AllItems[$Items - 1].field.value fail with Syntax error. Per-row validation works via plain fieldName.value inside the nested field's own validationRule. For cross-row rules, use a post-screen loops + decisions.
Other Repeater accessors don't resolve today. Only .AllItems works. AddedItems, PrepopulatedItems, RemovedItems all fail deploy with doesn't exist.
Prepopulating a Repeater from an existing collection
Bind an existing SObject collection to the Repeater so it renders one pre-filled row per source record. The user can then edit, add, or remove rows before submit.
Pattern: recordLookups (get source collection, getFirstRecordOnly=false, storeOutputAutomatically=true) → screen with Repeater bound via the collection inputParameter → nested fields use SourceCollection[$EachItem].FieldApiName as their value default.
<recordLookups>
<name>Get_Source</name>
<object>ServiceResource</object>
<getFirstRecordOnly>false</getFirstRecordOnly>
<storeOutputAutomatically>true</storeOutputAutomatically>
<connector><targetReference>Screen_Repeater</targetReference></connector>
</recordLookups>
<fields>
<name>accountRepeater</name>
<fieldType>Repeater</fieldType>
<inputParameters>
<name>collection</name>
<value><elementReference>Get_Source</elementReference></value>
</inputParameters>
<fields>
<name>account_info</name>
<fieldType>DisplayText</fieldType>
<fieldText><p>Id: {!Get_Source[$EachItem].Id}</p></fieldText>
</fields>
<fields>
<name>name</name>
<extensionName>runtime_service_fieldservice:dcTextInput</extensionName>
<fieldType>ComponentInstance</fieldType>
<inputParameters>
<name>label</name>
<value><stringValue>Name</stringValue></value>
</inputParameters>
<inputParameters>
<name>value</name>
<value><elementReference>Get_Source[$EachItem].Name</elementReference></value>
</inputParameters>
<isRequired>true</isRequired>
<storeOutputAutomatically>true</storeOutputAutomatically>
<inputsOnNextNavToAssocScrn>UseStoredValues</inputsOnNextNavToAssocScrn>
<styleProperties>…</styleProperties>
</fields>
<isRequired>false</isRequired>
<styleProperties>…</styleProperties>
</fields>
Key points:
- The binding inputParameter is named
collection, not value or source.
- Inside the Repeater, reference a source row via
SourceCollectionName[$EachItem].FieldApiName — use the record-lookup's name, not the Repeater's name. Works in both DisplayText.fieldText (as {!Get_Source[$EachItem].Id}) and in component value defaults (as <elementReference>Get_Source[$EachItem].Name</elementReference>).
$EachItem is the per-row iterator Salesforce injects while rendering the Repeater. It only resolves inside Repeater-nested fields.
- Downstream loops still iterate
Repeater_Name.AllItems as normal — prepopulation changes the input, not the output accessor.
- Prepopulated rows appear as regular
.AllItems entries after submit; there is no PrepopulatedItems / AddedItems split (those accessors fail deploy).
Displaying Repeater entries to the user (post-Repeater Loop screen)
To show the user what they captured (e.g. review / confirmation / per-row detail), put a Loop after the Repeater screen whose body connects to a display screen; the display screen then connects back to the Loop. The end connector of the Loop moves on to the next step.
<loops>
<name>Loop_Through_Repeater</name>
<collectionReference>accountRepeater.AllItems</collectionReference>
<iterationOrder>Asc</iterationOrder>
<nextValueConnector>
<targetReference>Repeater_Output_Screen</targetReference>
</nextValueConnector>
</loops>
<screens>
<name>Repeater_Output_Screen</name>
<connector><targetReference>Loop_Through_Repeater</targetReference></connector>
<fields>
<name>display_info</name>
<fieldType>DisplayText</fieldType>
<fieldText><p>Source Id: {!Loop_Through_Repeater.UniqueField__Id}</p>
<p>Name: {!Loop_Through_Repeater.name.value}</p>