AG Grid with dcc.Clipboard

Based on a request in another post, here is more info on using the dcc.Clipboad component with Dash Ag Grid.

If you want to copy text from the grid, the easiest way is to enable text selection . However if you would like to include a copy button, you can use the dcc.Clipboard in a cell renderer. . The nice thing about using the dcc.Clipboard component is that it’s possible to format the content that’s copied to the clipboard. :tada:

Note for AG Grid Enterprise users - see also: React Data Grid: Clipboard

Example 1 Copy a cell.

ag-grid-dcc-clipboard-cell

In this example, when you click on the copy button, the content of the cell is copied to the clipboard.

A couple of things to note in the JavaScript function

  • It creates a div that includes the content of the cell, props.value, and the dcc.Clipboard component.
  • Use the content prop to specify what is copied to the clipboard. Here we use content: props.value
  • it’s possible to format the content that’s copied to the clipboard. Try changing the content prop to
    content: "Ticker: " + props.value,
  • With dcc.Clipboard, it’s necessary to define setProps as a function in the cell renderer, even though it’s unused. And thanks for that tip @jinnyzor.

import dash_ag_grid as dag
from dash import Dash, html, dcc
import pandas as pd

data = {
    "ticker": ["AAPL", "MSFT", "AMZN", "GOOGL"],
    "company": ["Apple", "Microsoft", "Amazon", "Alphabet"],
    "price": [154.99, 268.65, 100.47, 96.75],
}
df = pd.DataFrame(data)

columnDefs = [

    {"headerName": "Company", "field": "company", "filter": True},
    {
        "headerName": "Last Close Price",
        "type": "rightAligned",
        "field": "price",
        "valueFormatter": {"function": """d3.format("($,.2f")(params.value)"""},
        "editable": True,
    },
    {
        "headerName": "Stock Ticker",
        "field": "ticker",
        "cellRenderer": "DCC_Clipboard",
    },
]

defaultColDef = {
    "resizable": True,
    "sortable": True,
    "editable": False,
}


grid = dag.AgGrid(
    id="grid",
    columnDefs=columnDefs,
    rowData=df.to_dict("records"),
    columnSize="autoSize",
    defaultColDef=defaultColDef,
    dashGridOptions={"rowHeight": 48},
)


app = Dash(__name__)

app.layout = html.Div(
    [
        dcc.Markdown("Example of cellRenderer with custom dcc.Clipboard"),
        grid,
        dcc.Textarea(style={"width": 600})
    ],
    style={"margin": 20},
)



if __name__ == "__main__":
    app.run(debug=True)


"""
Put the following in the dashAgGridComponentFunctions.js file in the assets folder

---------------

var dagcomponentfuncs = window.dashAgGridComponentFunctions = window.dashAgGridComponentFunctions || {};

dagcomponentfuncs.DCC_Clipboard = function (props) {
  return React.createElement("div", {}, [
    props.value,
    React.createElement(window.dash_core_components.Clipboard, {
      content: props.value,
      title: "Copy cell",
      style: {
        display: "inline-block",
        verticalAlign: "top",
        paddingLeft: 10,
        cursor: "pointer",
      },
      setProps: () => {},
    }),
  ]);
};
"""

Example 2 Copy a row

In this example the dcc.Clipboard component is in a separate column. When you click on the icon it copies the entire row.

ag-grid-dcc-clipboard-row

import dash_ag_grid as dag
from dash import Dash, html, dcc
import pandas as pd

data = {
    "ticker": ["AAPL", "MSFT", "AMZN", "GOOGL"],
    "company": ["Apple", "Microsoft", "Amazon", "Alphabet"],
    "price": [154.99, 268.65, 100.47, 96.75],
}
df = pd.DataFrame(data)

columnDefs = [
    {
        "headerName": "",
        "cellRenderer": "CopyRow",
        "lockPosition": "left",
        "maxWidth": 25,
        "filter": False,
        "cellStyle": {"paddingLeft": 5},
    },
    {
        "headerName": "Stock Ticker",
        "field": "ticker",
    },
    {"headerName": "Company", "field": "company", "filter": True},
    {
        "headerName": "Last Close Price",
        "type": "rightAligned",
        "field": "price",
        "valueFormatter": {"function": """d3.format("($,.2f")(params.value)"""},
        "editable": True,
    },
]


defaultColDef = {
    "resizable": True,
    "sortable": True,
    "editable": False,
}


grid = dag.AgGrid(
    id="grid",
    columnDefs=columnDefs,
    rowData=df.to_dict("records"),
    columnSize="autoSize",
    defaultColDef=defaultColDef,
    dashGridOptions={"rowHeight": 48},
)


app = Dash(__name__)

app.layout = html.Div(
    [
        dcc.Markdown("Example of cellRenderer with custom dcc.Clipboard"),
        grid,
        dcc.Textarea(style={"width": 600}),
    ],
    style={"margin": 20},
)


if __name__ == "__main__":
    app.run(debug=True)


"""
Put the following in the dashAgGridComponentFunctions.js file in the assets folder

---------------

var dagcomponentfuncs = window.dashAgGridComponentFunctions = window.dashAgGridComponentFunctions || {};

dagcomponentfuncs.CopyRow = function (props) {
  return React.createElement("div", {}, [
    React.createElement(window.dash_core_components.Clipboard, {
      content: JSON.stringify(props.data),
      title: "Copy Row",
      style: {
        display: "inline-block",        
        verticalAlign: "top",
        paddingLeft: 3,
        cursor: "pointer",
      },
      setProps: () => {},
    }),
  ]);
};

"""


Pro tip:
To see what’s included with the props in the cell renderer function, include a console.log() before the return statement, then you can see it in the browser console.

dagcomponentfuncs.DCC_Clipboard = function (props) {
  console.log("props", props)
  return React.createElement("div", {}, [
     
7 Likes

Thank you @AnnMarieW for those interesting examples! :rainbow:
You should tag “dag-docs” :wink:

2 Likes

Huge thanks, @AnnMarieW. I think the latest bit I was missing was setProps in the JS code. I had the content and title set to props.value and could verify on hovering that the values are correct, but clicking the clipboard icon was not doing anything.

1 Like