Snippets: dynamic forms
These are the snippets the console’s Snippets dialog offers under Dynamic forms. Each is TypeScript; in a .js script the console shows the same code with its types removed. Every one runs unchanged in Code Studio’s own tests. How the API they call behaves is in writing scripts and the script API reference.
Required only on a transition
setRequired holds the form until the field is filled. context.view says which form is open: here Resolution notes is required on a transition form and optional elsewhere. The work item view has no required fields, so Code Studio drops it there.
Runs in the browser of whoever fills in the form, not in a run.
export default async function (form, context) { const onTransition = context.view === 'IssueTransition' || context.view === 'IssueTransitionAgentView'; form.field('Resolution notes').setVisible(true).setRequired(onTransition);}Read only unless in a group
setReadOnly shows a field and stops a person changing it on the form. jira.get reads Jira as the person, so the groups are theirs. Read only is a convenience: an automation rule or the REST API can still change the field.
Runs in the browser of whoever fills in the form, not in a run.
export default async function (form) { const me = await jira.get('/rest/api/3/myself', { query: { expand: 'groups' } }); const finance = (me.groups?.items ?? []).some((group) => group.name === 'finance'); form.field('Budget').setReadOnly(!finance).setDescription(finance ? '' : 'Only the finance team changes the budget.');}Fill a default as the form opens
setValue fills a field. As the form opens (form.trigger is init) a value goes only into a field that is empty or still holds what the rule set, so what a person typed is kept. On the work item view a value is saved at once, so there it is set only when a field changes.
Runs in the browser of whoever fills in the form, not in a run.
export default async function (form) { if (form.trigger !== 'init') return; const due = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10); form.field('duedate').setValue(due); form.field('labels').setValue(['triage']);}Show fields by the value of another
form.changed is the field whose change started the run, null as the form opens. Here the cost fields show only for a work type that needs them, and a value left in a hidden field is cleared with clear(). Hiding is not a control: Jira saves a hidden field.
Runs in the browser of whoever fills in the form, not in a run.
export default async function (form) { const category = form.field('Category').value?.value ?? null; const hardware = category === 'Hardware'; for (const name of ['Asset tag', 'Purchase cost']) { const field = form.field(name).setVisible(hardware).setRequired(hardware); if (!hardware && field.value) field.clear(); }}Offer only some choices
setOptionsVisibility shows or hides a select’s choices by their option id, up to 100 at a time; the second argument says which. Here a customer request only offers the two lowest priorities. Read the ids from the field’s options in Jira’s field administration.
Runs in the browser of whoever fills in the form, not in a run.
export default async function (form, context) { if (!context.requestTypeId) return; form.field('priority').setOptionsVisibility(['4', '5'], true);}Rename a field and say what it is for
setName changes the label a person reads and setDescription the help under it, on this form only; the field keeps its name everywhere else. Here per space, from context.projectId.
Runs in the browser of whoever fills in the form, not in a run.
export default async function (form, context) { const hr = context.projectId === '10010'; form.field('Summary').setName(hr ? 'Request title' : 'Summary'); form.field('Description').setDescription(hr ? 'Do not write personal codes or health data here.' : '');}Fill a field from what Jira knows
jira.get reads Jira’s REST API as the person, under /rest/api/3/, /rest/agile/1.0/ or /rest/servicedeskapi/, and nothing else. Here the reporter’s team goes into Team when the form opens, read from their own profile property; with no property, the field stays as it was.
Runs in the browser of whoever fills in the form, not in a run.
export default async function (form, context) { if (form.trigger !== 'init' || !context.accountId) return; try { const team = await jira.get('/rest/api/3/user/properties/team', { query: { accountId: context.accountId } }); if (team?.value) form.field('Team').setValue(String(team.value)); } catch { return; }}Rules for one request type
context.requestTypeId and context.portalId name the request type and portal on a portal request form and on an agent form with a request type chosen; elsewhere they are null. form.has says whether a field is on this form at all.
Runs in the browser of whoever fills in the form, not in a run.
export default async function (form, context) { const laptop = context.requestTypeId === '17'; if (form.has('Delivery address')) form.field('Delivery address').setVisible(laptop).setRequired(laptop); form.field('Description').setDescription(laptop ? 'Say which model and when you need it.' : '');}Read every field on the form
form.fields lists every field the form holds, each with id, name, type, value, visible, required, readOnly and description. Here every empty required field gets a reminder in its description.
Runs in the browser of whoever fills in the form, not in a run.
export default async function (form) { for (const field of form.fields) { const empty = field.value === null || field.value === '' || (Array.isArray(field.value) && field.value.length === 0); if (field.required && empty) field.setDescription('Required before you can create the work item.'); }}Related
A problem or a question? Write to support@oktul.com or open a request in the Help Center (opens in a new tab). Both reach the same service desk, so either way the request gets a reference and an SLA measuring the response.