Breadcrumbs

Custom text formula

The value of this read-only custom field is calculated automatically using a custom text expression.

You can use it to display text that combines information from one or more fields (using field codes).

It also lets you create any custom text based on values from:

  • fields in the current work item, or

  • fields in other work items (for example: linked issues, sub-tasks, epics, stories, or issues selected via JQL).

Create a custom text formula field

Choose the template

Just like for any other formula field, follow the steps outlined here: Create and configure formula fields and select the Custom text formula field template in the field creation assistant.

Screenshot-2025-08-25_11h-38m.jpg

Once selected click on Next.


Provide the expression

Creating an expression from scratch might feel like a challenge, especially if you are not familiar with our expression editor (known from our app Jira Workflow Toolbox). But we have you covered!

Either start by looking at the built-in example expressions or browse through the use cases and examples we have collected for you at the bottom of this page.


Preview the output

Once you have provided the expression you can preview and validate the output by selecting an existing work item.

image-20250825-095943.png

Even if you don’t have the option to individually customize the display format (yet), you can choose to display emojis instead of just plain text just like in the example above RAG - due date traffic light.


📚 Use cases and examples

Use case

Parsing mode

Expression

Earliest date and time from linked work items

Jira expression

let minDate = issue?.links.map(link => link.linkedIssue.customfield_nnnnn).filter( d => d != null); minDate.length > 0 ? new Date(minDate.reduce((a, b) => a < b ? a : b )).toString() : ""

Earliest date from linked work items

Jira expression

let minDate = issue?.links.map(link => link.linkedIssue.customfield_nnnnn).filter( d => d != null); minDate.length > 0 ? new CalendarDate(minDate.reduce((a, b) => a < b ? a : b )).toString() : ""

Field value validation

General

%{matches(%{issue.cfnnnnn},"6|7|8|9") ? "Valid":"Invalid"}

Historical due dates

Jira expression

issue.changelogs.filter(changelog => changelog.items.some(item => item.fieldId == 'duedate' && item.from != null)).map( changelog => {duedateentry: changelog.items.filter(item => item.fieldId == 'duedate' )}).map(e => new CalendarDate( e.duedateentry[0].from).toString()).join(", ")

Keys of linked work items in current project

General

%{filterByProject(linkedIssues(), %{issue.project.key})}

Keys of non-estimated sub-tasks

Jira expression

issue.subtasks.filter(s => s?.originalEstimate == null && s?.customfield_nnnnn == null).map(i => i.key).join(", ")

Last status change date

Jira expression

issue.changelogs.filter(changelog => changelog.items.some(item => item.fieldId == 'status')).map(changelog => changelog.created).concat(issue.created)[0].toString()

RAG - due date traffic light

General

%{{issue.dueDate} = null or %{issue.resolution} != null? "⚪" : (addDays({system.currentDateTime}, 14, RUN_AS_LOCAL) < {issue.dueDate} ? "🟢" : (addDays({system.currentDateTime}, 7, RUN_AS_LOCAL) < {issue.dueDate} ? "🟡" : ({system.currentDateTime} < {issue.dueDate} ? "🟠" : "🔴")))}

RAG - status traffic light

General

%{%{issue.status.category} = "To Do" ? "🔴⚪️⚪️" : ( %{issue.status.category} = "In Progress" ? "⚪️🟡⚪️" : ( %{issue.status.category} = "Done" ? "⚪️⚪️🟢" : "⚪️⚪️⚪️" ))}

Validate URLs for Google Analytics

General

%{count(findPattern(%{issue.cfnnnnn}, "\b(?:https?://|www\.)\S*(?=.*utm_source=)(?=.*utm_medium=)(?=.*utm_campaign=)\S\b")) = count(findPattern(%{issue.cfnnnnn}, "\b(?:https?://|www\.)\S+\b")) ? "🟢" : "🔴"}

Visual progress of sub-tasks

General

let subtasks = issue.subtasks|| []; if (subtasks.length == 0){ 'No sub-tasks' } else{ let doneSubtasks = subtasks.filter(s => s.status.name == "Done"); let value = (doneSubtasks.length / subtasks.length) * 100; let percent = value - value % 1 + (value % 1 >= 0.5 ? 1 : 0); let totalBlocks = 10; let filled = (percent / 100) * totalBlocks; let full = filled - filled % 1 + (filled % 1 >= 0.5 ? 1 : 0); let bar = '🟩'.repeat(full) + '⬜️'.repeat(totalBlocks - full); `${bar} ${percent}%` }

Visual progress of work item

General

%{%{issue.status} = "Open" ? "🟩🟩🟩🟩🟩" : ( %{issue.status} = "Planning" ? "🟩🟩⬜️⬜️⬜️" : ( %{issue.status} = "In Progress" ? "🟩🟩🟩⬜️⬜️" : ( %{issue.status} = "In Review" ? "🟩🟩🟩🟩⬜️" : ( %{issue.status} = "Done" ? "🟩🟩🟩🟩🟩" : "⬜️⬜️⬜️⬜️⬜️" ))))}