Overview
Drill-downs allow users to navigate from a high-level view to a detailed view with context-specific filters applied. This creates an interactive and intuitive data exploration experience.
Basic Implementation Pattern
// Applied to charts/tables view // 1. Get the value you want to filter on const selectedValue = value; // Value from the clicked cell/row // 2. Load the target view const view = app.loadSheetView('WorkspaceName', 'ViewName'); // 3. Apply filters view.addFilter('TableName', 'FieldName', 'Operator', value1, value2); // 4. Set any additional options view.addOption('OptionName', 'OptionValue'); // 5. Set a custom title if desired view.name = `Custom Title`; // 6. Return the view return view;
Core Components
Loading a View
const view = app.loadSheetView('WorkspaceName', 'ViewName');
- WorkspaceName: The name of the workspace containing the target view
- ViewName: The name of the view to load
Adding Filters
view.addFilter('TableName', 'FieldName', 'Operator', value1, value2);
- TableName: The name of the table containing the field
- FieldName: The field to filter on
- Operator: The comparison operator (see list below)
- value1: Primary filter value
- value2: Secondary filter value (required for some operators like 'Between')
Setting Options
view.addOption('OptionName', 'OptionValue');
- Use to configure additional settings in the target view
Setting Custom Title
view.name = `Custom Title`;
- Creates a descriptive title for the drilled-down view
Filter Operators
Basic Operators (All Data Types)
Operator | Description | Example |
---|---|---|
Equal | Exact match (=) | view.addFilter('Users', 'Status', 'Equal', 'Active') |
NotEquals | Not matching (!=) | view.addFilter('Products', 'Category', 'NotEquals', 'Discontinued') |
String Operators
Operator | Description | Example |
---|---|---|
Contains | String contains value | view.addFilter('Incident', 'Description', 'Contains', 'error') |
StartsWith | String starts with value | view.addFilter('Incident', 'Code', 'StartsWith', 'ERR-') |
EndsWith | String ends with value | view.addFilter('Incident', 'Reference', 'EndsWith', '-2024') |
Numeric/Date Operators
Operator | Description | Example |
---|---|---|
GreaterThan | Greater than (>) | view.addFilter('Incident', 'Priority', 'GreaterThan', 2) |
LessThan | Less than (<) | view.addFilter('Inventory', 'Stock', 'LessThan', 10) |
GreaterThanOrEqual | Greater than or equal (>=) | view.addFilter('Performance', 'Score', 'GreaterThanOrEqual', 75) |
LessThanOrEqual | Less than or equal (<=) | view.addFilter('Tasks', 'Priority', 'LessThanOrEqual', 3) |
Between | Between two values | view.addFilter('Incident', 'Count', 'Between', 10, 20) |
Date/Time Specific Operators
Operator | Description | Example |
---|---|---|
Overlaps | For date ranges | view.addFilter('Incident', 'StartDate', 'Overlaps', startDate, endDate) |
InTheLastYear | Last 12 months | view.addFilter('Incident', 'StartDate', 'InTheLastYear') |
InTheLastQuarter | Last 3 months | view.addFilter('Incident', 'StartDate', 'InTheLastQuarter') |
InTheLastMonth | Last month | view.addFilter('Incident', 'StartDate', 'InTheLastMonth') |
InTheLastWeek | Last 7 days | view.addFilter('Incident', 'StartDate', 'InTheLastWeek') |
InTheNextYear | Next 12 months | view.addFilter('Incident', 'StartDate', 'InTheNextYear') |
InTheNextQuarter | Next 3 months | view.addFilter('Incident', 'StartDate', 'InTheNextQuarter') |
InTheNextMonth | Next month | view.addFilter('Incident', 'StartDate', 'InTheNextMonth') |
InTheNextWeek | Next 7 days | view.addFilter('Incident', 'StartDate', 'InTheNextWeek') |
User/Team Specific Operators
Operator | Description | Example |
---|---|---|
AssignedToMe | Current user | view.addFilter('Incident', 'AssignedTo', 'AssignedToMe') |
AssignedToMyTeam | Current user's team | view.addFilter('Incident', 'AssignedTo', 'AssignedToMyTeam') |
AssignedToTeam | Specific team | view.addFilter('Incident', 'AssignedTo', 'AssignedToTeam', ['Team Name']) |
Accessing Field Values
When writing drill-down code, you have several ways to access field values:
1. Using the record object
// The record object is available in drill-down scripts const fieldValue = record.getValue('FieldName');
2. Using the value variable
// The value variable contains the clicked cell's value const fieldValue = value;
3. Using the result object
// The result object contains the full record data const fieldValue = result.FieldName;
4. Accessing fields from specific tables
// Access fields from a specific table const fieldValue = record.getFieldValue('TableName', 'FieldName');
Example: Drill-down using record values
// Applied to charts view // Get the selected record const selectedRecord = record; // Check if record exists if (!selectedRecord) { return; } // Get the Work Order Number from the Work Order table's Number field const workOrderNumber = selectedRecord.getFieldValue('Work Order', 'Number'); // Check if work order number exists if (!workOrderNumber) { return; } // Load the Incident Details view const view = app.loadSheetView('Incidents', 'Incident Details'); if (!view) { return; // Handle case where view couldn't be loaded } // Apply filter using the record's Work Order Number view.addFilter('Incident', 'WorkOrderRouting', 'Equal', workOrderNumber); // Set a custom title for the drilled-down view view.name = `Incident Details for Work Order #${workOrderNumber}`; // Return the view return view;
Complete Example with Multiple Field Access Methods
// Applied to charts view // Get the selected value const selectedValue = value; if (!selectedValue) { return; } // Load the target view const view = app.loadSheetView('MyWorkspace', 'DetailView'); if (!view) { return; } // Example of getting field values from the record const recordId = record.getValue('Id'); const recordName = record.getValue('Name'); const recordDate = record.getValue('StartDate'); // Example of getting field values from the result object const resultId = result.Id; const resultName = result.Name; const resultDate = result.StartDate; // Calculate date range using the field value const startDate = new Date(selectedValue); const endDate = new Date(selectedValue); endDate.setHours(23, 59, 59, 999); // Apply filters using the field values view.addFilter('Incident', 'StartDate', 'Overlaps', startDate, endDate) .addFilter('Incident', 'Id', 'Equal', recordId) .addFilter('Incident', 'Name', 'Contains', recordName); // Set view options view.addOption('Time Segment', 'Number of Days', 1) .addOption('Time Segment', 'End Date', selectedValue); // Set custom title using field values view.name = `${recordName} details for ${selectedValue.toLocaleDateString("en-US")}`; return view;
Key Points About Field Value Access
- The record object provides getValue() and getFieldValue() methods to access field values
- The value variable contains the clicked cell's value
- The result object provides direct access to field values as properties
- Field values are automatically converted to the appropriate type (dates, numbers, strings, etc.)
- These values can be used for filters, date calculations, custom titles, view options, and conditional logic
Data Type Examples
Date Filtering
// Applied to charts view // Single date const view = app.loadSheetView('Workspace', 'View'); view.addFilter('Incident', 'StartDate', 'Equal', new Date('2024-03-20')); // Date range const startDate = new Date('2024-03-01'); const endDate = new Date('2024-03-31'); view.addFilter('Incident', 'StartDate', 'Between', startDate, endDate); // Date overlap (for start/end date pairs) view.addFilter('Incident', 'StartDate', 'Overlaps', startDate, endDate); // Relative date ranges view.addFilter('Incident', 'StartDate', 'InTheLastMonth'); view.addFilter('Incident', 'StartDate', 'InTheNextWeek');
User Filtering
// Applied to charts view // Current user context view.addFilter('Incident', 'AssignedTo', 'AssignedToMe'); view.addFilter('Incident', 'AssignedTo', 'AssignedToMyTeam'); // Specific users (by name) view.addFilter('Incident', 'AssignedTo', 'Equal', ['John Smith', 'Jane Doe']); // Team filtering view.addFilter('Incident', 'AssignedTo', 'AssignedToTeam', ['Team Name']);
String Filtering
// Applied to charts view view.addFilter('Incident', 'Description', 'Contains', 'error'); view.addFilter('Incident', 'Code', 'StartsWith', 'ERR-'); view.addFilter('Incident', 'Reference', 'EndsWith', '-2024');
Numeric Filtering
// Applied to charts view view.addFilter('Incident', 'Priority', 'GreaterThan', 2); view.addFilter('Incident', 'Count', 'Between', 10, 20);
Special Fields
// System-level fields available for filtering view.addFilter('Incident', 'Valid', 'Equal', true); // Record validity view.addFilter('Incident', 'Archived', 'Equal', false); // Archive status view.addFilter('Incident', 'Created', 'InTheLastMonth'); // Creation date/time view.addFilter('Incident', 'CreatedBy', 'Equal', 'John'); // Creator view.addFilter('Incident', 'PortalPublic', 'Equal', true); // Portal visibility
Complete Example with Multiple Filters
// Applied to charts view // Get the selected value const selectedValue = value; if (!selectedValue) { return; } // Load the target view const view = app.loadSheetView('MyWorkspace', 'DetailView'); if (!view) { return; } // Calculate date range const startDate = new Date(selectedValue); const endDate = new Date(selectedValue); endDate.setHours(23, 59, 59, 999); // Apply multiple filters view.addFilter('Incident', 'StartDate', 'Overlaps', startDate, endDate) .addFilter('Incident', 'Status', 'Equal', 'Active') .addFilter('Incident', 'Priority', 'GreaterThan', 2) .addFilter('Incident', 'AssignedTo', 'AssignedToMyTeam') .addFilter('Incident', 'Description', 'Contains', 'critical'); // Set view options view.addOption('Time Segment', 'Number of Days', 1) .addOption('Time Segment', 'End Date', selectedValue); // Set custom title view.name = `Critical Incidents for ${selectedValue.toLocaleDateString("en-US")}`; return view;
Best Practices
1. Input Validation
Always check if required values exist before using them
if (!selectedValue) return;
2. Error Handling
Handle cases where views cannot be loaded
const view = app.loadSheetView('Workspace', 'View'); if (!view) { return; // Handle the case where view couldn't be loaded }
3. Method Chaining
Use method chaining for cleaner code
view.addFilter('Table1', 'Field1', 'Equal', value1) .addFilter('Table2', 'Field2', 'Contains', value2) .addOption('Option1', 'Value1');
4. Descriptive Titles
Use informative titles that describe the filtered view
view.name = `Sales for ${region} - ${quarter}`;
5. Use Appropriate Operators
Select operators that match your data type and filtering needs
- For dates, use Overlaps when dealing with start/end date pairs
- For users, use AssignedToMe or AssignedToMyTeam for current context
- For relative time ranges, use operators like InTheLastMonth
6. Date/Time Handling
Handle time zones appropriately for date/time fields
// Set end of day for date range const endOfDay = new Date(selectedDate); endOfDay.setHours(23, 59, 59, 999);
Troubleshooting
- If your drill-down isn't working, verify workspace and view names
- Check that field names match exactly in your filter calls
- Ensure your operator is compatible with the field type
- Verify that the values you're filtering on exist in the data
- For date filters, check that the date format is valid
- For user/team filters, verify that the specified users/teams exist
- Use console logging to debug filter values during development
Real-World Examples
Example: Work Order to Incident Details
// Applied to Work Order table view // Get the selected record const selectedRecord = record; // Check if record exists if (!selectedRecord) { return; } // Get the Work Order Number from the Work Order table's Number field const workOrderNumber = selectedRecord.getFieldValue('Work Order', 'Number'); // Check if work order number exists if (!workOrderNumber) { return; } // Load the Incident Details view const view = app.loadSheetView('Incidents', 'Incident Details'); if (!view) { return; // Handle case where view couldn't be loaded } // Apply filter using the record's Work Order Number view.addFilter('Incident', 'WorkOrderRouting', 'Equal', workOrderNumber); // Set a custom title for the drilled-down view view.name = `Incident Details for Work Order #${workOrderNumber}`; return view;
This example shows how to create a drill-down from a Work Order view to the Incident Details view, filtering by the work order routing field.