Skip to content
PDF

Communication Between Different Tiles

Overview

Smart Pages tiles can communicate with each other and with other Smart View components through a message bus system. This enables dynamic, interactive interfaces where tiles can react to user actions and update their content accordingly.

Tile Communication Overview

Placeholder for Image

Add a diagram showing tile communication architecture

Radio Channel Communication

All tile communication in Smart Pages uses the Radio channel messaging system. The primary channel used is ampagenotify, which acts as a centralized message bus for all tile interactions.

Initializing the Radio Channel

Before tiles can communicate, they need to initialize the Radio channel:

csui.onReady2([
    'csui/lib/jquery',
    'csui/lib/underscore',
    'csui/lib/radio'
], function(jQ, _, Radio) {
    // Get the page message bus
    var amChannel = Radio.channel('ampagenotify');

    // Now tiles can communicate through amChannel
});

Communication Patterns

Pattern 1: Command-Based Communication

Tiles can trigger commands that other tiles listen for. This is the most common pattern for tile communication.

Sending Commands

// In Tile A's data source widgetConfig
html: """
    <script>
        csui.onReady2(['csui/lib/radio'], function(Radio) {
            var amChannel = Radio.channel('ampagenotify');

            // Trigger a command
            amChannel.trigger("updateChart", [
                {name: "filter", value: "active"}
            ]);
        });
    </script>
"""

Receiving Commands

// In Tile B's data source widgetConfig
html: """
    <script>
        csui.onReady2(['csui/lib/radio'], function(Radio) {
            var amChannel = Radio.channel('ampagenotify');

            // Listen for command
            amChannel.on("updateChart", function(params) {
                // Process params and update tile
                console.log("Received updateChart command", params);
                // Reload tile data or update UI
            });
        });
    </script>
"""

Pattern 2: Request-Response Communication

Tiles can request data from other tiles using the request pattern.

Making Requests

// Request data from another tile
var chart = amChannel.request("ampages:myChart");
if (chart) {
    // Use the chart object
    chart.updateData(newData);
}

Providing Data

// Register data provider
amChannel.reply("ampages:myChart", function() {
    return myChartInstance;
});

Pattern 3: Event Broadcasting

Tiles can broadcast events that multiple tiles can listen to.

Broadcasting Events

// Broadcast an event
amChannel.trigger("tile:dataUpdated", {
    tileId: "chart_1",
    data: newData
});

Listening to Events

// Listen for events
amChannel.on("tile:dataUpdated", function(eventData) {
    if (eventData.tileId === "chart_1") {
        // React to chart update
        updateRelatedTile(eventData.data);
    }
});

Common Communication Scenarios

Scenario 1: Chart and Filter Tiles

A filter tile updates a chart tile when filters change.

Filter Tile (Sender)

// In filter tile's data source
if(params.widgetConfig){
    json(widgetConfig: [
        html: """
            <script>
                csui.onReady2(['csui/lib/jquery', 'csui/lib/radio'], 
                    function($, Radio) {
                        var amChannel = Radio.channel('ampagenotify');

                        $('#filterInput').on('change', function() {
                            var filterValue = $(this).val();
                            amChannel.trigger("updateChart", [
                                {name: "filter", value: filterValue}
                            ]);
                        });
                    });
            </script>
            <input id="filterInput" type="text" placeholder="Filter...">
        """
    ])
}

Chart Tile (Receiver)

// In chart tile's data source
if(params.widgetConfig){
    json(widgetConfig: [
        reloadCommands: ["updateChart"],  // Tile will reload when this command is triggered
        html: """
            <script>
                csui.onReady2(['csui/lib/radio'], function(Radio) {
                    var amChannel = Radio.channel('ampagenotify');

                    amChannel.on("updateChart", function(params) {
                        // The tile will automatically reload
                        // because "updateChart" is in reloadCommands
                    });
                });
            </script>
        """
    ])
} else {
    // Generate chart data based on params.filter
    def filter = params.filter ?: "all"
    // ... generate chart data ...
    json([/* chart data */])
}

Chart and Filter Communication

Placeholder for Image

Add a screenshot showing a filter tile updating a chart tile

A links tile triggers navigation or actions that update a node table.

// In links tile's data source
json([
    data: [
        links: [
            [
                name: "Show Active Items",
                url: "#",
                action: "notify",
                command: "updateNodeTable",
                params: "active"
            ],
            [
                name: "Show All Items",
                url: "#",
                action: "notify",
                command: "updateNodeTable",
                params: "all"
            ]
        ]
    ]
])

