Jobs: forms and resources
Merge selected job table cells
/a/Job_setTableCells
Apply a table-ID and row/field-position patch without replacing other saved table cells.
When to use this endpoint
Use for small table answer edits after reading the current table and its field order. Unspecified cells and tables remain.
Use Job_setTables only when intentionally replacing the entire saved table collection.
Authentication and permissions
Authenticate with signed API-key fields or a logged-in CRM session. The handler performs no additional page or role-permission check.
Job and form IDs refer to the authenticated account. Cross-account writes occur only through the stored outsourcing relationship on the routes that explicitly mirror changes.
The dispatcher also applies account/user and IP restrictions. A CRM session carrying a CSRF token must supply it through X-FMCSRF or _csrf; missing/incorrect tokens can be rejected before this handler runs.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
job_id | Integer string | Yes | Positive physical job ID. |
changes | JSON object string | Yes | Nonempty table-ID map of position-to-value maps, for example {"302":{"0_1":"Passed"}}. Positions are x_y: zero-based row then field index. Native arrays are not accepted by json_decode; inner shape/coordinate bounds are not validated. |
Example request
$result = FM_api('Job_setTableCells', [
'job_id'=>'1042', 'changes'=>json_encode(['302'=>['0_1'=>'Passed']]),
]);
Example response
{"ok":1}
Errors and unusual responses
| Response | Condition |
|---|---|
{"error":"not logged in"} | No authenticated tenant context is available. Invalid signed credentials can be rejected by the dispatcher before the handler runs. |
{"error":"missing or invalid parameter: job_id"} | Job ID is nonpositive. |
{"error":"missing or empty parameter: changes"} | Decoded changes is not an array or is empty. |
{"error":"no such job exists"} | No job row is read. |
{"error":"Unable to save job"} | The primary database save failed. Successful-save history and subsequent follow-ups are not run. |
{"ok":1,"warning":"Job saved; follow-up incomplete. Inspect saved state before retrying.","warnings":["Job_updateCosts: Unable to save job"],"saved":1} | The primary save succeeded, but a recalculation, asset rebuild, notification or outsourced mirror failed. warnings identifies the failed follow-up; any normal response fields remain present. A benign no-change result from a follow-up is not a failure. Read saved state before retrying. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- The job lookup and UPDATE both require an active job. No table-form existence, field type, required-answer or assignee scope is checked.
- Splits each position string on underscore and integer-converts its first two components. Missing rows become arrays and earlier field gaps become empty strings; values are stored as supplied. Supply valid nonnegative, bounded indexes; malformed positions are not a supported error contract.
- Whole stored table JSON is rewritten after merging. Concurrent edits can overwrite each other; there is no version token, paging or batch-size limit.
Side effects
- Unchecked write of subform_values, last_edited and edited_uuid with meetings-cache invalidation and generic job history.
- Calls Job_updateAssetJobs to rebuild derived asset associations and Job_updateCosts to enrich/recalculate resources and prices; follow-up errors produce saved-state warnings. No general outsourced-table mirror or stock-level reconciliation is called.
See it in Fieldmotion
CRM1
Edit a cell on a job’s Tables page. pageJobTables.js batches addressed cells into changes and sends Job_setTableCells. The rate picker also uses this contract for an encoded rate answer.
CRM2
Create a linked child job from a subform field in the job Form. pageJobForm.js sends Job_setTableCells with table ID and rowIndex_fieldIndex mapped to the child ID.
Related endpoints
Job_setTablesreplaces the full saved table collection and refreshes dependencies.Job_tableRowAppendappends rows already in destination field order.Job_updateCostsrefreshes cost/resource snapshots and invokes the price follow-up.