As side note, you get more help if the code is ready to be copied, pasted and run without modification.
Going to the point, there was 2 problems, in the upd function it was missing an event argunment and in the JS code the \n needs two “\”. Below you can finde the whole code and a video showing how it works.
import pandas as pd
from bokeh.layouts import column
from bokeh.models import (ColumnDataSource, CustomJS,
Select, Button)
from bokeh.plotting import curdoc
from os.path import dirname, join
dummysel = Select(value='n', options=['y', 'n'])
df = pd.DataFrame()
global source
source = ColumnDataSource(df)
def upd(e):
global df, source
data = {
'A': ['A1', 'A2', 'A3', 'A4', 'A5'],
'B': ['B1', 'B2', 'B3', 'B4', 'B4'],
'C': ['C1', 'C2', 'C3', 'C3', 'C3'],
'D': ['D1', 'D2', 'D2', 'D2', 'D2'],
'E': ['E1', 'E1', 'E1', 'E1', 'E1']
}
df = pd.DataFrame(data)
cds = ColumnDataSource(df)
source.data = dict(cds.data)
print(dummysel.value)
dummysel.value = 'y' # change to value to trigger the download
print(dummysel.value) # correctly shows changed value (from n to y) but download doesn't happen
print(source.data)
dlbutton = Button(label="print", button_type="success",width=100)
js_code = """
function table_to_csv(source) {
const columns = Object.keys(source.data)
const nrows = source.get_length()
const lines = [columns.join(',')]
for (let i = 0; i < nrows; i++) {
let row = [];
for (let j = 0; j < columns.length; j++) {
const column = columns[j];
row.push(source.data[column][i].toString());
}
lines.push(row.join(','))
}
return(lines.join('\\n').concat('\\n'));
}
let lines = table_to_csv(source);
console.log(lines)
const filename = 'data_result.csv'
const filetext = table_to_csv(source)
const blob = new Blob([filetext], { type: 'text/csv;charset=utf-8;' })
//addresses IE
if (navigator.msSaveBlob) {
navigator.msSaveBlob(blob, filename)
} else {
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.download = filename
link.target = '_blank'
link.style.visibility = 'hidden'
link.dispatchEvent(new MouseEvent('click'))
}
"""
dummysel.js_on_change('value',CustomJS(args=dict(source=source),
code=js_code))
dlbutton.on_click(upd)
col = column(dlbutton, dummysel)
curdoc().add_root(col)