Directory Dialog: Modal Size

I’ve modified @riziles Fast File Selection demo into a Modal Directory Dialog. I have 2 nagging questions:

  1. How do I manage the size of the modal?
  2. How do I left justify text in a selector or text field?
import os
import pathlib

import panel as pn
import param


def on_accept(self):
    selected_directory.value = self.current_dir
    template.close_modal()


class DirectoryDialog(param.Parameterized):
    selection = param.Selector(
        default="",
        label="Browse",
    )
    current_dir = param.String(
        default="/",
        label="Current Directory",
        constant=True,
    )

    accept = param.Action(
        on_accept,
        label="Accept",
    )
    _contents_map = param.Dict()

    @param.depends("selection", watch=True)
    def change_dir(self):
        if self.selection:
            with param.edit_constant(self):
                self.current_dir = str(self._contents_map[self.selection])
        self.selection = ""

    @param.depends("current_dir", watch=True, on_init=True)
    def refesh_list(self):
        contents = {}
        if self.current_dir:
            self.param["selection"].objects = [""]
            contents[""] = None
            contents["\u2ba0"] = pathlib.Path(self.current_dir).parent
            try:
                for i in pathlib.Path(self.current_dir).iterdir():
                    if i.is_dir() and not i.name.startswith((".", "_")):
                        contents[i.name] = i
            except Exception as e:
                contents[str(e)] = pathlib.Path(self.current_dir)

            self._contents_map = dict(sorted(contents.items()))
            items = list(contents.keys())
            items[2:] = sorted(items[2:])
            self.param["selection"].objects = items
        self.selection = ""


def create_panel(current_dir=os.getcwd()):
    dd = DirectoryDialog(name="Select Directory", current_dir=current_dir)
    return pn.Param(dd.param, parameters=["selection", "current_dir", "accept"])


def dialog_open(event):
    template.open_modal()


selected_directory = pn.widgets.TextInput(name="Selected Directory", value="")
select_dir_btn = pn.widgets.Button(name="Select Directory")
select_dir_btn.on_click(dialog_open)

template = pn.template.BootstrapTemplate(title="Directory Dialog Demo")
template.modal.append(create_panel)
template.main.append(pn.Column(selected_directory, select_dir_btn))

pn.serve(
    template,
    show=False,
    port=5099,
    websocket_origin="*",
    autoreload=True,
)

Same problem here. I am trying to display a Tabulator table in the modal, but it just won’t display all of it. Is there any way to set the dimensions of the modal?

Modal Directory Dialog

@skytaker

You can use raw_css. First you will need to figure out what to add. You do that by inspecting the css of the modal.

You will see that you need to change the width or max-width of the modal-dialog. For example you can set

RAW_CSS = """
@media (min-width: 576px) {
  .modal-dialog {
    max-width: 500px;
  }
}
"""

import os
import pathlib

import panel as pn
import param

pn.extension()


def on_accept(self):
    selected_directory.value = self.current_dir
    template.close_modal()


class DirectoryDialog(param.Parameterized):
    selection = param.Selector(
        default="",
        label="Browse",
    )
    current_dir = param.String(
        default="/",
        label="Current Directory",
        constant=True,
    )

    accept = param.Action(
        on_accept,
        label="Accept",
    )
    _contents_map = param.Dict()

    @param.depends("selection", watch=True)
    def change_dir(self):
        if self.selection:
            with param.edit_constant(self):
                self.current_dir = str(self._contents_map[self.selection])
        self.selection = ""

    @param.depends("current_dir", watch=True, on_init=True)
    def refesh_list(self):
        contents = {}
        if self.current_dir:
            self.param["selection"].objects = [""]
            contents[""] = None
            contents["\u2ba0"] = pathlib.Path(self.current_dir).parent
            try:
                for i in pathlib.Path(self.current_dir).iterdir():
                    if i.is_dir() and not i.name.startswith((".", "_")):
                        contents[i.name] = i
            except Exception as e:
                contents[str(e)] = pathlib.Path(self.current_dir)

            self._contents_map = dict(sorted(contents.items()))
            items = list(contents.keys())
            items[2:] = sorted(items[2:])
            self.param["selection"].objects = items
        self.selection = ""


def create_panel(current_dir=os.getcwd()):
    dd = DirectoryDialog(name="Select Directory", current_dir=current_dir)
    return pn.Param(dd.param, parameters=["selection", "current_dir", "accept"])


def dialog_open(event):
    template.open_modal()


selected_directory = pn.widgets.TextInput(name="Selected Directory", value="")
select_dir_btn = pn.widgets.Button(name="Select Directory")
select_dir_btn.on_click(dialog_open)

RAW_CSS = """
@media (min-width: 576px) {
  .modal-dialog {
    max-width: 500px;
  }
}
"""

template = pn.template.BootstrapTemplate(title="Directory Dialog Demo", 
    raw_css=[RAW_CSS]
)
template.modal.append(create_panel)
template.main.append(pn.Column(selected_directory, select_dir_btn))

template.servable()
1 Like

Tabulator table in Modal

Hi @contango. Without a minimum, reproducible example its hard for me to know if the problem is the modal, tabulator or something third.

But it can work

import panel as pn
import pandas as pd

pn.extension("tabulator", sizing_mode="stretch_width")

data = pd.DataFrame({
    "x": [1,2],
    "y": [1,2],
})

table = pn.widgets.Tabulator(data)
submit = pn.widgets.Button(name="Submit")

RAW_CSS = """
@media (min-width: 576px) {
  .modal-dialog {
    max-width: 250px;
  }
}
"""

template = pn.template.BootstrapTemplate(site="Panel", title="App", main=[submit], modal=[table], raw_css=[RAW_CSS])

pn.bind(lambda e: template.open_modal(), submit, watch=True)
template.servable()
1 Like

@skytaker

Regarding left justify. I don’t understand the question. Could you provide a minimum, reproducible code example and a screenshot of what is not working/ how it should be working?

1 Like