With ipyvuetify, I have to repeatedly use a pair of Textfield
and Textarea
in an ExpansionPanel
.
Their interactions are linked as they are represent two fields from a DB line.
Is it possible to create a custom widget, which contains the different nested ipyvuetify widgets and allows to interact with the whole group as a single object and also is rendered like a widgte when called?
Something like this:
import ipyvuetify as vue
Class customWidget():
def __init__(self, titleText, bodyText):
title = vue.TextField(class_='mb-n2', label='Label')
title.value = titleText
title.on_event('click.stop', None)
openIn= vue.Btn(text=True, max_width='10px', children=[vue.Icon(children=['open_in_new'])])
openIn.on_event('click.stop', None)
note = vue.Textarea(class_='ma-0 pa-0 text-xs-caption', name='markerA', solo=True, elevation=0, outlined=True)
note.value = bodyText
panel = vue.ExpansionPanel(class_='ma-0 pa-0 text-xs-caption', children=[
vue.ExpansionPanelHeader(class_='ma-0 pa-0 pl-5 pr-5', children=[title, openIn]),
vue.ExpansionPanelContent(class_='ma-0 pa-0 text-xs-caption', children=[note]),
])
self.expansionPanel = vue.ExpansionPanels(v_model=[0], multiple=True, focusable=False, children=[panel])
The easiest solution I found so far is to make the customWidget class inherit from the ipyvuetify widget I want to display and prepopulate it with the nested other widgets in the constructor.
This works pretty well and can be set up to still have access to each element even in deeply nested structures.
Care should be taken not to overwrite attributes names which ipyvuetify already uses.
In the case above my solution looks like this:
import ipyvuetify as vue
class customWidget(vue.ExpansionPanels):
def __init__(self, titleText, bodyText, **kwargs):
children = []
title = vue.TextField(
class_ = 'mb-n2',
label = 'Label'
)
title.value = titleText
title.on_event('click.stop', None)
openIn = vue.Btn(
text = True,
max_width = '10px',
children = [
vue.Icon(
children = ['open_in_new']
)
]
)
openIn.on_event('click.stop', None)
note = vue.Textarea(
class_ = 'ma-0 pa-0 text-xs-caption',
name = 'markerA',
solo = True,
elevation = 0,
outlined = True
)
note.value = bodyText
panel = vue.ExpansionPanel(
class_ = 'ma-0 pa-0 text-xs-caption',
children = [
vue.ExpansionPanelHeader(
class_ = 'ma-0 pa-0 pl-5 pr-5',
children = [
title,
openIn
]
),
vue.ExpansionPanelContent(
class_ = 'ma-0 pa-0 text-xs-caption',
children = [
note
]
),
]
)
# add elements to kwargs, this allows to still pass others via the instance call
kwargs['v_model'] = [0]
kwargs['children'] = [panel]
kwargs['multiple'] = True
kwargs['focusable'] = False
super().__init__(**kwargs)