- 17 Minutes to read
- Print
- DarkLight
- PDF
Concepts: Custom Fields Deep Dive
- 17 Minutes to read
- Print
- DarkLight
- PDF
Introduction
This article takes a deeper look at each custom field data type and provides examples, details, and tips for each one.
Available Data Types
As previously outlined in the system objects with custom fields intro article, there are currently 10 different data types available:
Data Type Id | Data Type Name | Stored As |
---|---|---|
1 | Basic Text | ValueAsString |
2 | Rich Text* | ValueAsString |
3 | Whole Number | ValueAsNumber |
4 | Decimal Number | ValueAsDecimal |
5 | Yes or No Choice | ValueAsBoolean |
6 | Date Only | ValueAsDate |
7 | Date and Time | ValueAsDate |
8 | Single Choice | ValueAsString |
9 | Multiple Choice** | ValueAsString |
10 | Reference | ReferenceObject |
Data Type: Basic Text
The following script example creates a new client that has a basic text custom field named “Billing Contact Name”
$billingContactNameFieldId = 10
$clientToCreate = @{
Name = "SoundWave Studios"
Reference = "SWS0001"
Fields = @(
@{
FieldId = $billingContactNameFieldId
Label = "Billing Contact Name"
Value = @{
ValueAsString = "Seth Trapsitell"
}
}
)
}
$createdClient = Add-Client -Entry $clientToCreate
Write-Output "Client $($createdClient.ClientId) ($($createdClient.Name)) was created"
The output of this script:
Client 85 (SoundWave Studios) was created
Points of Interest:
Note that we used the
ValueAsString
property to store the decimal value.
Data Type: Rich Text
The following script example creates a new client that has a rich text custom field named “Client Address”
$clientAddressFieldId = 90
$clientToCreate = @{
Name = "SoundWave Studios"
Reference = "SWS0001"
Fields = @(
@{
FieldId = $clientAddressFieldId
Label = "Client Address"
Value = @{
ValueAsString = "<p><strong>123 Main Street</strong><br />Suite 2400<br />Somewheresville, NW 55555</p>"
}
}
)
}
$createdClient = Add-Client -Entry $clientToCreate
Write-Output "Client $($createdClient.ClientId) ($($createdClient.Name)) was created"
The output of this script:
Client 86 (SoundWave Studios) was created
Points of Interest:
Note that we used the
ValueAsString
property to store the decimal value.Rich text fields allow you to add light-weight tag-based HTML formatting to your values. As seen in the example above, we wrapped the value in an HTML paragraph tag, made the street portion of the address bold, and added HTML line breaks to format the address so it displays nicely in the browser.
Head’s Up!
As mentioned, light-weight tag-based HTML formatting is allowed, but there are many HTML features that are sanitized for security reasons, specifically <script> tags and inline attributes such as the style attribute. Intended formatting includes creating paragraphs, line breaks, hyperlinks, tables, and lists. You can experiment with what works and what doesn’t directly within the application by entering information into a rich text field by using the HTML source code button on the righthand side of the UI editor widget’s toolbar.
Data Type: Whole Number
The following script example creates a new media log entry that has a whole number custom field named “Total Documents Destroyed”
# Media Type Id for Hard Drive
$mediaTypeId = 2
# Create the media log entry on a matter by associating the Matter Id
$matterId = 1
# The custom field Id for the total documents destroyed field on the media log entry object
$totalDocsDestroyedFieldId = 91
# Use the ConvertTo-DateString command to convert the date to a specific time zone:
$currentDateTime = ConvertTo-DateString `
-DateTime (Get-Date) `
-TimeZone "Central Standard Time" `
-IncludeTime
# Define a media log entry entry object
$mediaLogEntry = @{
MediaTypeId = $mediaTypeId
MatterId = $matterId
Date = $currentDateTime
Fields = @(
@{
FieldId = $totalDocsDestroyedFieldId
Label = "Total Documents Destroyed"
Value = @{
ValueAsNumber = 1000
}
}
)
}
# Pass the media log entry object to the Add-MediaLogEntry command to create the entry.
# This example bypasses custom field validation by including the switch parameter
$createdMediaLogEntry = Add-MediaLogEntry -Entry $mediaLogEntry -BypassCustomFieldValidation
# Use Write-Output to log the execution results
Write-Output "Media log entry $($createdMediaLogEntry.MediaLogEntryId) created"
The output of this script:
Media log entry 58 created
Points of Interest:
Note that we used the
ValueAsNumber
property to store the value.
Data Type: Decimal Number
The following script example creates a new volume that has a decimal number custom field named “Uncompressed Data (GB)”
# Create the volume on a matter by associating the Matter Id
$matterId = 1
# The custom field Id for the uncompressed data (GB) field on the media log entry object
$uncompressedDataGBFieldId = 92
# Use the ConvertTo-DateString command to convert the date to a specific time zone:
$currentDateTime = ConvertTo-DateString `
-DateTime (Get-Date) `
-TimeZone "Central Standard Time" `
-IncludeTime
# Define a volume object
$volume = @{
Name = "VOL001"
MatterId = $matterId
VolumeDate = $currentDateTime
DocCount = 100
PageCount = 0
NativeCount = 100
Fields = @(
@{
FieldId = $uncompressedDataGBFieldId
Label = "Uncompressed Data (GB)"
Value = @{
ValueAsDecimal = 32.24
}
}
)
}
# Pass the volume object to the Add-Volume command to create the entry.
# This example bypasses custom field validation by including the switch parameter
$createdVolume = Add-Volume -Entry $volume -BypassCustomFieldValidation
# Use Write-Output to log the execution results
Write-Output "Volume $($createdVolume.VolumeId) created"
The output of this script:
Volume 44 created
Points of Interest:
Note that we used the
ValueAsDecimal
property to store the value.
Decimal Precision
At the time of this writing, the decimal fields will only store up to 2 places. If you try to provide a number with more decimal places, the system will round it to the nearest 100th.
Data Type: Yes or No Choice
The following script example creates a new billing entry that has a yes or no custom field named “Billed?”
# Billing Type Id for Hourly Technical Work
$billingTypeId = 98
# Create the billing entry on the matter by associating the Matter Id
$matterId = 3
# The custom field Id for the billed field on the billing entry object
$billedFieldId = 93
# Use the ConvertTo-DateString command to convert the date to a specific time zone:
$currentDateTime = ConvertTo-DateString `
-DateTime (Get-Date) `
-TimeZone "Central Standard Time" `
-IncludeTime
# Defind a billing entry object
$billingEntry = @{
BillingTypeId = 98
MatterId = $matterId
Narrative = "Scripted Billing Entry."
Quantity = 0.50
UnitPrice = 100.00
Date = $currentDateTime
Fields = @(
@{
FieldId = $billedFieldId
Label = "Billed?"
Value = @{
ValueAsBoolean = $true
}
}
)
}
# Pass the billing entry object to the Add-BillingEntry command to create the entry.
# This example bypasses custom field validation by including the switch parameter
$createdBillingEntry = Add-BillingEntry -Entry $billingEntry -BypassCustomFieldValidation
# Use Write-Output to log the execution results
Write-Output "Billing entry $($createdBillingEntry.BillingEntryId) created"
The output of this script:
Billing entry 485 created
Points of Interest:
Note that we used the
ValueAsBoolean
property to store the value.
Data Type: Date Only
The following script example creates a new billing entry that has a date only custom field named “Invoiced On”
# Define our own function for retreiving the current date with a specificed time zone offset
# where the time component is set to noon. We do this because Agility Blue stores all dates
# as DateTimeOffset.
function Get-CurrentDateOnlyString([int]$offset) {
# Get the current date and set it to noon
$currentDateAtNoon = (Get-Date).Date.AddHours(12)
# Ensure the kind is unspecified
$currentDateAtNoon = [DateTime]::SpecifyKind($currentDateAtNoon, [DateTimeKind]::Unspecified)
# Specify the offset (e.g., -05:00 for Central Time)
$offsetTimeSpan = [TimeSpan]::FromHours($offset)
# Create the DateTimeOffset object with the specified offset
$currentDateAtNoonWithOffset = [System.DateTimeOffset]::new($currentDateAtNoon, $offsetTimeSpan)
# Return the format that Agility Blue needs to store the date
return ConvertTo-DateString `
-DateTimeOffset $currentDateAtNoonWithOffset `
-IncludeTime
}
# Billing Type Id for Processing
$billingTypeId = 224
# Create the billing entry on the matter by associating the Matter Id
$matterId = 1
# The custom field Id for the billed field on the billing entry object
$invoicedOnFieldId = 93
# Call our custom function to retrieve a date-only string with a time zone offset of -5
# to indicate that we want it in central standard time
$currentDate = Get-CurrentDateOnlyString -offset -5
# Defind a billing entry object
$billingEntry = @{
BillingTypeId = $billingTypeId
MatterId = $matterId
Narrative = "Scripted Billing Entry."
Quantity = 0.50
UnitPrice = 100.00
Date = $currentDate
Fields = @(
@{
FieldId = $invoicedOnFieldId
Label = "Invoiced On"
Value = @{
ValueAsDate = $currentDate
}
}
)
}
# Pass the billing entry object to the Add-BillingEntry command to create the entry.
# This example bypasses custom field validation by including the switch parameter
$createdBillingEntry = Add-BillingEntry -Entry $billingEntry -BypassCustomFieldValidation
# Use Write-Output to log the execution results
Write-Output "Billing entry $($createdBillingEntry.BillingEntryId) created"
The output of this script:
Billing entry 489 created
Points of Interest:
Note that we used the
ValueAsDate
property to store the value.All dates in Agility Blue are stored with a date, time, and time zone component in the following format:
yyyy-MM-ddTHH:mm:ssK
. You can use the utility commandConvertTo-DateString
to format a date object into this format with a specified time zone. Not specifying a time zone for a DateTime object will result in dates being stored in UTC time.
Date Only Fields
In Agility Blue, you can pick between a date only field and a date and time field. When choosing these types of fields, the time being omitted or not refers to the formatting as they are displayed to end users in the browser, however, they are both stored with a time and time zone offset component regardless of which one is selected. If a date is provided without a time or time zone offset, they will default to
UTC 00:00:00+00:00
. Because of this, you should be mindful of how the time component can affect users that may exist in other time zones. Agility Blue will always display times local to the user’s time zone. If you don’t want to have to worry about the time component for a date-only field and you have users that access Agility Blue that span within 12 hours of each other, consider setting the time to 12:00 noon like in the example above instead of 00:00 midnight so the dates don’t appear to shift around for users in the other time zones. For users outside of a 12-hour time difference, they will need to be made aware of this behavior.
Data Type: Date and Time
The following script example creates a new media log entry that has a media log entry date and time custom field named “Checked Out At”
# Media Type Id for Hard Drive
$mediaTypeId = 2
# Create the media log entry on a matter by associating the Matter Id
$matterId = 1
# The custom field Id for the total documents destroyed field on the media log entry object
$checkedOutAtFieldId = 94
# Use the ConvertTo-DateString command to convert the date to a specific time zone:
$currentDateTime = ConvertTo-DateString `
-DateTime (Get-Date) `
-TimeZone "Eastern Standard Time" `
-IncludeTime
# Define a media log entry entry object
$mediaLogEntry = @{
MediaTypeId = $mediaTypeId
MatterId = $matterId
Date = $checkedOutAtFieldId
Fields = @(
@{
FieldId = $checkedOutAtFieldId
Label = "Checked Out At"
Value = @{
ValueAsDate = $currentDateTime
}
}
)
}
# Pass the media log entry object to the Add-MediaLogEntry command to create the entry.
# This example bypasses custom field validation by including the switch parameter
$createdMediaLogEntry = Add-MediaLogEntry -Entry $mediaLogEntry -BypassCustomFieldValidation
# Use Write-Output to log the execution results
Write-Output "Media log entry $($createdMediaLogEntry.MediaLogEntryId) created"
The output of this script:
Media log entry 59 created
Points of Interest:
Note that we used the
ValueAsDate
property to store the value.All dates in Agility Blue are stored with a date, time, and time zone component in the following format:
yyyy-MM-ddTHH:mm:ssK
. You can use the utility commandConvertTo-DateString
to format a date into this format with a specified time zone. Not specifying a time zone for a DateTime object will result in dates being stored in UTC time.
Data Type: Single Choice
The following script example creates a contact that has a single choice custom field named “Office Location”
# The custom field Id for the office location field on the contact object
$officeLocationFieldId = 95
# Define a contact object
$contact = @{
FirstName = "Donna"
LastName = "Taylor"
EmailAddress = "dtayler@agilitybluedemo.com"
Fields = @(
@{
FieldId = $officeLocationFieldId
Label = "Office Location Field"
Value = @{
ValueAsString = "Minneapolis"
}
}
)
}
# Pass the contact object to the Add-Contact command to create the entry.
# This example bypasses custom field validation by including the switch parameter
$createdContact = Add-Contact -Entry $contact -BypassCustomFieldValidation
# Use Write-Output to log the execution results
Write-Output "Contact $($createdContact.ContactId) created"
The output of this script:
Media log entry 60 created
Points of Interest:
Note that we used the
ValueAsString
property to store the value.Single choice values are simply stored as strings. You can technically store values that aren’t listed in the choices defined on the object!
Data Type: Multiple Choice
The following script example creates a new media log entry that has a multiple choice custom field named “Properties”
# Media Type Id for Hard Drive
$mediaTypeId = 2
# Create the media log entry on a matter by associating the Matter Id
$matterId = 1
# The custom field Id for the properties field on the media log entry object
$propertiesFieldId = 96
# Use the ConvertTo-DateString command to convert the date to a specific time zone:
$currentDateTime = ConvertTo-DateString `
-DateTime (Get-Date) `
-TimeZone "Central Standard Time" `
-IncludeTime
# Define a media log entry entry object
$mediaLogEntry = @{
MediaTypeId = $mediaTypeId
MatterId = $matterId
Date = $currentDateTime
Fields = @(
@{
FieldId = $propertiesFieldId
Label = "Properties"
Value = @{
ValueAsString = "Forensics`nChain of Custody`nFast-Track"
}
}
)
}
# Pass the media log entry object to the Add-MediaLogEntry command to create the entry.
# This example bypasses custom field validation by including the switch parameter
$createdMediaLogEntry = Add-MediaLogEntry -Entry $mediaLogEntry -BypassCustomFieldValidation
# Use Write-Output to log the execution results
Write-Output "Media log entry $($createdMediaLogEntry.MediaLogEntryId) created"
The output of this script:
Media log entry 65 created
Points of Interest:
Note that we used the
ValueAsString
property to store the value.Separate selected choices by using the newline character `n within the string value.
Data Type: Reference
Reference fields are fields that can store zero, one, or many values in a collection of records that contain a small amount of metadata about the source object instance they point to. Here is an example of a custom field that references the “User” object:
{
"FieldId": 55,
"ObjectId": 1,
"DataTypeId": 10,
"DataTypeName": "Reference",
"Label": "Project Manager",
"IsRequired": false,
"Position": 5,
"Guid": 2907893454017,
"IsSystemField": false,
"IsReferenceValue": false,
"DefaultValue": null,
"CopyPreviousValueOnSaveAndNew": false,
"Value": {
"ObjectFieldValueId": 2140,
"ObjectFieldId": 55,
"ObjectId": 1,
"PrimaryKeyId": 71,
"ValueAsString": null,
"ValueAsBoolean": null,
"ValueAsNumber": null,
"ValueAsDecimal": null,
"ValueAsDate": null,
"ReferenceObject": {
"ObjectFieldReferenceObjectInstanceId": 320,
"ObjectFieldValueId": 2140,
"ObjectId": 8,
"Object": null,
"PrimaryObjectId": 1,
"PrimaryKeyId": 71,
"KeyType": "String",
"DisplayFormat": "%Val%",
"IsSystemObject": true,
"Name": null,
"NumberOfValues": 1,
"Values": [
{
"ObjectFieldReferenceObjectInstanceValueId": 239,
"ObjectFieldReferenceObjectInstanceId": 320,
"KeyAsString": "2c35e3b4-2e17-4ee6-b192-e92e4db5cf3c",
"KeyAsInteger": null,
"KeyAsLong": null,
"Value": "Roger Schlachter"
}
]
}
}
}
The root of the object contains the standard metadata information about the field, where the DataTypeName
property indicates that this is a reference type field. When a field is a reference type, the value will be stored in the ReferenceObject
object property that contains information about what kind of reference is being used (for example, users, clients, media log entries, etc.), and a collection property named Values
that stores the actual reference values. Reference values contain two pieces of information: the KeyAs*
property and the Value
. The type of key (ID) that’s stored depends on the reference object because some objects, like User, use a string for their key, where most other objects use an integer for their key.
The following table provides the system objects that can be referenced and information about their keys:
Object Id | Object Name | Key Name | Key Data Type | KeyAs* Property | Value Format |
---|---|---|---|---|---|
1 | Client | ClientId | Int32 | KeyAsInteger | Client Name + Reference in parenthesis. Ex: “ABC Client (0001)” |
2 | Matter | MatterId | Int32 | KeyAsInteger | Matter Name + Reference in parenthesis. Ex: “ABC vs XYZ (0001)” |
3 | Media Log Entry | MediaLogEntryId | Int32 | KeyAsInteger | Id + Media Type. Ex: “#1 - Hard Drive” |
4 | Volume | VolumeId | Int32 | KeyAsInteger | Id + Volume Name. Ex: “#2 - VOL001” |
5 | Project | ProjectId | Int64 | KeyAsLong | Id + Project Description. Ex: “#2024060000001 - Production” |
6 | Task | TaskId | Int32 | KeyAsInteger | Id + Task Name. Ex: “#1026 - Process Documents” |
7 | Contact | ContactId | Int32 | KeyAsInteger | Full Name + Email in brackets. Ex: Adele Butler <abutler@abdemo.com>“ |
8 | User | Id | String | KeyAsString | Full Name. Ex: “Roger Schlachter” |
9 | Billing Entry | BillingEntryId | Int32 | KeyAsInteger | Id + Billing Type + Quantity in parenthesis. Ex: “#1 - Hourly Technical Work (Quantity: 3.5)” |
10+ | Custom Object | Id | Int32 | KeyAsInteger | The reference link field. Ex: “Analyst” |
When creating or updating a reference field with values, there are only a few fields that need to be provided. The following example is a script that creates a new client that contains a custom user reference field named “Project Manager”:
$clientToCreate = @{
Name = "SoundWave Studios"
Reference = "SWS0001"
Fields = @(
@{
FieldId = 55
Label = "Project Manager"
Value = @{
ReferenceObject = @{
Values = @(
@{
KeyAsString = "2c35e3b4-2e17-4ee6-b192-e92e4db5cf3c"
Value = "Roger Schlachter"
}
)
}
}
}
)
}
$createdClient = Add-Client -Entry $clientToCreate
Write-Output "Client $($createdClient.ClientId) ($($createdClient.Name)) was created"
Points of Interest:
As usual, the custom field requires that we provide the
FieldId
property. TheLabel
property is only used here to help us understand which field this is in the field collection and is ignored by the system because it is read-only.The
Value
object property only needs to contain theReferenceObject
property that contains the values collection for the record we’re referencing.In this example, the “Project Manager” field is setup to reference users. To reference a user, we need to know their Id and their full name. The user’s Id will need to be placed in the
KeyAsString
property because the key data type for users is “String”. The user’s full name can then be placed into theValue
property. The value is what the end user sees when they are viewing this record within the application.
Head’s Up!
You can technically put anything you want into the
Value
property for the custom field and the application will reflect what you put in there. However, if you ever end up updating the source instance of the referenced field, the system will automatically propagate the update anywhere it’s referenced and the value will change to the system-defined format as described in the table above. Additionally, the system may update the cached values from time to time during maintenance cycles.