Node Table Tile (Receiver)

// In node table tile's data source
if(params.widgetConfig){
    json([
        widgetConfig: [
            reloadCommands: ["updateNodeTable"]
        ]
    ])
} else {
    // Generate node list based on params.filter
    def filter = params.tile ?: "all"
    // ... query nodes based on filter ...
    json([/* node data */])
}

Scenario 3: Tree Tile and Content Display

A tree tile triggers content display in another tile when nodes are selected.

Tree Tile (Sender)

// In tree tile's data source
data = [
    [
        id: 2000,
        text: "Documents",
        action: "notify",
        params: "2000"
    ]
]

json(data)

The tree tile configuration should include:

if(params.widgetConfig){
    json([
        widgetConfig: [
            html: """
                <script>
                    csui.onReady2(['csui/lib/radio'], function(Radio) {
                        var amChannel = Radio.channel('ampagenotify');

                        // Tree will trigger "notify" action when node is clicked
                        // This will trigger the command specified in params
                    });
                </script>
            """
        ]
    ])
}

Content Tile (Receiver)

// In content display tile's data source
if(params.widgetConfig){
    json([
        widgetConfig: [
            reloadCommands: ["showNodeContent"]
        ]
    ])
} else {
    // Display content for the selected node
    def nodeId = params.tile ?: 2000
    def node = docman.getNodeFast(nodeId as long)
    // ... generate content display ...
    json([/* content data */])
}

Scenario 4: Smart Page Actions

Tiles can trigger Smart Page-level actions that affect multiple tiles.

Triggering Smart Page Actions

// In any tile's data source
json([
    data: [
        links: [
            [
                name: "Refresh All",
                url: "#",
                command: "smartPage",  // Notify Smart Page
                action: "refreshAll",   // Action name
                params: ""             // Action parameters
            ]
        ]
    ]
])

Smart Page Action Handler

// In Smart Page template or tile widgetConfig
html: """
    <script>
        csui.onReady2(['csui/lib/radio'], function(Radio) {
            var amChannel = Radio.channel('ampagenotify');

            amChannel.on("smartPage_action", function(action, param) {
                if (action === "refreshAll") {
                    // Trigger reload for multiple tiles
                    amChannel.trigger("updateChart", []);
                    amChannel.trigger("updateNodeTable", []);
                    amChannel.trigger("updateLinks", []);
                }
            });
        });
    </script>
"""

Reload Commands

The reloadCommands configuration option allows tiles to automatically reload when specific commands are triggered.

Configuration

if(params.widgetConfig){
    json([
        widgetConfig: [
            reloadCommands: [
                "updateChart",
                "refreshData",
                "filterChanged"
            ]
        ]
    ])
}

When any of these commands are triggered via amChannel.trigger(), the tile will automatically reload its data source.

Benefits

  • Automatic synchronization: Tiles stay in sync without manual reload code
  • Simplified code: No need to manually call reload functions
  • Consistent behavior: All tiles use the same reload mechanism

Best Practices

Command Naming

  • Use descriptive names: updateChart is better than cmd1
  • Follow conventions: Use camelCase for command names
  • Namespace when needed: Use prefixes like tile:, page:, chart: to avoid conflicts

Error Handling

amChannel.on("updateChart", function(params) {
    try {
        // Process command
    } catch (error) {
        console.error("Error processing updateChart:", error);
        // Show user-friendly error message
    }
});

Performance

  • Debounce rapid updates: Use debouncing for frequently triggered commands
  • Batch updates: Combine multiple updates into a single command when possible
  • Clean up listeners: Remove event listeners when tiles are destroyed

Debugging

// Enable debug logging
amChannel.on("all", function(eventName, ...args) {
    console.log("Radio event:", eventName, args);
});

Advanced Patterns

Pattern: Observer Pattern

Multiple tiles observe a single data source tile:

// Data source tile broadcasts updates
amChannel.trigger("dataSource:updated", {
    data: newData,
    timestamp: Date.now()
});

// Multiple observer tiles listen
amChannel.on("dataSource:updated", function(eventData) {
    updateTile(eventData.data);
});

Pattern: Mediator Pattern

A central mediator tile coordinates communication between multiple tiles:

// Mediator tile
amChannel.on("tileA:action", function(data) {
    // Process and forward to tile B
    amChannel.trigger("tileB:update", processedData);
});

amChannel.on("tileB:response", function(data) {
    // Process and forward to tile C
    amChannel.trigger("tileC:update", processedData);
});

Next Steps