vizro icon indicating copy to clipboard operation
vizro copied to clipboard

Use vizro.models.button to switch to another page

Open Tom-Sachs opened this issue 1 year ago • 1 comments

Question

Hi there!

As far as I know, the only way to create a clicktable container/button to switch to another Page is to use a Card, and use the href parameter.

I was wondering if this was possible to do the same thing using Button instead of Card ? The Button design seems a bit more user-friendly. At the moment, Button needs to take an action as an input, but the only two actions available are filter actions, or data exports, so I haven't found a way to do this.

Thank you!

Code/Examples

No response

Other information

No response

vizro version

No response

Python version

No response

OS

No response

Code of Conduct

Tom-Sachs avatar Nov 30 '23 08:11 Tom-Sachs

Hi @Tom-Sachs, great question! Currently, we are working on enabling this feature natively through the vm.Button component. However, this behaviour is already possible to construct utilising the custom components and here is an example on how to achieve it:

# Inherit the Vizro Button model in purpose to slightly modify its behaviour
class HrefButton(vm.Button):
    href: str = "/"

    def build(self):
        # Calling vm.Button build method that returns the html.Div object:
        # html.Div(
        #     [
        #         dbc.Button(
        #             id=self.id,
        #             children=self.text,
        #             className="button_primary",
        #         ),
        #     ],
        #     className="button_container",
        #     id=f"{self.id}_outer",
        # )
        button_build_obj = super().build()
        # button_build_obj[self.id] fetches the underlying dbc.Button object
        button_build_obj[self.id].href = self.href
        # Modified object with the "href" attributed is returned
        return button_build_obj 

dashboard = vm.Dashboard(
    pages=[
        vm.Page(
            title="Homepage",
            components=[
                HrefButton(
                    text="Go to analysis",    # Inherited vm.Button attribute
                    href="/analysis",    # Additionally added attribute in the HrefButton implementation
                ),
            ]
        ),
        vm.Page(
            title="Analysis",
            components=[
                vm.Card(text="Analysis")
            ]
        )
    ]
)

Vizro().build(dashboard).run()

Instead of calling super().build() inside the HrefButton build method, there is an option to completely copy-paste vm.Button build method implementation and then just adjust it by adding the href attribute as a dbc.Button argument.


class HrefButton(vm.Button):
    href: str = "/"

    def build(self):
        return html.Div(
            [
                dbc.Button(
                    id=self.id,
                    children=self.text,
                    className="button_primary",
                    href=self.href  # Additionally added argument
                ),
            ],
            className="button_container",
            id=f"{self.id}_outer",
        )

N.B. If you need to use this component in some of dict/json/yaml configuration, you need to set the discriminator "type" as the additional class attribute and to extend supported types of the Page.components. You can achieve it in a following way:

class HrefButton(vm.Button):
    href: str = "/"
    type: Literal["href_button"] = "href_button"

   ...

vm.Page.add_type("components", HrefButton)

...
# Configuration in dict, json or yaml format

Let us know does the suggested solution work for you, we are happy to help. 😄

petar-qb avatar Dec 01 '23 09:12 petar-qb