Vizro AgGrid - how to create clickable link in my ag grid table

Hello!
I have a ag grid table with a column that contains links and text. When there is a link I want to allow user to click on it so that it opens on the next page. I am trying to use pandas data frame (first code snippet below) and tried cell render (second code snippet below) as well however both are not working. Can you please help me implement it?

"""Example app to show all features of Vizro."""
import pandas as pd
from dash import html
from typing import Literal

import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.models.types import capture
from vizro.tables import dash_ag_grid

# GLOBALS --------------------------------------------------------------------->
DROPDOWN_LINK_OPTIONS = [
    {
        "label": "Google",
        "value": "https://google.com",
    },
    {
        "label": "Vizro GitHub",
        "value": "https://github.com/mckinsey/vizro",
    },
    {
        "label": "Vizro Docs",
        "value": "https://vizro.readthedocs.io/",
    },
]

# incorporating data frame
link_options = pd.DataFrame()
link_options = link_options._append(DROPDOWN_LINK_OPTIONS, ignore_index=True)


# convert link value to a clickable link
def create_clickable_link(row):
    return f'<a href="{row["value"]}" target="_blank">{row["value"]}</a>'


link_options['value'] = link_options.apply(create_clickable_link, axis=1)

# PAGE ----------------------------------------------------------------------->
page = vm.Page(
    title="Page Title",
    layout=vm.Layout(grid=[
        [0]
    ]),
    components=[
        vm.AgGrid(figure=dash_ag_grid(link_options,
                                      dashGridOptions={"pagination": True, "exportDataAsCsv": True},
                                      ),

                  )
    ],
)

dashboard = vm.Dashboard(pages=[page])

if __name__ == "__main__":
    Vizro().build(dashboard).run()

JS code added as dashAgGridComponentFunctions.js in “assets” folder.

var dagcomponentfuncs = window.dashAgGridComponentFunctions || {};

dagcomponentfuncs.LinkCellRenderer = function (props) {
    return React.createElement('a', { href: props.value, target: '_blank' }, props.value);
};
"""Example app to show all features of Vizro."""
import pandas as pd
from dash import html
from typing import Literal

import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.models.types import capture
from vizro.tables import dash_ag_grid

# GLOBALS --------------------------------------------------------------------->
DROPDOWN_LINK_OPTIONS = [
    {
        "label": "Google",
        "value": "https://google.com",
    },
    {
        "label": "Vizro GitHub",
        "value": "https://github.com/mckinsey/vizro",
    },
    {
        "label": "Vizro Docs",
        "value": "https://vizro.readthedocs.io/",
    },
]

# incorporating data frame
link_options = pd.DataFrame()
link_options = link_options._append(DROPDOWN_LINK_OPTIONS, ignore_index=True)


# convert link value to a clickable link
def create_clickable_link(row):
    return f'<a href="{row["value"]}" target="_blank">{row["value"]}</a>'


# PAGE ----------------------------------------------------------------------->
page = vm.Page(
    title="Page Title",
    layout=vm.Layout(grid=[
        [0]
    ]),
    components=[
        vm.AgGrid(figure=dash_ag_grid(link_options,
                                      dashGridOptions={"pagination": True, "exportDataAsCsv": True},
                                      columnDefs=[{"headerName": "Label", "field": "label"},
                                                  {"headerName": "Value", "field": "value",
                                                   "cellRenderer": "LinkCellRenderer"}]
                                      ),

                  )
    ],
)

dashboard = vm.Dashboard(pages=[page])

if __name__ == "__main__":
    Vizro().build(dashboard).run()

Thanks!

Hi @sumitmehta12

You can use the markdown component to display the links. Try running this:


import pandas as pd
from dash import html
from typing import Literal

import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.models.types import capture
from vizro.tables import dash_ag_grid

# GLOBALS --------------------------------------------------------------------->
DROPDOWN_LINK_OPTIONS = [
    {
        "label": "Google",
        "value": "https://google.com",
    },
    {
        "label": "Vizro GitHub",
        "value": "https://github.com/mckinsey/vizro",
    },
    {
        "label": "Vizro Docs",
        "value": "https://vizro.readthedocs.io/",
    },
]

