I would like to be able to build a datatable that contains a file name in a column (pdf for example).
With a click or a double click on the column I would like to open the file.
Is it possible to create this with bokeh?
Kind Regards
More information is needed. Is this:
- A Bokeh server app?
- Or standalone HTML output?
- Are these files local files on the same computer as the browser?
- Or files on the server that is serving the Bokeh server app?
- Something else? (e.g. remote S3 or URL links?)
It’s not possible to speculate or offer guidance without more details.
More information;
- I wish do this in A Bokeh server app
- The file are on the server that is serving the Bokeh server app
Thanks You
Something along the lines of this maybe, leveraging two things:
- When the user clicks a row in a bokeh DataTable, the CDS driving it actually changes its selected indices property to the selected row/index of the source, and;
- os.system to open stuff locally
So stashing the location of your pdfs into the CDS itself and launching that pdf location via os.system when the user selects a row…
import os
from bokeh.models import ColumnDataSource, DataTable,TableColumn
from bokeh.io import curdoc
table_source = ColumnDataSource(data={'thing':['pdf0','pdf1'],'pdf':['where_is_pdf0.pdf','where_is_pdf1.pdf']})
def file_launcher(attr,old,new):
#get the index of the selected row in the table
ind = table_source.selected.indices[0]
#get the pdf associated with it
pdf = table_source.data['pdf'][ind]
#launch that sucker
os.system(pdf)
tbl = DataTable(columns=[TableColumn(field='Thing',title='Thing')],source)
#tell that function to happen when the selected indices of the datasource driving the table change
table_source.selected.on_change('indices',file_launcher)
hello gmerritt123
I have tested your suggestion and everything works very well.
I realized that I explained myself badly in the last part.
I would like to open the file on the browser which is connected to the bokeh server.
Basically replace the os.system (pdf) command with something that opens the pdf in the client
Not sure what you mean by “in the client”? I’m probably out of my element at this point but I’ll chime in if I can.
@mauroDia I think to view the PDF in the browser, you will need to take the data that is returned (in a CDS possibly, or a DataModel
is another option) and then in a JS callback pass it off to something like PDF.js:
However, I’ve never tried to string all these pieces together, and I have not heard of anyone else doing so either. So it will take some experimentation on your end. You will probably need a custom page template for the Bokeh app to load the PDF.js
source and make it available in a Bokeh CustomJS
callback.
A more sophisticated approach would be to create a Bokeh custom extension that wraps PDF.js
(or a similar tool) but that is a fairly advanced undertaking:
Hello everybody
Sorry for my English.
My purpose is not advanced enough to be able to see it inside the browser using PDF.js, but it is limited to being able to see it.
So for example a pop up window that opens the pdf or any thing that, acting on the datatable, allows me to open a client window which would be fine to see it.
I enclose an example of what I would like to do.
The problem is that the js command doesn’t open the file.
What am I doing wrong?
import os
from bokeh.models import ColumnDataSource, DataTable,TableColumn,Column,CustomJS
from bokeh.io import curdoc
from bokeh.models.widgets import TextInput
table_source = ColumnDataSource(data=
{'thing':['pdf0','pdf1'],
'pdf':['C:\\A\\diapdf\\art1.pdf','C:\\A\\diapdf\\art12.pdf']})
# widget to generate event
widgetEventoOpenFile = TextInput(width=10,visible=False,value='X')
nomeFileWeb=""
openFileCustomJS=CustomJS(code="""
var A= '{0}';
window.open(A);
""" .format (str(nomeFileWeb)))
widgetEventoOpenFile.js_on_change('value',openFileCustomJS)
def file_launcher(attr,old,new):
global widgetEventoOpenFile
global openFileCustomJS
global nomeFileWeb
#get the index of the selected row in the table
ind = table_source.selected.indices[0]
#get the pdf associated with it
nomeFilePDF = table_source.data['pdf'][ind]
nomeRidottoFilePDF=os.path.basename(nomeFilePDF)
nomeFileStatic=" C:\\DiaBi\\static\\pdf\\"+nomeRidottoFilePDF
cmd="copy "+nomeFilePDF+" "+nomeFileStatic+" /Y"
print(cmd)
os.system(cmd)
nomeFileWeb="http://localhost:5006/DiaBi/static/pdf/"+nomeRidottoFilePDF
js_code="""var A= '{0}';window.open(A);""" .format (nomeFileWeb)
print("js_code=",js_code)
openFileCustomJS.code = js_code # update js code
if widgetEventoOpenFile.value=='X':
widgetEventoOpenFile.value = "Y" # call JS
else:
widgetEventoOpenFile.value = "X" # call JS
print("widgetEventoOpenFile.value=",widgetEventoOpenFile.value)
return
tbl = DataTable(columns=[TableColumn(field='thing',title='Thing')],source=table_source)
#tell that function to happen when the selected indices of the datasource driving the table change
table_source.selected.on_change('indices',file_launcher)
layout=Column(tbl)
curdoc().add_root(layout)
# bokeh serve C:\DiaBi C:\Eclipse\eclipse-workspace\BiDia64\testDocumentale.py
# localhost:5006/testDocumentale
Sorry,
I have found my error.
This is the code that do what I wish.
Thanks YOU!!!
import os
from bokeh.models import ColumnDataSource, DataTable,TableColumn,Column,CustomJS,OpenURL
from bokeh.io import curdoc
from bokeh.models.widgets import TextInput
table_source = ColumnDataSource(data=
{'thing':['pdf0','pdf1'],
'pdf':['C:\\A\\diapdf\\art1.pdf','C:\\A\\diapdf\\art12.pdf']})
# widget to generate event
widgetEventoOpenFile = TextInput(width=10,visible=False,value='X')
nomeFileWeb=""
openFileCustomJS=CustomJS(code="""
var A= '{0}';
window.open(A);
""" .format (nomeFileWeb))
widgetEventoOpenFile.js_on_change('value',openFileCustomJS)
def file_launcher(attr,old,new):
global widgetEventoOpenFile
global openFileCustomJS
global nomeFileWeb
#get the index of the selected row in the table
ind = table_source.selected.indices[0]
#get the pdf associated with it
nomeFilePDF = table_source.data['pdf'][ind]
nomeRidottoFilePDF=os.path.basename(nomeFilePDF)
nomeFileStatic=" C:\\DiaBi\\static\\pdf\\"+nomeRidottoFilePDF
cmd="copy "+nomeFilePDF+" "+nomeFileStatic+" /Y"
os.system(cmd)
nomeFileWeb="http://localhost:5006/DiaBi/static/pdf/"+nomeRidottoFilePDF
js_code="""var A= '{0}';window.open(A);""" .format (nomeFileWeb)
openFileCustomJS.code = js_code # update js code
if widgetEventoOpenFile.value=='X':
widgetEventoOpenFile.value = "Y" # call JS
else:
widgetEventoOpenFile.value = "X" # call JS
return
tbl = DataTable(columns=[TableColumn(field='thing',title='Thing')],source=table_source)
#tell that function to happen when the selected indices of the datasource driving the table change
table_source.selected.on_change('indices',file_launcher)
layout=Column(tbl,widgetEventoOpenFile)
curdoc().add_root(layout)
# bokeh serve C:\DiaBi C:\Eclipse\eclipse-workspace\BiDia64\testDocumentale.py
# localhost:5006/testDocumentale
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.