Developing custom Bitrix24 list views

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages

Development of Custom List Views in Bitrix24

Standard list views in Bitrix24 — kanban and flat table. This is enough for most tasks. But when you need to show a task hierarchy as a Gantt chart, display deals on a map by customer addresses, or show requests in a calendar view — there are no built-in views. A custom view solves the task of visualizing data in a format convenient for a specific business process.

Embedding Mechanism

A custom list view is implemented through a REST application embedded in the B24 interface through placement. For CRM entity lists, the following are available:

  • CRM_DEAL_LIST_TOOLBAR — button in deal list toolbar
  • CRM_ANALYTICS_TOOLBAR — embedding in CRM analytics
  • REST_APP_URI — fullscreen application as separate section

For a full custom view, it's better to use a separate section in the left menu (LEFT_MENU placement) or embedding as tabs within an existing section through GRID_TOOLBAR.

Logic: the application loads in an iframe, receives authorization context, requests data via REST API (crm.deal.list, crm.item.list, tasks.task.list) and renders it in its own format.

Three Typical Custom Views

1. Map. Deals or contacts with addresses are displayed as markers on Yandex Maps or Leaflet. Clickable markers open the entity card via BX24.openPath('/crm/deal/details/{id}/').

Data for the map: REST request crm.deal.list selecting fields ID, TITLE, UF_CRM_ADDRESS, STAGE_ID, OPPORTUNITY. Address geocoding — on your backend via geocoder API, results cached to avoid recoding on each open.

2. Calendar. Items with dates (deal deadline, event date in smart-process) display in month/week view. FullCalendar library integrates in 1–2 days. Drag-and-drop to move date → call crm.deal.update with new date.

3. Gantt Chart. Tasks or project stages with dependencies. Each item — a segment from DATE_START to DATE_END. Libraries: DHTMLX Gantt (paid, full-featured) or Frappe Gantt (open source, basic). Data from tasks.task.list or custom smart-process.

Working with Large Lists

Bitrix24 REST API returns maximum 50 items per request. For a view showing hundreds of items simultaneously (map with markers, Gantt with tasks), you need pagination.

Optimal strategy — parallel batch requests:

// Get total from first request
BX24.callMethod('crm.deal.list', {
    select: ['ID', 'TITLE', 'UF_CRM_ADDRESS'],
    filter: {'STAGE_SEMANTIC_ID': 'P'}
}, function(result) {
    var total = result.total();
    var pages = Math.ceil(total / 50);

    // Form batch from parallel requests
    var batch = {};
    for (var i = 0; i < pages; i++) {
        batch['page_' + i] = ['crm.deal.list', {
            select: ['ID', 'TITLE', 'UF_CRM_ADDRESS'],
            filter: {'STAGE_SEMANTIC_ID': 'P'},
            start: i * 50
        }];
    }
    BX24.callBatch(batch, renderAll);
});

Batch limit: up to 50 commands in one batch request. For lists with 5000+ items, batch requests are sent sequentially in batches. In practice, 2500 deals load in 3–5 seconds via batch.

Filtering and Synchronization with Main Filter

Critically important: custom view should respect filters set by the user in the standard interface. The problem is that iframe application doesn't have direct access to B24 filter state.

Two approaches:

  • Own filter. Implement filtering inside the application. User configures filters in your UI, they translate to filter parameter in REST request. Simpler to implement, but user works with two different filters.
  • Context passing. Via BX24.placement.info() you can get basic context (entity ID, type). For full filter passing use an intermediate handler: user clicks "Show on map" button in toolbar-placement, application reads current page GET-parameters (where filter is encoded) and applies them.

Client-Side Caching

For views that open often (territory map, project Gantt), implement cache in browser IndexedDB. Schema:

  1. First open — full data load via REST, save to IndexedDB with timestamp
  2. Subsequent open — render from cache, background update request
  3. Cache invalidation — by timer (every 5 minutes) or by event via WebSocket (if B24 Push connected)

Effort Estimation

View Complexity Timeframe
Table with custom columns Low 2–3 days
Calendar (FullCalendar) Medium 4–5 days
Map with markers and clustering Medium 5–7 days
Gantt chart with dependencies High 7–10 days
Dashboard with charts (Chart.js) Medium 4–6 days

Main risk — not UI, but performance with large data volumes. Prototype on real volume: if CRM has 20,000 deals, the view should work with 20,000 deals, not test 50.