Page and View Events

Page and view events provide the foundation for triggering business logic when users navigate your application and when content is displayed.

⏲️

COMING SOON

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)

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);
});

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;
  }
});