# incorporating data frame
link_options = pd.DataFrame()
link_options = link_options._append(DROPDOWN_LINK_OPTIONS, ignore_index=True)


# convert link value to a clickable link
def create_clickable_link(row):
    return f'<a href="{row["value"]}" target="_blank">{row["value"]}</a>'


link_options['value'] = link_options.apply(create_clickable_link, axis=1)

columnDefs = [
    {"field": "label"},
    {"field": "value", "cellRenderer": "markdown"}
]

# PAGE ----------------------------------------------------------------------->
page = vm.Page(
    title="Page Title",
    layout=vm.Layout(grid=[
        [0]
    ]),
    components=[
        vm.AgGrid(
            figure=dash_ag_grid(
                link_options,
                columnDefs=columnDefs,
                dashGridOptions={"pagination": True, "exportDataAsCsv": True},
                dangerously_allow_code=True
            ),
        )
    ],
)

dashboard = vm.Dashboard(pages=[page])

Vizro().build(dashboard).run()


Note that you can avoid having to set dangerously_allow_code=True if you format the links as markdown links. See more info here:

5 Likes

Thank you @AnnMarieW :slightly_smiling_face: This worked however the link opens on the same page. My main purpose of using “create_clickable_link” was to use target=“_blank” property and force the link to open in new window.

Can you please help me find what is missing in that function? Thank you again!

Hello @sumitmehta12,

We actually have a target link in the markdown definition as well.

Pass the columnDef a “linkTarget”:”_blank” and it should open in a new window/tab accordingly.

This needs to be documented. :grin:

2 Likes

Hi @jinnyzor! that worked! Thank you so much :smiley:

2 Likes

Just adding additional information that I experienced when I tried to implement the solution for the project dataframe. I had to additionally modify my function and bring target=“_blank” in the front (see code below). After this I was able to open in the new window.

# convert link value to a clickable link
def create_clickable_link(row):
    return f'<a target="_blank" href="{row["value"]}"> page_link </a>'

You shouldn’t need to do raw html, with markdown and the target link it should work as the above without the dangerous html.

1 Like

Thanks @jinnyzor ! I will give it a try again!

1 Like

Hi @sumitmehta12

Here is an example of opening a new tab with a Markdown link in Dash AG Grid


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

app = Dash(__name__)


columnDefs = [
    {"field": "make"},
    {"field": "model"},
    {"field": "price"},
    {"field": "link", "headerName": "Link opens same tab", "cellRenderer": "markdown"},
    {"field": "link", "headerName": "Link opens new tab", "cellRenderer": "markdown", "linkTarget":"_blank"},
    {"field": "image", "cellRenderer": "markdown"},
]

"""
Note that here, images are loaded from a remote source. They can also be loaded locally using:
    f"![image alt text]({dash.get_asset_url('sun.png')})"
as the cell value.
"""
rain =  "![alt text: rain](https://www.ag-grid.com/example-assets/weather/rain.png)"
sun = "![alt text: sun](https://www.ag-grid.com/example-assets/weather/sun.png)"

rowData = [
    {
        "make": "Toyota",
        "model": "Celica",
        "price": 35000,
        "link": "[Example](#)",
        "image": f"{rain} {rain} {rain} {rain} {rain}"
    },
    {
        "make": "Ford",
        "model": "Mondeo",
        "price": 32000,
        "link": "[Google](https://google.com)",
        "image": sun,
    },
    {
        "make": "Porsche",
        "model": "Boxster",
        "price": 72000,
        "link": "[Example](#)",
        "image": rain
    },
]

app.layout = html.Div(
    [
        dcc.Markdown(
            "Images, links, and other special cell values can be formatted in Markdown by specifying the `cellRenderer` property to be `'markdown'` in the column definition."
        ),
        dag.AgGrid(
            id="cell-renderer-table-4",
            columnSize="sizeToFit",
            columnDefs=columnDefs,
            rowData=rowData,
        ),
    ]
)


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



2 Likes

Thank you, @AnnMarieW! I am able to code the required functionality.