Closed secana closed 5 years ago
So what's happening here is that the Jupyter front-end uses RequireJS and the library Sweet Alert library is configured to adapt to this. There are two approaches to dealing with this. One is that you can make use of RequireJS more like this:
https://www.stefaanlippens.net/jupyter-custom-d3-visualization.html
Sketched implementation:
"""<script>
require.config({
paths: {
sweetalert: 'https://unpkg.com/sweetalert/dist/sweetalert.min'
}
});
</script>""" |> Util.Html |> Display
"""
<script>
(function() {
require(['sweetalert'], function(swal) {
swal('Hi Stefan');
});
})();
</script>""" |> Util.Html |> Display
The other way is if you don't want the module system, you can hide it and stick JavaScript in global scope (which has issues but convenient in a notebook context):
let wc = new System.Net.WebClient()
wc.DownloadString("https://unpkg.com/sweetalert/dist/sweetalert.min")
|> sprintf
"""
<script type="text/javascript">
var require_save = require;
var requirejs_save = requirejs;
var define_save = define;
require = requirejs = define = undefined;
%s
require = require_save;
requirejs = requirejs_save;
define = define_save;
"""
|> Util.Html
|> Display
"""<script type="text/javascript">swal("Hello World!")</script>""" |> Util.Html |> Display
This second approach is what we use in: https://github.com/fsprojects/IfSharp/blob/f1d6c88e834df4208edfca863d9f0f9d93bb59fa/src/IfSharp/XPlot.GoogleCharts.fsx#L11 https://github.com/fsprojects/IfSharp/blob/f1d6c88e834df4208edfca863d9f0f9d93bb59fa/src/IfSharp/XPlot.Plotly.fsx#L18
where we decided to just make the functions global and inline the scripts.
We've discussed potentially making general helper scripts for this but I'm not quite sure of the right API and modules or not.
Hope this helps.
Hi @cgravill,
I got it working with your second approach (there is a closing missing). Thanks a lot for the answer. Without it, my project idea would have been dead.
Regards, Stefan
Great, glad it was useful. Funny my test worked without closing in my browser!
I had a few thoughts of ways we could make this more usable (note they're all proposals, not implemented):
The wrapped functions is the easiest to implement but would be standardising use of global scope which perhaps isn't ideal. That would fit in with what's been done elsewhere.
@dsyme and @tpetricek do either of you have a view on what would makes sense together with other interactive and notebook-variant uses of F#?
All my IFSharp experiments involving JavaScript were somewhat hacky - so I guess that's what the standard situation is :-). I think having helpers like the ones in your first example would be a good starting point - it should help with getting some common scenarios to work (and we could see if people actually use it, how and whether it works for them before trying to do something more clever...)
Great, I've merged that syntax and I'll go ahead and close this issue. We can do clever things later if they seem needed.
Description
When a JavaScript library is loaded, the exposed functions cannot be called because the are undefined.
Repro steps
Step A Load some arbitrary JS library:
@"<script src=""https://unpkg.com/sweetalert/dist/sweetalert.min.js""></script>" |> Util.Html |> Display
(Lib to show "nice" alerts)Step B Try to execute some function from the JS library:
"""<script type="text/javascript">swal("Hello World!")</script>""" |> Util.Html |> Display
Expected behavior
Alert popup with the text "Hello World".
Actual behavior
I can see in the browser debug view that the library itself was downloaded but the function is not callable.
Related information
I've used a Docker image to start a local Jupyter Notebook:
docker run --rm --name jupyter -it -v /home/user/notebookfolder:/notebooks -p 8888:8888 godu/ifsharp