Injecting javascript to sort the table which has hyperlinks

Hey, Iā€™m using Streamlit framework in python to display a pandas table that consists of links and prices of some items but I want the links to be hyperlinked and the table should still be dynamic and sortable. I managed to inject js but it gets injected into an iframe when I use the components.html() so the obvious workaround for this would be as follows

import pandas as pd
import streamlit as st
from streamlit.components.v1 import html

data = [["Item 1", "https://www.item1.com", "$10"],
        ["Item 3", "https://www.item3.com", "$30"],
        ["Item 2", "https://www.item2.com", "$20"],]

df = pd.DataFrame(data, columns=["Name", "Link", "Price"])

def make_clickable(val):
    return f'<a href="{val}">{val}</a>'

df["Link"] = df["Link"].apply(make_clickable)
tablehtml = df.to_html(escape=False, index=False, table_id="myTable")
## Add the hyperlinked table to webpage
st.write(tablehtml, unsafe_allow_html=True)

This outputs a table like this which cant sort

before

Adding the following fixes that

html('''
<script src='https://cdnjs.cloudflare.com/ajax/libs/tablesort/5.0.2/tablesort.min.js'></script>
<script>
    var table = window.parent.document.getElementById("myTable");
    console.log("ye")
    console.log(table.id);
</script>
<script>new Tablesort(window.parent.document.getElementById("myTable"));</script>
''')

Note: The html() creates an iframe and its not directly injected to the main page, this means that the iframe cant access the main page if we use document.getElementById("myTable") but we can use window.parent.document.getElementById("myTable") and allow it to access the main page content

The final result

after

I made this tutorial as I wasted like 3 days to find a fix for this i could only find ways to make the table into a hyperlinked one or just normally sort it.

2 Likes