I don’t love the folder navigation interface in the FileSelector widget, so I built a separate widget for when I need to quickly navigate directories AND only need to select one file:
import pathlib
import param
import panel as pn
class FastFileSelector(param.Parameterized):
current_dir = param.String(default = '/')
filter = param.String(default = '*')
selection = param.Selector(default = '')
_contents_map = param.Dict()
@param.depends('selection', watch = True)
def change_dir(self):
if self.selection and self.selection[-1] == '/':
self.current_dir = str(self._contents_map[self.selection])
@param.depends('current_dir', 'filter', watch = True, on_init = True)
def refesh_list(self):
contents = {}
if self.current_dir and self.filter:
self.param['selection'].objects = ['']
contents[''] = None
contents['../'] = pathlib.Path(self.current_dir).parent
try:
for i in pathlib.Path(self.current_dir).iterdir():
if i.is_dir():
contents['./' + i.name + '/'] = i
for i in pathlib.Path(self.current_dir).glob(self.filter):
if not i.is_dir():
contents[i.name] = i
except Exception as e:
contents[str(e)] = pathlib.Path(self.current_dir)
self._contents_map = dict(sorted(contents.items()))
self.param['selection'].objects = list(sorted(contents.keys()))
self.selection = ''
def create_panel(current_dir = '/', filter = '*'):
ffs = FastFileSelector(
current_dir = current_dir,
filter = filter
)
return pn.Param(
ffs.param,
parameters = ['current_dir','filter','selection']
)
if __name__ == '__main__':
pn.serve(create_panel)