jp_proxy_widget
jp_proxy_widget copied to clipboard
Detachable / floating jp_proxy_widget example?
Do you know of any examples of detaching a jp_proxy_widget
instance so that it can be detached from the output area of the cell that displays it so that it can float or be dragged around the notebook? (This makes the widget more useful it it is accessed / referenced from multiple other cells in a notebook.)
An example in this ipywidgets
issue using the following approach to display a floating panel at the top of the notebook:
display(Javascript("""$('div.job_widget')
.detach()
.appendTo($('#header'))
.css({
'z-index': 999,
'position': 'fixed',
'box-shadow': '5px 5px 5px -3px black',
'opacity': 0.95,
'float': 'left,'
})
"""))
It's easy enough to add the css attributes to the widget, but is there a simple way of detaching it and appending it to the notebook $('#header')
?
Look here
https://github.com/AaronWatters/jp_doodle/blob/master/notebooks/workshop/3%20-%20Silly%20example.ipynb
demo.in_dialog()
Here is the implementation:
https://github.com/AaronWatters/jp_doodle/blob/master/jp_doodle/dual_canvas.py#L563
I think this should work with other proxy widgets. Let me know if this is not what you had in mind.
Ah, that demo looks like it could be exactly what I need. Will give it a go. Thanks..
PS ..element.dialog()
does the job nicely.... Thanks:-)
Just following on from that, I'm now wondering if there's any easy way to also pull in some of the jquery.dialogextend.js
features, such as the ability to launch full screen view, or collapsed view?
eg it'd be nice to be able to say something like:
widget.element.dialog().dialogExtend({"closable":True,
"maximizable" :True,
"minimizable" :True,
"collapsable" :True})
etc.?
Hi Tony,
Sorry for the delayed reply. I added this as a demo to the jp_doodle repository (I don't like to clutter up jp_proxy_widgets, so I put miscellaneous demos in jp_doodle).
Please look here
http://localhost:8889/notebooks/repos/jp_doodle/notebooks/misc/JQueryUI%20dialogextend%20plugin%20demo.ipynb
And let me know what you think.
@Aaron-Watters that looks like just what I need.... thanks...
My current active tinkering is in this context... Will give the extension a go next time I'm back at the computer (bank holiday tomorrow, and I'm trying to get into the habit of avoiding screens on holidays and weekends... Though I am really itching to try this... :-)
I'd overlooked the misc
dir before. Will also have a good look through those other examples to see if they help me figure out a couple of outstanding things I'd like to be able to do (my model of how py and js interact is still hazy...)
Thanks again..
very cool! Thanks for the link.
I seem to have the same issue as you that calling from py doesn't seem to work...
I also get really erratic behaviour... when I try things in a brand new notebook, things work fine. But if I am working in a legacy notebook, or sometimes close the widget then reopen it (which works normally), I get a new error message: TypeError: element.dialog(...).dialogExtend is not a function
error. There is something I fundamentally don't understand about require.js
, how packages are loaded into a browser, and what scope they have.
PS Ah, okay, so it seems I have to run the loader cell, and display the loader widget, and then in a new cell run the code to instantiate the widget I actually want to run the .dialogExtend()
on...
I suspect the problem is this:
The code that installs the jquery plugin needs to re-run every time you open a new javascript context. This is one of the confusing things about the notebook interfaces -- it's not always clear what has been run in the current context and what was run at some previous time and stored away in the notebook document.
Yeah, I reckon that must be it... it's a real faff.... is there a way I could dig deeper into the jp_proxy_widget code hack a requirement that the dialogExtend package is loaded when I try to pop out the widget? (So I guess require dialogExtend is available before the widget is created?)
I guess a similar issue is if I try to simply call a function in js widget from py magic? I can't get my head round the contexts properly, because the examples I tried resulted in an error that the js function wasn't defined even though it's there and being used in the widget (I guess I need to create my own set of really simple recipes that I can refer to... the context I'm working in is getting more and more complex!)
(Just as a by the by, I don't suppose you (know if) anyone hacked the tensorflow playground or any other simple NN demos into into an ipywidget using jp_proxy_widget? Also, do you have a demo of a widget js function using a py function to do some work, so eg js function calls a py function, then py function returns a result to the js widget?)
I started wondering whether there's a route to load an arbitrary required js package in before rendering the widget, but I guess this needs an async load success callback and I couldnlt spot one offhand.
eg this recipe:
roboSim = eds.Ev3DevWidget()
def show_robosim():
display(roboSim)
roboSim.element.dialog().dialogExtend({
"maximizable" : True,
"dblclick" : "maximize",
"icons" : { "maximize" : "ui-icon-arrow-4-diag" }});
roboSim.check_jquery(force=True, onsuccess=show_robosim(),
code_fn=eds.get_file_path('js/jquery.dialogextend.js'))
where Ev3DevWidge
extenda 'jp_proxy_widget.JSProxyWidget
, renders the widget and then a few moments later displays
new error message: timeout awaiting /srv/conda/envs/notebook/lib/python3.7/site-packages/nbev3devsim/js/jquery.dialogextend.js
So the onsuccess
callback in proxy_widget.py
is presumably success at queuing up the async load, not success in completing the load?
Sorry for the delay.
First observation: you probably don't want to call show_robosim
in check_jquery
because it should be called when the check is complete, not before: check_jquery(force=True, onsuccess=show_robosim,
...
Aside from that I'm not sure what is going on here. My initial reaction would be to open the Dev Tools in Chrome and see if there are any errors in the Javascript console.
No probs - I'm working across multiple fronts at the moment!
So how do you call something after the check is complete (onsuccess
seems not to mean on the success of the check_jquery()
call?
I've actually sort of got round the problem by adding the required js package load into the load procedure of a notebook extension I'm also loading in to support some of widget activities.
Note to self - to wait for the package to load, is it simply a case of:
require( [ 'js/jquery.dialogextend.js' ], function () {
show_robosim();
});
An alternative way of rendering a widget ins a separate panel in JupyterLab is to use the jupyter-widgets/jupyterlab-sidecar
extension, which now allows you to display the output of a code cell in a separate, detached panel:
Whilst I can get this demo to run in Binder environment launched from this repo (with sidecar
then installed and the JupyterLab browser page refreshed), if I try to install the jp_proxy_widget
package into the Binder environment launched from the sidecar repo, it fails with an Error displaying widget: model not found error (related issue: https://github.com/AaronWatters/jp_proxy_widget/issues/27).
The jp_proxy_widget
extension needs installing...
!jupyter labextension install jp_proxy_widget