I would like to make use of a javascript library (specifically this one) in my Bokeh javascript callback. How can I specify importing of this javascript library such that the library is accessible from Bokeh's js callback functions?
The examples at:
https://docs.bokeh.org/en/latest/docs/user_guide/extensions.html
mainly talk about creating a custom Bokeh Model. I am not particularly interested in creating a new Model, just want to use the library functions in a callback to modify the data that is plotted.
There are two ways:
Server app
Standalone HTML app
Here is how:
Server app:
You can create a Bokeh server directory structure.
create a directory called myapp
name your Python script main.py and put it there
create a subdirectory there called templates
create index.html, main.js and optional styles.css files and put them in templates subdirectory
open terminal, navigate to directory one level higher than myapp directory and start your app with this command: bokeh serve --show myapp
The following example works for Bokeh v1.0.4.
Directory structure:
myapp
|
+---main.py
+---templates
+---index.html
+---main.js
+---styles.css
main.py
from bokeh.plotting import curdoc
from bokeh.models import Button, CustomJS
button = Button(label = 'Click Me')
button.callback = CustomJS(code = """ alert($) """)
curdoc().add_root(button)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<meta charset="utf-8">
{{ bokeh_css }}
{{ bokeh_js }}
<style>
{% include 'styles.css' %}
</style>
</head>
<body>
<script>
{% include 'main.js' %}
</script>
{{ plot_div|indent(8) }}
{{ plot_script|indent(8) }}
</body>
</html>
Please note that this way you can include local, but also remote JS libraries or style sheets.
main.js
$(document).ready(function() {
alert('jQuery succesfully loaded !')
});
styles.css
body { background: #111122; }
> Standalone HTML app:
import os
from bokeh.io import save
from bokeh.models import Slider
from bokeh.util.browser import view
template = """
{% block postamble %}
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script>
$(document).ready(function() {
var slider = Bokeh.documents[0].get_model_by_name('my_slider')
alert('slider value: ' + slider.value)
});
</script>
{% endblock %} """
slider = Slider(start=0, end=10, value=5, name='my_slider')
save(slider, template=template)
view(os.path.join(os.path.dirname(__file__), os.path.basename(__file__)).replace('.py', ".html")
Related
I am learning Rails 7 with the new default Importmap jsmp syntax. I have tried to follow what few tutorials are out there, but am still unable to get either jQuery or Stimulus to respond to a simple alert function on page load.
I started over with a bare-bones Rails 7 application, ran bundle install, followed by rails turbo:install, rails stimulus:install and created a Static controller to route to a Landing page at Static#Landing.
My `landing.html.erb' file contains:
<h2>Landing</h2>
<p>
<script>
document.write("Vanilla JS is working...");
</script>
</p>
I get the expected string output, so I know Javascript is enabled in the Browser.
My importmap.rb file contains:
# Pin npm packages by running ./bin/importmap
pin "application", preload: true
pin "#hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "#hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "#hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin "jquery", to: "library/jquery.js" #"https://ga.jspm.io/npm:jquery#3.6.0/dist/jquery.js"
pin "jquery-ui-dist", to: "library/jquery.js" #"https://ga.jspm.io/npm:jquery-ui-dist#1.13.1/jquery-ui.js"
pin "jqtree", to: "https://ga.jspm.io/npm:jqtree#1.6.2/lib/tree.jquery.js"
pin_all_from "app/javascript/controllers", under: "controllers"
The only lines I added were the 3 invoking a form of jQuery.
I next added the 3 import statements for jQuery, jQuery-ui-dist, and jqtree to the application.js file. The complete file contains:
// Javascript document
// Document Name: application.js
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "#hotwired/turbo-rails"
import "jQuery"
import "jquery-ui-dist"
import "jqtree"
import "controllers"
// Configure Stimulus development experience
application.debug = false
window.Stimulus = application
// NOTE: make jquery global
window.$ = window.jQuery = jQuery;
$(function(){
window.alert("It looks like jQuery is too.");
});
export { application }
I next edited my app/assets/config/manifest.js file to include the following:
//= link_tree ../images
//= link_tree ../icons
//= link_directory ../stylesheets .css
//= link_tree ../../javascript .js
//= link_tree ../../javascript/library .js
//= link_tree ../../../vendor/javascript .js
However, even though inline <script>s work as outlined above, I get no response from either jQuery or Stimulus to the alert function in application.js. When I check my source code, I see the following:
<!DOCTYPE html>
<html>
<head>
<title>Testingjquery</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="LkQZA1mB-KU38K8S1lg_BMJWPx4HLonSyQ0s8W2vCotmw3aHIXZNDnPcJCtbgeXSTWrEuWJBZWlkOZcLe7Ru9w" />
<link rel="stylesheet" href="/assets/application-e0cf9d8fcb18bf7f909d8d91a5e78499f82ac29523d475bf3a9ab265d5e2b451.css" data-turbo-track="reload" />
<script type="importmap" data-turbo-track="reload">{
"imports": {
"application": "/assets/application-79a33b4392f09ada2a09f9c0b7de4d6479378090d98fa671caaef897dcec0de9.js",
"#hotwired/turbo-rails": "/assets/turbo.min-e5023178542f05fc063cd1dc5865457259cc01f3fba76a28454060d33de6f429.js",
"#hotwired/stimulus": "/assets/stimulus.min-b8a9738499c7a8362910cd545375417370d72a9776fb4e766df7671484e2beb7.js",
"#hotwired/stimulus-loading": "/assets/stimulus-loading-1fc59770fb1654500044afd3f5f6d7d00800e5be36746d55b94a2963a7a228aa.js",
"jquery": "/assets/library/jquery-58fa327d47526faff06ea7057a0022e9c42b2ca3a9aeea413f0e18176a63cd9f.js",
"jquery-ui-dist": "/assets/library/jquery-58fa327d47526faff06ea7057a0022e9c42b2ca3a9aeea413f0e18176a63cd9f.js",
"jqtree": "https://ga.jspm.io/npm:jqtree#1.6.2/lib/tree.jquery.js",
"controllers/application": "/assets/controllers/application-368d98631bccbf2349e0d4f8269afb3fe9625118341966de054759d96ea86c7e.js",
"controllers/hello_controller": "/assets/controllers/hello_controller-549135e8e7c683a538c3d6d517339ba470fcfb79d62f738a0a089ba41851a554.js",
"controllers": "/assets/controllers/index-2db729dddcc5b979110e98de4b6720f83f91a123172e87281d5a58410fc43806.js"
}
}</script>
<link rel="modulepreload" href="/assets/application-79a33b4392f09ada2a09f9c0b7de4d6479378090d98fa671caaef897dcec0de9.js">
<link rel="modulepreload" href="/assets/turbo.min-e5023178542f05fc063cd1dc5865457259cc01f3fba76a28454060d33de6f429.js">
<link rel="modulepreload" href="/assets/stimulus.min-b8a9738499c7a8362910cd545375417370d72a9776fb4e766df7671484e2beb7.js">
<link rel="modulepreload" href="/assets/stimulus-loading-1fc59770fb1654500044afd3f5f6d7d00800e5be36746d55b94a2963a7a228aa.js">
<script src="/assets/es-module-shims.min-d89e73202ec09dede55fb74115af9c5f9f2bb965433de1c2446e1faa6dac2470.js" async="async" data-turbo-track="reload"></script>
<script type="module">import "application"</script>
</head>
<body>
<h2>Landing</h2>
<p>
<script>
document.write("Vanilla JS is working...");
</script>
</p>
</body>
</html>
As you can see, jQuery is not being loaded at all and Stimulus is being loaded, but is unresponsive to any code references. I am new to Stimulus, intermediate with Javascript/jQuery and new to Rails 7. From what I have read, I like the conceptualization behind these radical shifts in Rails methodology, but so far, haven't been able to get it to work.
The files are all in their appropriate places according to the references to them. For illustration, this is my file tree:
-app
-assets
-config
-manifest.js
-javascript
-controllers
-application.js
...
-library
-jquery.js
-jquery-ui.js
-application.js
...
-config
-importmap.js
...
The final application.js file contains no code that I changed and is as follows:
import { Application } from "#hotwired/stimulus"
const application = Application.start()
// Configure Stimulus development experience
application.debug = false
window.Stimulus = application
// NOTE: make jquery global
window.$ = window.jQuery = jQuery;
export { application }
Granted, there are two application.js files that Importmaps/Stimulus/Turbo seem to rely upon, and perhaps I inserted some code into the wrong application.js file. If so, it was because the tutorials that I was following didn't specify or clarify which file to insert certain code into.
Does anyone see a fundamental error in my code or can suggest another approach? Thanks in advance.
I'm having an issue when using Flask and it's templates when importing Scripts and Stylesheets. I searched everywhere how to do it, and none of them solved my problem.
This is my project's structure:
https://i.gyazo.com/f746c58499cbbafa11b023eecb316b15.png
This is how I defined Flask's configuration:
app = Flask(__name__,
template_folder="../web/templates",
static_folder="../web/static",
static_url_path=''
)
And this is how i'm importing the scripts :
<script src={{ url_for('static', filename='/js/home.js') }}></script>
And this is the msg I get :
Falló la carga de con fuente “http://localhost:5000/js/home.js”.
(Basically says that it failed loading that script)
I already read the Quickstart guide from Flask.
I tried creating a "static" folder in the project's root and not setting anything on the config. Tried to change the static folder everywhere on my project.
Can anyone help me solve this? I'm new to Flask and Jinja, but have been searching the whole day and can't make it work.
NOTE : The path for the templates work, my templates work fine, except for .js and .css imports.
you need to remove starting '/' from <script src={{ url_for('static',filename='/js/home.js') }}.
so change it to <script src={{ url_for('static',filename='js/home.js') }}.
your project structure should look like this:
MyFlaskApp/templates/home.html
MyFlaskApp/static/js/home.js
MyFlaskApp/app.py
app.py
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/")
def home():
return render_template("home.html")
if __name__ == "__main__":
app.run()
home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src={{ url_for('static',filename='js/home.js') }}> </script>
</body>
</html>
home.js
alert("hello");
I'm having a difficult time importing client side javascript files with flow router. Without flow router, the imports work as expected but the second I introduce flow router the files aren't loaded properly.
Here are what my files look like. Anybody out there ever experienced this ? You help is greatly appreciated! If you help me I will be 100% sure to mark your answer as so :)
client/main.js
import '../imports/startup/client'; // initialize all relevant javascript
import './main.html';
client/main.html
<head>
<title>Welcome </title>
</head>
<template name="visitorLayout">
<body>
{{> Template.dynamic template=header }}
{{> Template.dynamic template=main }}
{{> Template.dynamic template=footer }}
</body>
</template>
<template name="adminLayout">
<body>
{{> Template.dynamic template=main }}
</body>
</template>
imports/startup/client/index.js
import '../../ui/pages/landing_page/modernizr-2.6.2.min.js';
import '../../ui/pages/landing_page/jquery.easing.1.3.js';
import '../../ui/pages/landing_page/bootstrap.min.js';
import '../../ui/pages/landing_page/jquery.waypoints.min.js';
import './routes';
imports/startup/client/routes.js
import { FlowRouter } from 'meteor/kadira:flow-router';
import { BlazeLayout } from 'meteor/kadira:blaze-layout';
FlowRouter.route('/', {
action() {
BlazeLayout.render('visitorLayout', {
header : "header",
footer : "footer",
main : "index"
})
}
});
FlowRouter.route('/admin', {
action() {
BlazeLayout.render('adminLayout', {
main : "admin"
})
}
});
I guess is that you have problem with files loading order. It seems like your routes.js is loaded before main.html therefore there is no template available to render. To fix, try one of the followings:
Remove the line import './main.html'; in client/main.js, files under client folder do not need imported they are loaded automatically.
Create a new html file including the two templates you want to render (visitorLayout and adminLayout) under import folder or sub-folder of import, then import this new html file in routes.js. You also need to remove body tag inside those two templates, use div instead, because body is a special tag in Meteor and are not treated like other tags
When the gray div is clicked I want the website to be opened in a new tab, but here this javascript code isn't working. Why? How I can edit it?
views.py:
from django.shortcuts import render
from django.http import HttpResponse
def test(request):
return render(request, 'test.html')
test.html:
<html>
<head>
<script src="jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#gray").click(function(){
window.open("http://www.w3schools.com");
});
});
</script>
</head>
<body>
<div id='gray' style="width:100px;height:100px;background:gray;"></div>
</body>
urls.py:
from django.conf.urls import include, url
from secondv.views import test
urlpatterns = [
url(r'^test', test),
]
The jquery.min.js file is in the template directory, the same directory as test.html file.
Template directory is only for templates. All static content such as js, images should be placed to static directory. It's well described in docs
https://docs.djangoproject.com/en/1.9/intro/tutorial06/
https://docs.djangoproject.com/en/1.9/howto/static-files/deployment/ - for production
Can I load template file with dynamic javascript file. For example when I render a.html, I want to load a.js
How can I do this?
If you just want to include a static javascript file, you can do it the same way that you load any other javascript file in HTML:
<script src="jquery-1.11.2.min.js"></script>
However, if what you want to do is pass in a javascript file that the template will load, depending on some backend output, something like this will work:
#views.py
from django.shortcuts import render
from django.template import RequestContext
def my_view(request):
# Logic here...
js_file = "jquery-1.11.2.min.js"
render_to_response('template.html',
context_instance=RequestContext(request,{
"js_file": js_file
}))
#template.html
<script src="{{ js_file }}"></script>