Page and view events provide the foundation for triggering business logic when users navigate your application and when content is displayed.
Page Events
Page events fire when users navigate to different pages in your application:
Knack.ready().then(async () => {
// Listen for any page render
Knack.on('page:render', ({ pageKey }) => {
console.log('Page rendered:', pageKey);
// Use for business logic, not DOM manipulation
});
// Listen for a specific page render
Knack.on('page:render:scene_123', ({ pageKey }) => {
console.log('Dashboard page rendered');
// Trigger page-specific business logic
});
});
Supported Page Events:
Event: page:render
Event: page:render:scene_123
Page Event Use Cases
Page events are ideal for:
- Loading page-specific data
- Initializing page-level business logic
- Tracking page views for analytics
- Setting up page-specific configurations
Knack.on('page:render:scene_dashboard', async ({ pageKey }) => {
console.log('Dashboard loaded');
try {
const user = await Knack.getUser();
const tables = await Knack.getTables();
console.log(`Dashboard loaded for ${user?.email}`);
console.log(`Available tables: ${tables.length}`);
// Track page access
trackPageView(pageKey, user?.email);
} catch (error) {
console.error('Failed to load dashboard data:', error);
}
});
View Events
Supported View Events:
view:render
view:render:<view_key>
view:render: <view_type> (form, table, details, list)
getViewFilters()
view(viewKey).refresh() reload a view's data on demand to keep your app displaying the most current information.
View events fire when individual views render on a page:
Knack.ready().then(async () => {
// Listen for any view render
Knack.on('view:render', ({ viewKey }) => {
console.log('View rendered:', viewKey);
// Use for analytics, logging, or business logic
});
// Listen for a specific view render
Knack.on('view:render:view_456', ({ viewKey }) => {
console.log('Contact form rendered');
// Trigger view-specific business logic
});
// Listen for specific view types
Knack.on('view:render:form', ({ viewKey }) => {
console.log('A form view was rendered:', viewKey);
// Handle form-specific logic
});
});
View Type Events
You can listen for specific types of views:
// Form views
Knack.on('view:render:form', ({ viewKey }) => {
console.log('Form view rendered:', viewKey);
initializeFormValidation(viewKey);
});
// Table views
Knack.on('view:render:table', ({ viewKey }) => {
console.log('Table view rendered:', viewKey);
initializeTableAnalytics(viewKey);
});
// List views
Knack.on('view:render:list', ({ viewKey }) => {
console.log('List view rendered:', viewKey);
processListData(viewKey);
});
// Detail views
Knack.on('view:render:details', ({ viewKey }) => {
console.log('Detail view rendered:', viewKey);
loadRelatedData(viewKey);
});
How to Use getViewFilters()
The getViewFilters() method gives you real-time access to the active filter configuration of any view on a page. This enables you to build more advanced and context-aware custom logic, create sophisticated integrations, and more easily debug complex filtering scenarios.
By retrieving the current filter state, your custom code can dynamically respond to how a user is interacting with your views.
Parameters: viewKey (string, required): The unique identifier for the view whose filters you want to retrieve.
Returns: An object representing the filter configuration currently applied to the specified view. The structure of this object will reflect the filters you have configured in the Builder.
How to Use getViewFilters()
To use this method, you simply call it with the viewKey of the target view. It is best practice to ensure the page is fully rendered before attempting to access a view's filters.
Example: Logging Filters to the Console
The following example demonstrates how to retrieve and log the active filters for a specific view.
// Wait for the Knack app to be ready
window.Knack.ready().then(() => {
console.log('Testing getViewFilters...');
// Replace 'view_123' with the actual key of the view you want to inspect
const viewKey = 'view_123';
// Retrieve the filters for the specified view
const filters = window.Knack.page.getViewFilters(viewKey);
// Log the filter configuration to the console for inspection
console.log(`Active filters for ${viewKey}:`, filters);
});Programmatically Refreshing Views
The Knack.view(viewKey).refresh() method lets you reload a view's data on demand without requiring a full page reload. Use it to create more dynamic, responsive apps where data changes need to be reflected immediately.
## Key Features
- **On-demand data reload:** Fetch fresh data from the server for any view.
- **Asynchronous operation:** Returns a Promise that resolves when the refresh is complete, so you can chain actions or respond to completion.
- **Broad view compatibility:** Works with tables, lists, details, calendars, and charts.
- **State preservation:** Filters, sorting, and pagination are maintained by default.
- **Optional state reset:** Pass `{ reset: true }` to restore the view to its default state.
---
### Knack.view(viewKey).refresh(options)
Initiates a refresh of the specified view, fetching the latest data from the server.
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `viewKey` | string | Yes | The unique identifier for the view you want to refresh. |
| `options` | object | No | Additional options for the refresh operation. |
**Options:**
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `reset` | boolean | `false` | When `true`, resets the view's filters, sorting, and pagination to their original configuration. |
**Returns:** A Promise that resolves when the view has been successfully refreshed. If the refresh fails, the Promise is rejected with an error.
---
## Usage Examples
### Refresh a Table After Form Submission
The most common use case: after a user submits a form, automatically refresh a table to display the new record.
```js
Knack.ready().then(async () => {
// Listen for the submit event on a specific form (e.g., view_215)
Knack.on("form:submit:view_215", async ({ record, viewKey }) => {
console.log("Form submitted, refreshing related table...");
// Refresh the table view (e.g., view_216) to show the new record
try {
await Knack.view("view_216").refresh();
console.log("Table refreshed successfully!");
} catch (error) {
console.error("Failed to refresh table:", error);
}
});
});
```
### Update a Chart with New Data
Refresh a chart view to reflect changes made through other interactions on the page.
```js
// Assuming a button with the ID 'refresh-chart-button' triggers the refresh
const refreshButton = document.getElementById("refresh-chart-button");
if (refreshButton) {
refreshButton.addEventListener("click", async () => {
console.log("Refreshing chart...");
try {
await Knack.view("view_101").refresh(); // Replace with your chart's viewKey
console.log("Chart updated!");
} catch (error) {
console.error("Failed to refresh chart:", error);
}
});
}
```
### Refresh a View and Reset Its State
To refresh a view and clear any user-applied filters, sorting, or pagination, pass `{ reset: true }`.
```js
// Refresh a list view and reset it to its default state
Knack.view("view_303").refresh({ reset: true });
```
---
## State Management
By default, `refresh()` is non-disruptive to the user experience. The following are preserved during a refresh:
- **Filters:** Any active filters remain applied.
- **Sorting:** The current sort order is maintained.
- **Pagination:** The user stays on the same page of results.
To clear these and return the view to its initial state, use `refresh({ reset: true })`.
---
## Error Handling
Wrap `refresh()` calls in a `try...catch` block to handle failures gracefully.
**Common error scenarios:**
- **Invalid `viewKey`:** The specified view does not exist.
- **Network issues:** The request to the server fails.
- **Server-side errors:** The server encounters an issue while fetching data.
```js
try {
await Knack.view("non_existent_view").refresh();
} catch (error) {
// Log the error and provide feedback to the user
console.error("An error occurred while refreshing the view:", error);
// Optionally, display a user-friendly error message in the UI
}Troubleshooting
View not refreshing
Double-check that you're using the correct viewKey. You can find it in the Builder by selecting the view.
Incorrect data displayed
Verify that your data sources and connections are configured correctly. The refresh() method only displays data that is available on the server.
Performance issues
For large datasets, the refresh may take a moment. Consider showing a loading indicator to let users know the view is updating.
Records Render Events
Special events fire when views display record data:
Knack.ready().then(async () => {
// Listen for when records are loaded in any view
Knack.on('records:render', ({ records, viewKey }) => {
console.log(`${records.length} records loaded in ${viewKey}`);
// Analyze the loaded data
analyzeRecords(records, viewKey);
});
// Listen for records in a specific view
Knack.on('records:render:view_188', ({ records, viewKey }) => {
console.log('Contact table data loaded:', records.length, 'records');
// Process contact data
const statusCounts = records.reduce((acc, record) => {
const status = record.field_status;
acc[status] = (acc[status] || 0) + 1;
return acc;
}, {});
console.log('Status distribution:', statusCounts);
// Business logic based on data analysis
if (statusCounts.Expired > 10) {
console.log('High number of expired records detected');
triggerExpirationAlert();
}
});
});
Practical Examples
User Role-Based Logic
Knack.on('page:render', async ({ pageKey }) => {
try {
const user = await Knack.getUser();
const userRoles = user?.roles || [];
console.log('User roles detected:', userRoles);
if (userRoles.includes('Administrator')) {
console.log('Admin user detected, admin features available');
// Example CSS (add to stylesheet, not JS):
// .scene_admin_dashboard .admin-features { display: block; }
}
if (userRoles.includes('Manager')) {
console.log('Manager user detected, enabling manager features');
document.body.classList.add('manager-user');
}
// Role-based page access logging
if (pageKey === 'scene_reports' && !userRoles.includes('Manager') && !userRoles.includes('Administrator')) {
console.log('Non-privileged user accessing reports');
logRestrictedAccess(pageKey, user.email);
}
} catch (error) {
console.error('Failed to get user information:', error);
}
});
View-Specific Initialization
// Initialize different logic based on view type
Knack.on('view:render', ({ viewKey }) => {
switch (viewKey) {
case 'view_456':
initializeContactForm();
break;
case 'view_789':
loadSalesMetrics();
break;
case 'view_321':
checkInventoryLevels();
break;
}
});
function initializeContactForm() {
console.log('Contact form initialized');
// Set up form-specific business logic
}
function loadSalesMetrics() {
console.log('Loading sales metrics');
// Trigger sales data analysis
}
function checkInventoryLevels() {
console.log('Checking inventory levels');
// Monitor inventory status
}
Best Practices
⚠️Use caution with DOM Manipulation
Use caution with page and view events for DOM manipulation - there may be a CSS solution instead:
// ⚠️ Caution - DOM manipulation
Knack.on('view:render:view_456', () => {
document.querySelector('.kn-button').style.color = 'red';
});
// ✅ Business logic only
Knack.on('view:render:view_456', ({ viewKey }) => {
console.log('Contact form loaded');
initializeContactValidation();
loadContactDefaults();
});
Efficient Event Handling
Use conditional logic instead of many specific listeners:
// ✅ Efficient approach
Knack.on('view:render', ({ viewKey }) => {
switch(viewKey) {
case 'view_456':
handleContactForm();
break;
case 'view_789':
handleSalesDashboard();
break;
case 'view_321':
handleInventoryTable();
break;
}
});

