I am attempting to implement a custom widget that a) has one or more child widgets and b) calls some custom functionality from the render() function when the widget displays.
While I have gotten the custom widget with the child widget(s) to display, it appears that the DOM classes aren’t being set on the child widgets, nor is their layout being applied.
I suspect that I am missing call to initialize their layout or something. Does anyone know what I am missing? Any help would be appreciated.
Here is a toy example of my code, boiled down to the simplest case:
class ParentWidget(DOMWidget):
_model_name = Unicode('ParentWidgetModel').tag(sync=True)
_model_module = Unicode(module_name).tag(sync=True)
_model_module_version = Unicode(module_version).tag(sync=True)
_view_name = Unicode('ParentWidgetView').tag(sync=True)
_view_module = Unicode(module_name).tag(sync=True)
_view_module_version = Unicode(module_version).tag(sync=True)
# Declare the child widget
child_widget = Instance(GridBox, ()).tag(sync=True, **widget_serialization)
def __init__(self, **kwargs):
DOMWidget.__init__(self, **kwargs)
# Init the child widget
label = Label(layout=Layout(width='auto', grid_area='label'))
input = Text(layout=Layout(width='auto', grid_area='input'))
self.child_widget = GridBox([label, input], _dom_classes=['childwidget'], layout=Layout(
width='100%',
grid_template_rows='auto auto',
grid_template_columns='25% 75%',
grid_template_areas='"label input"'), **kwargs)
export class ParentWidgetView extends DOMWidgetView {
render() {
super.render();
// Do custom rendering stuff here
// Add the child widget
const parent_element = this.el;
const child_model = this.model.get('child_widget');
this.create_child_view(child_model).then((view) => {
parent_element.appendChild(view.el);
return view;
}).catch(reject('Could not add child to the parent', true));
}
}
export class ParentWidgetModel extends DOMWidgetModel {
static model_name = 'ParentWidgetModel';
static model_module = MODULE_NAME;
static model_module_version = MODULE_VERSION;
static view_name = 'ParentWidgetView';
static view_module = MODULE_NAME;
static view_module_version = MODULE_VERSION;
static serializers: ISerializers = {
...DOMWidgetModel.serializers,
child_widget: {
deserialize: (value: any, manager: ManagerBase<any>|undefined) =>
unpack_models(value, manager as ManagerBase<any>)
}
};
defaults() {
return {
...super.defaults(),
_model_name: ParentWidgetModel.model_name,
_model_module: ParentWidgetModel.model_module,
_model_module_version: ParentWidgetModel.model_module_version,
_view_name: ParentWidgetModel.view_name,
_view_module: ParentWidgetModel.view_module,
_view_module_version: ParentWidgetModel.view_module_version,
child_widget: undefined
};
}
}
If you run this, you’ll notice that the widget and child widget both display, but that the childwidget
class isn’t applied to the child widget, nor is the grid template included.