Skip to content

Grid Events

Example 1

Ag-Grid supports many events. Let's look at some examples.

To begin, let's display in a separate Div the data from a grid row when it is selected.

import justpy as jp
import pandas as pd

wm_df = pd.read_csv('https://elimintz.github.io/women_majors.csv').round(2)

def row_selected2(self, msg):
    print(msg)
    if msg.selected:
        self.row_data_div.text = msg.data
        self.row_selected2 = msg.rowIndex
    elif self.row_selected2 == msg.rowIndex:
        self.row_data_div.text = ''

def grid_test11():
    wp = jp.WebPage()
    row_data_div = jp.Div(a=wp)
    grid = wm_df.jp.ag_grid(a=wp)
    grid.row_data_div = row_data_div
    grid.on('rowSelected', row_selected2)
    grid.options.columnDefs[0].checkboxSelection = True
    return wp

jp.justpy(grid_test11)

We add a Div named row_data_div to the page and the row_selected2 function, the event handler for the grid's rowSelected event, sets the row data as the text of the Div.

JustPy provides in msg.data all the data from the row in a form of a dictionary whose keys are the column names. msg.selected is set to True if the row was selected and to False if the row was de-selected. Both selection and de-selection fire the same rowSelected event and msg.selected can be used to distinguish between them.

The index of the row for which the selection or de-selection occurred is found in msg.rowIndex. If the same row that was previously selected is deselected, row_data_div content is set to the empty string.

Example 2

This previous example is not very interesting. Let's change it to display a chart of the selected row instead.

import justpy as jp
import pandas as pd

wm_df = pd.read_csv('https://elimintz.github.io/women_majors.csv').round(2)

def row_selected3(self, msg):
    print(msg)
    if msg.selected:
        categories, values = list(msg.data.keys()), list(msg.data.values())
        o = self.row_chart.options
        o.title.text = f'{values[0]} - Percent Women in Major'
        o.xAxis.categories = categories[1:]
        s = jp.Dict({'name': values[0], 'data': values[1:]})
        s.dataLabels.enabled = True
        if len(o.series) > 0:
            o.series[0] = s
        else:
            o.series.append(s)
        self.row_selected3 = msg.rowIndex
        self.row_chart.show = True
    elif self.row_selected3 == msg.rowIndex:
        self.row_chart.show = False

def grid_test12():
    wp = jp.WebPage()
    row_chart = jp.HighCharts(a=wp)
    row_chart.options.chart.type = 'column'
    row_chart.options.yAxis.title.text = '%'
    row_chart.show = False
    grid = wm_df.jp.ag_grid(a=wp)
    grid.row_chart = row_chart
    grid.on('rowSelected', row_selected3)
    grid.options.columnDefs[0].checkboxSelection = True
    return wp

jp.justpy(grid_test12)

The chart is created once when the page is requested, but the first and only series in it is changed to reflect the new values once a row is selected.

Example 3 - Multiple Row Selection

import justpy as jp

grid_options = """
{
    rowSelection: 'multiple',
    defaultColDef: {
        filter: true,
        sortable: true,
        resizable: true,
        cellStyle: {textAlign: 'center'},
        headerClass: 'font-bold'
    }, 
      columnDefs: [
      {headerName: "Make", field: "make"},
      {headerName: "Model", field: "model"},
      {headerName: "Price", field: "price"}
    ],
      rowData: [
      {make: "Toyota", model: "Celica", price: 35000},
      {make: "Ford", model: "Mondeo", price: 32000},
      {make: "Porsche", model: "Boxter", price: 72000}
    ]
}
"""


def row_selected4(self, msg):
    print(msg.selected, msg)
    wp = msg.page
    row_id = msg.row_id
    if msg.selected:
        wp.selected_rows[row_id] = msg.data
    else:
        wp.selected_rows.pop(row_id)
    s = f'Selected rows {sorted(list(wp.selected_rows.keys()))}'
    for i in sorted(wp.selected_rows):
        s = f'{s}\n Row {i}  Data: {wp.selected_rows[i]}'
    if wp.selected_rows:
        wp.rows_div.text = s
    else:
        wp.rows_div.text = 'No row selected'


def grid_test13():
    wp = jp.WebPage()
    wp.selected_rows = {}  # Dictionary holding selected rows
    grid = jp.AgGrid(a=wp, options=grid_options, style='height: 200px; width: 300px; margin: 0.25em')
    grid.options.columnDefs[0].checkboxSelection = True
    grid.on('rowSelected', row_selected4)
    wp.rows_div = jp.Pre(text='Data will go here when you select rows', classes='border text-lg', a=wp)
    return wp

