Skip to main content

useJobForm

useJobForm(input: UseJobFormProps): HookLoadingResult | UseJobFormReady

Headless hook for creating or updating an employee's job — title, hire date, S-Corp 2% shareholder flag, and Washington state workers' compensation fields.

Remarks

Companion hook to useCompensationForm. Jobs and their compensations are separate entities in the Gusto API and this hook focuses exclusively on the job side. Presence of jobId selects the verb:

Hook configModeAPI call
{ employeeId, jobId }updatePUT /v1/jobs/:jobId (with version)
{ employeeId } (no jobId)createPOST /v1/employees/:employeeId/jobs
{} + submit employeeIdcreatePOST /v1/employees/:options.employeeId/jobs

Creating a job auto-creates a stub compensation. To update the stub in the same flow, capture currentCompensationUuid (and the compensation's version from compensations[]) from the create response and thread them into useCompensationForm.actions.onSubmit({ jobId, compensationId, compensationVersion }).

When the primary job's hireDate changes, secondary compensation effective dates are corrected after the PUT; isPending stays true through that.

Example

Example
import { useJobForm, SDKFormProvider } from '@gusto/embedded-react-sdk'

function JobForm({ employeeId }: { employeeId: string }) {
const job = useJobForm({ employeeId })
if (job.isLoading) return null

const { Fields } = job.form
return (
<form onSubmit={e => { e.preventDefault(); job.actions.onSubmit() }}>
<SDKFormProvider formHookResult={job}>
{Fields.Title && <Fields.Title label="Job title" />}
{Fields.HireDate && <Fields.HireDate label="Hire date" />}
{Fields.TwoPercentShareholder && (
<Fields.TwoPercentShareholder label="2% S-Corp shareholder" />
)}
</SDKFormProvider>
<button type="submit" disabled={job.status.isPending}>Save</button>
</form>
)
}

Props

UseJobFormProps

Configuration options for useJobForm.

Remarks

Presence or absence of jobId selects the API verb — see the jobId field description. employeeId is optional so the hook can be composed alongside an employee-creation step; supply it at submit time via JobSubmitOptions.employeeId in that case.

PropertyTypeDescription
defaultValues?Partial<JobFormData>Pre-fill form values. Server data takes precedence on update mode.
employeeId?stringUUID of the employee whose job is being created or edited. May be omitted when the employee is created in the same submit chain — supply the value via JobSubmitOptions.employeeId at submit time.
jobId?stringPresent → update mode (PUT /v1/jobs/:id with version). Omitted → create mode (POST /v1/employees/:id/jobs).
optionalFieldsToRequire?JobOptionalFieldsToRequireOverride fields that are optional on a given mode to be required. See JobOptionalFieldsToRequire.
shouldFocusError?booleanAuto-focus the first invalid field on submit. Set to false when using composeSubmitHandler so submit-time focus is coordinated across multiple forms. Defaults to true.
validationMode?"onChange" | "onBlur" | "onSubmit" | "onTouched" | "all"Passed through to react-hook-form. Defaults to 'onSubmit'.
withHireDateField?booleanWhen false, hides Fields.HireDate (becomes undefined) and removes hireDate from schema validation. Supply the value via JobSubmitOptions.hireDate at submit time, or rely on the loaded job's existing value on update. Use this when the date is driven by external context rather than user input (e.g. the employee's startDate). Defaults to true.
withTitleField?booleanWhen false, hides Fields.Title (becomes undefined), removes title from schema validation, and skips sending title on PUT/POST. Use this when another form owns the title field — e.g. compensation edit surfaces render the title via CompFields.Title because title lives on compensation in the API (job.title is just a denormalized snapshot of the primary comp's title). Defaults to true so the standalone job-creation flow still gathers a title for the create body.

Returns

HookLoadingResult | UseJobFormReady

A HookLoadingResult while data is loading, or a UseJobFormReady once ready.

UseJobFormResult

UseJobFormResult = HookLoadingResult | UseJobFormReady

Discriminated union returned by useJobForm.

Remarks

Branch on isLoading to narrow to either HookLoadingResult or UseJobFormReady.


UseJobFormReady

Ready-state shape returned by useJobForm once data has loaded.

Remarks

Discriminated by isLoading: false. Extends BaseFormHookReady with the job-specific data, status, actions, and form.Fields shape.

PropertyTypeDescription
actionsobjectSubmit actions exposed by the hook.
actions.onSubmit(options?: JobSubmitOptions) => Promise<HookSubmitResult<Job> | undefined>Validates the form, runs the appropriate create/update mutation, and resolves to a HookSubmitResult containing the saved job. Resolves to undefined on validation failure or mutation error.
dataobjectJob-specific data payload: the loaded job (if any), the employee's other jobs, the employee record, the active work address, and presentation flags for conditional fields.
data.currentJobJob | nullThe job row loaded for update; null in create mode.
data.currentWorkAddressEmployeeWorkAddress | nullThe employee's active work address, or null when none is set.
data.employeeEmployee | nullThe loaded employee record, or null when employeeId was omitted.
data.jobsJob[] | undefinedAll jobs for the employee, when employeeId is set. Useful for screen-level cross-checks across jobs.
data.showStateWcbooleanTrue when the active work-address state is WA; use this to decide whether to render StateWcCovered. Fields.StateWcClassCode is additionally gated on stateWcCovered === true, so most callers only need to check Fields.StateWcCovered / Fields.StateWcClassCode truthiness rather than this flag directly.
data.showTwoPercentShareholderbooleanTrue when the company is taxable as an S-Corp; use this to decide whether to render TwoPercentShareholder.
errorHandlingHookErrorHandlingError state and recovery actions.
formobjectForm bindings: pre-bound field components, per-field metadata, submission values, and react-hook-form internals.
form.FieldsJobFormFields-
form.fieldsMetadataJobFieldsMetadata-
form.getFormSubmissionValues() => JobFormData | undefined-
form.hookFormInternalsHookFormInternals<JobFormData>-
isLoadingfalseAlways false in this branch; discriminates from HookLoadingResult.
statusobjectSubmission state. isPending is true while any in-flight mutation (including the secondary-compensation correction block) hasn't settled. mode reflects whether the next submit will create or update.
status.isPendingboolean-
status.mode"create" | "update"-

Fields

JobFormFields

Pre-bound field components exposed on useJobForm().form.Fields.

Remarks

Each property is either the field component or undefined. A field is undefined when conditions for rendering it aren't met — see each member for its visibility rule. Always null-check conditional fields (e.g. {Fields.TwoPercentShareholder && <Fields.TwoPercentShareholder ... />}) before rendering.

PropertyTypeDescription
HireDateComponentType<HireDateFieldProps> | undefinedBound to hireDate. Hire date picker. undefined when withHireDateField: false.
StateWcClassCodeComponentType<StateWcClassCodeFieldProps> | undefinedBound to stateWcClassCode. Washington state workers' compensation risk class code select. undefined when the active work address is not in Washington or when stateWcCovered is false.
StateWcCoveredComponentType<StateWcCoveredFieldProps> | undefinedBound to stateWcCovered. Washington state workers' compensation coverage radio group. undefined when the active work address is not in Washington (see data.showStateWc).
TitleComponentType<JobTitleFieldProps> | undefinedBound to title. Job title text input. undefined when withTitleField: false.
TwoPercentShareholderComponentType<TwoPercentShareholderFieldProps> | undefinedBound to twoPercentShareholder. S-Corp 2% shareholder checkbox. undefined when the company is not taxable as an S-Corp (see data.showTwoPercentShareholder).

HireDate

Bound to hireDate. Hire date picker. undefined when withHireDateField: false.

{form.Fields.HireDate && (
<form.Fields.HireDate
label="Hire date"
validationMessages={{ REQUIRED: '…' }}
/>
)}

HireDateFieldProps

HookFieldProps<DatePickerHookFieldProps<JobRequiredValidation>>

Props accepted by useJobForm's Fields.HireDate component.

PropertyTypeDescription
labelstringVisible label rendered above the field.
FieldComponent?ComponentType<DatePickerProps>Replaces the default date picker UI component; must accept the same props as DatePickerProps.
validationMessages?ValidationMessages<JobRequiredValidation>Custom error text keyed by validation error code.

Also accepts description, formHookResult, maxDate, minDate, portalContainer from DatePickerHookFieldProps.


StateWcClassCode

Bound to stateWcClassCode. Washington state workers' compensation risk class code select. undefined when the active work address is not in Washington or when stateWcCovered is false.

{form.Fields.StateWcClassCode && (
<form.Fields.StateWcClassCode
label="State wc class code"
validationMessages={{ REQUIRED: '…' }}
/>
)}

StateWcClassCodeFieldProps

HookFieldProps<SelectHookFieldProps<JobRequiredValidation, WARiskClassCode>>

Props accepted by useJobForm's Fields.StateWcClassCode component.

PropertyTypeDescription
labelstringVisible label rendered above the field.
placeholderstringPlaceholder text displayed when no option is selected. Required so empty dropdowns always communicate the action — pass an empty string only when a default value is guaranteed.
FieldComponent?ComponentType<SelectProps>Replaces the default select UI component; must accept the same props as SelectProps.
getOptionLabel?(entry: WARiskClassCode) => stringMaps a raw option entry to its display label; when omitted, options use the labels provided by the hook.
validationMessages?ValidationMessages<JobRequiredValidation>Custom error text keyed by validation error code.

Also accepts description, formHookResult, portalContainer from SelectHookFieldProps.


StateWcCovered

Bound to stateWcCovered. Washington state workers' compensation coverage radio group. undefined when the active work address is not in Washington (see data.showStateWc).

{form.Fields.StateWcCovered && (
<form.Fields.StateWcCovered label="State wc covered" />
)}

StateWcCoveredFieldProps

HookFieldProps<RadioGroupHookFieldProps<never, boolean>>

Props accepted by useJobForm's Fields.StateWcCovered component.

PropertyTypeDescription
labelstringVisible label rendered above the field.
FieldComponent?ComponentType<RadioGroupProps>Replaces the default radio group UI component; must accept the same props as RadioGroupProps.
getOptionLabel?(entry: boolean) => stringMaps a raw option entry to its display label; when omitted, options use the labels provided by the hook.

Also accepts description, formHookResult from RadioGroupHookFieldProps.


Title

Bound to title. Job title text input. undefined when withTitleField: false.

{form.Fields.Title && (
<form.Fields.Title
label="Title"
validationMessages={{ REQUIRED: '…' }}
/>
)}

JobTitleFieldProps

HookFieldProps<TextInputHookFieldProps<JobRequiredValidation>>

Props accepted by useJobForm's Fields.Title component.

PropertyTypeDescription
labelstringVisible label rendered above the field.
FieldComponent?ComponentType<TextInputProps>Replaces the default text input UI component; must accept the same props as TextInputProps.
validationMessages?ValidationMessages<JobRequiredValidation>Custom error text keyed by validation error code.

Also accepts description, formHookResult, placeholder, transform from TextInputHookFieldProps.


TwoPercentShareholder

Bound to twoPercentShareholder. S-Corp 2% shareholder checkbox. undefined when the company is not taxable as an S-Corp (see data.showTwoPercentShareholder).

{form.Fields.TwoPercentShareholder && (
<form.Fields.TwoPercentShareholder label="Two percent shareholder" />
)}

TwoPercentShareholderFieldProps

HookFieldProps<CheckboxHookFieldProps>

Props accepted by useJobForm's Fields.TwoPercentShareholder component.

PropertyTypeDescription
labelstringVisible label rendered above the field.
FieldComponent?ComponentType<CheckboxProps>Replaces the default checkbox UI component; must accept the same props as CheckboxProps.

Also accepts description, formHookResult from CheckboxHookFieldProps.

Validations

JobRequiredValidation

JobRequiredValidation = "REQUIRED"

The validation error code a useJobForm field can produce.

Remarks

Currently a single literal — 'REQUIRED' — surfaced as the key in validationMessages on each Fields.* component. Future schema additions may extend the union.

Utility types

JobErrorCode

JobErrorCode = "REQUIRED"

Union of every error code produced by the useJobForm schema.


JobErrorCodes

const JobErrorCodes: object

Validation error codes produced by the useJobForm schema.

Remarks

Use these constants as the keys in a field's validationMessages prop to map an error code to a user-facing message.

Example

import { JobErrorCodes } from '@gusto/embedded-react-sdk'

<Fields.Title
label="Job title"
validationMessages={{ [JobErrorCodes.REQUIRED]: 'Job title is required' }}
/>

Type Declaration

NameType
REQUIRED"REQUIRED"

JobFieldsMetadata

FieldType
hireDateFieldMetadata
stateWcClassCodeFieldMetadataWithOptions<WARiskClassCode>
stateWcCoveredFieldMetadataWithOptions<boolean>
titleFieldMetadata
twoPercentShareholderFieldMetadata

Shape of the per-field metadata exposed at useJobForm().form.fieldsMetadata.

Remarks

Maps each field name in JobFormData to its presentation metadata — including the registered name, whether the field is required or disabled, and (for select-like fields) the option list.


JobFormData

Shape of the form values managed by useJobForm.

Remarks

Accepted as defaultValues on useJobForm and returned by form.getFormSubmissionValues() once the form has validated. hireDate is an ISO date string (YYYY-MM-DD) or null; stateWcCovered is a boolean even though the radio group surfaces 'true' / 'false' strings during input (the schema preprocessor coerces them).

Properties

PropertyTypeDescription
hireDatestring | nullThe employee's hire date as an ISO 8601 string (YYYY-MM-DD), or null if unknown.
stateWcClassCodestringWashington state workers' compensation risk-class code. Required when stateWcCovered is true.
stateWcCoveredbooleanWhether the employee is covered under Washington state workers' compensation insurance.
titlestringThe employee's job title (e.g. "Software Engineer").
twoPercentShareholderbooleanWhether the employee owns 2 % or more of an S-corporation. Affects benefit-deduction tax treatment.

JobOptionalFieldsToRequire

Override which fields are required on a given submission mode of useJobForm.

Remarks

Each mode key lists the fields that are optional by default for that mode but should be promoted to required. stateWcClassCode is automatically required when stateWcCovered is true and is not configurable here.

FieldRequired on createRequired on updateConfigurable?
titleYesNoYes (on update)
hireDateYesNoYes (on update)
twoPercentShareholderNoNoYes (either mode)
stateWcCoveredNoNoYes (either mode)
stateWcClassCodeWhen WC is coveredWhen WC is coveredNo (auto)

Example

const job = useJobForm({
employeeId,
jobId,
optionalFieldsToRequire: {
update: ['title', 'hireDate'],
},
})

Properties

PropertyTypeDescription
create?("stateWcClassCode" | "twoPercentShareholder" | "stateWcCovered")[]Fields that can be required in create mode
update?("title" | "hireDate" | "stateWcClassCode" | "twoPercentShareholder" | "stateWcCovered")[]Fields that can be required in update mode

JobSubmitOptions

Optional values supplied to useJobForm's actions.onSubmit at submit time.

Remarks

Use these when a value isn't sourced from a rendered field — typically because the hook was configured with withHireDateField: false, or because the employee being saved was created in the same submit chain and the employeeId wasn't known at hook construction.

Properties

PropertyTypeDescription
employeeId?stringOverride the employeeId configured at hook construction. Useful when the employee is created in the same submit chain.
hireDate?stringSupply hireDate at submit time rather than via a rendered field. Use with withHireDateField: false for screens that derive hireDate from external context (e.g. the employee's startDate during onboarding). Falls back to the loaded job's hireDate on update mode when omitted; required (or sourced from a default) on create mode.

Endpoints