@@ -307,6 +307,9 @@ def __init__(
307
307
# list of dependencies
308
308
self .callback_map = {}
309
309
310
+ # list of inline scripts
311
+ self ._inline_scripts = []
312
+
310
313
# index_string has special setter so can't go in config
311
314
self ._index_string = ""
312
315
self .index_string = index_string
@@ -636,6 +639,10 @@ def _generate_scripts_html(self):
636
639
if isinstance (src , dict )
637
640
else '<script src="{}"></script>' .format (src )
638
641
for src in srcs
642
+ ] +
643
+ [
644
+ '<script>{}</script>' .format (src )
645
+ for src in self ._inline_scripts
639
646
]
640
647
)
641
648
@@ -1194,13 +1201,14 @@ def clientside_callback(
1194
1201
(JavaScript) function instead of a Python function.
1195
1202
1196
1203
Unlike `@app.calllback`, `clientside_callback` is not a decorator:
1197
- it takes a
1204
+ it takes either a
1198
1205
`dash.dependencies.ClientsideFunction(namespace, function_name)`
1199
1206
argument that describes which JavaScript function to call
1200
1207
(Dash will look for the JavaScript function at
1201
- `window[namespace][function_name]`).
1208
+ `window.dash_clientside[namespace][function_name]`), or it may take
1209
+ a string argument that contains the clientside function source.
1202
1210
1203
- For example:
1211
+ For example, when using a `dash.dependencies.ClientsideFunction` :
1204
1212
```
1205
1213
app.clientside_callback(
1206
1214
ClientsideFunction('my_clientside_library', 'my_function'),
@@ -1211,16 +1219,17 @@ def clientside_callback(
1211
1219
```
1212
1220
1213
1221
With this signature, Dash's front-end will call
1214
- `window.my_clientside_library.my_function` with the current
1215
- values of the `value` properties of the components
1216
- `my-input` and `another-input` whenever those values change.
1217
-
1218
- Include a JavaScript file by including it your `assets/` folder.
1219
- The file can be named anything but you'll need to assign the
1220
- function's namespace to the `window` . For example, this file might
1221
- look like :
1222
+ `window.dash_clientside. my_clientside_library.my_function` with the
1223
+ current values of the `value` properties of the components `my-input`
1224
+ and `another-input` whenever those values change.
1225
+
1226
+ Include a JavaScript file by including it your `assets/` folder. The
1227
+ file can be named anything but you'll need to assign the function's
1228
+ namespace to the `window.dash_clientside` namespace . For example,
1229
+ this file might look :
1222
1230
```
1223
- window.my_clientside_library = {
1231
+ window.dash_clientside = window.dash_clientside || {};
1232
+ window.dash_clientside.my_clientside_library = {
1224
1233
my_function: function(input_value_1, input_value_2) {
1225
1234
return (
1226
1235
parseFloat(input_value_1, 10) +
@@ -1229,10 +1238,54 @@ def clientside_callback(
1229
1238
}
1230
1239
}
1231
1240
```
1241
+
1242
+ Alternatively, you can pass the JavaScript source directly to
1243
+ `clientside_callback`. In this case, the same example would look like:
1244
+ ```
1245
+ app.clientside_callback(
1246
+ '''
1247
+ function(input_value_1, input_value_2) {
1248
+ return (
1249
+ parseFloat(input_value_1, 10) +
1250
+ parseFloat(input_value_2, 10)
1251
+ );
1252
+ }
1253
+ ''',
1254
+ Output('my-div' 'children'),
1255
+ [Input('my-input', 'value'),
1256
+ Input('another-input', 'value')]
1257
+ )
1258
+ ```
1232
1259
"""
1233
1260
self ._validate_callback (output , inputs , state )
1234
1261
callback_id = _create_callback_id (output )
1235
1262
1263
+ # If JS source is explicitly given, create a namespace and function
1264
+ # name, then inject the code.
1265
+ if isinstance (clientside_function , str ):
1266
+
1267
+ out0 = output
1268
+ if isinstance (output , (list , tuple )):
1269
+ out0 = output [0 ]
1270
+
1271
+ namespace = '_dashprivate_{}' .format (out0 .component_id )
1272
+ function_name = '{}' .format (out0 .component_property )
1273
+
1274
+ self ._inline_scripts .append (
1275
+ """
1276
+ var clientside = window.dash_clientside = window.dash_clientside || {{}};
1277
+ var ns = clientside["{0}"] = clientside["{0}"] || {{}};
1278
+ ns["{1}"] = {2};
1279
+ """ .format (namespace .replace ('"' , '\\ "' ),
1280
+ function_name .replace ('"' , '\\ "' ),
1281
+ clientside_function )
1282
+ )
1283
+
1284
+ # Callback is stored in an external asset.
1285
+ else :
1286
+ namespace = clientside_function .namespace
1287
+ function_name = clientside_function .function_name
1288
+
1236
1289
self .callback_map [callback_id ] = {
1237
1290
"inputs" : [
1238
1291
{"id" : c .component_id , "property" : c .component_property }
@@ -1243,8 +1296,8 @@ def clientside_callback(
1243
1296
for c in state
1244
1297
],
1245
1298
"clientside_function" : {
1246
- "namespace" : clientside_function . namespace ,
1247
- "function_name" : clientside_function . function_name ,
1299
+ "namespace" : namespace ,
1300
+ "function_name" : function_name ,
1248
1301
},
1249
1302
}
1250
1303
0 commit comments