jp.justpy(grid_test13)

Event Properties

Ag-Grid supports many events. All the events supported by the community version can be captured and acted upon using JustPy. Each event contains different properties most of which JustPy makes available to the event handler through its second argument (msg in the tutorial).

A simple way to see which properties are available is to print msg. Another way is to go here.

In the case of an event being one of ['sortChanged', 'filterChanged', 'columnMoved', 'rowDragEnd'] all the data in the gird after sorting and filtering is put into msg.data in CSV format.

Warning

When working with websockets, the size of each message is limited to 1 MByte when using uvicorn, so if your tables are larger, use Ajax by setting the websockets key word argument of the justpy command to False.

Linking a chart and a grid using grid events

Using grid events, it requires a few lines of code to link a grid to a chart. Filtering and sorting changes in the grid, will be reflected in the chart.

import justpy as jp
import pandas as pd

df = pd.read_csv('https://raw.githubusercontent.com/fivethirtyeight/data/master/alcohol-consumption/drinks.csv', encoding="ISO-8859-1")

def grid_change(self, msg):
    msg.page.df = jp.read_csv_from_string(msg.data)
    c = msg.page.df.jp.plot(0, [1,2,3,4], kind='column', classes='m-2 p-2 w-2/3 border', title='Alcohol Consumption per Country')
    msg.page.c.options = c.options

def grid_test14():
    wp = jp.WebPage()
    wp.df = df
    wp.c = df.jp.plot(0, [1,2,3,4], kind='column', a=wp, classes='m-2 p-2 border', title='Alcohol Consumption per Country')
    grid = df.jp.ag_grid(a=wp)
    grid.options.columnDefs[0].rowDrag = True
    for event_name in ['sortChanged', 'filterChanged', 'columnMoved', 'rowDragEnd']:
        grid.on(event_name, grid_change)
    return wp

jp.justpy(grid_test14)

The example above can be simplified even further by creating a component in which a chart and a grid are linked. With the new component in hand, charts and grids can be linked with one line of code.

import justpy as jp
import pandas as pd

class LinkedChartGrid(jp.Div):

    def __init__(self, df, x, y, **kwargs):
        super().__init__(**kwargs)
        self.df = df
        self.x = x
        self.y = y
        self.kind = kwargs.get('kind', 'column')
        self.stacking = kwargs.get('stacking', '')
        self.title = kwargs.get('title', '')
        self.subtitle = kwargs.get('subtitle', '')
        self.set_classes('flex flex-col')
        self.chart = df.jp.plot(x, y, a=self, classes='m-2 p-2 border', kind=self.kind, stacking=self.stacking, title=self.title, subtitle=self.subtitle)
        self.grid = df.jp.ag_grid(a=self)
        self.grid.parent = self
        self.grid.options.columnDefs[0].rowDrag = True
        for event_name in ['sortChanged', 'filterChanged', 'columnMoved', 'rowDragEnd']:
            self.grid.on(event_name, self.grid_change)


    @staticmethod
    def grid_change(self, msg):
        self.parent.df = jp.read_csv_from_string(msg.data)
        c = self.parent.df.jp.plot(self.parent.x, self.parent.y, kind=self.parent.kind, title=self.parent.title,
                                   subtitle=self.parent.subtitle, stacking=self.parent.stacking)
        self.parent.chart.options = c.options



alcohol_df = pd.read_csv('https://raw.githubusercontent.com/fivethirtyeight/data/master/alcohol-consumption/drinks.csv', encoding="ISO-8859-1")
bad_drivers_df = pd.read_csv('https://raw.githubusercontent.com/fivethirtyeight/data/master/bad-drivers/bad-drivers.csv', encoding="ISO-8859-1")


def grid_test15():
    wp = jp.WebPage()
    c = LinkedChartGrid(alcohol_df, 0, [1,2,3,4], kind='column', a=wp, classes='m-4 p-2 border',
                        stacking='normal', title='Alcohol Consumption per Country', subtitle='538 data')
    LinkedChartGrid(bad_drivers_df, 0, [1,2,3,4,5,6,7], kind='column', a=wp, classes='m-4 p-2 border-4', title='Bad Drivers per US State', subtitle='538 data')
    return wp

jp.justpy(grid_test15)