I would like to use crosstalk
with a default value using the filter_select
function. This answer gives a JavaScript option but it doesn't seem to work. We have to use the id of the function and a default value. This is the code:
```{js}
function filter_default() {
document.getElementById("std_specie").getElementsByClassName("selectized")
[0].selectize.setValue("setosa", false);
}
window.onload = filter_default;
```
But the filter doesn't show a default value in the dashboard. Here is some reproducible code:
---
title: "Example"
format: dashboard
---
```{r}
library(crosstalk)
```
```{r}
sd <- SharedData$new(iris)
filter_select("std_specie", "Choose your specie", sd, ~Species)
```
```{js}
function filter_default() {
document.getElementById("std_specie").getElementsByClassName("selectized")
[0].selectize.setValue("setosa", false);
}
window.onload = filter_default;
```
Output:
As you can see there is no default value. It would have been great to have a default selection option. So I was wondering why this code isn't working?
The content in your selectize
control is dynamically loaded by the JS in the document's <head>
. window.onload
is triggered after the page content is loaded, but before the script generating the filter drop down has finished executing. So this triggers an error. You have two options:
Just make your function check if the element is loaded and if not then call itself again 20ms later:
```{js}
function filter_default() {
let el = document
.getElementById("std_specie")
.getElementsByClassName("selectized")[0];
el ? el.selectize.setValue("setosa", true) : setTimeout(filter_default, 20);
}
document.addEventListener("DOMContentLoaded", filter_default);
```
This will work but you may not want to do this if you're building a proper web app. If for some reason the content never loads then this will never finish executing and the page may become unresponsive.
First, put this in your HTML:
<script>
function filter_default() {
document
.getElementById("std_specie")
.getElementsByClassName("selectized")[0]
.selectize.setValue("setosa", true);
}
filter_default();
</script>
Generate your Quarto html then use the Python script I wrote in Load Quarto html map data from json for Leaflet map generated in R.
The relevant part of this script for your problem is that it will:
<script src = "*.js">
tags from the <head>
of the html, storing the URLs to be loaded later.<script>
tags hardcoded into the body of the html and move the code to separate *.js files.<head>
which uses Promises with chained .then()
statements to do the following (in this order):
<head>
.<body>
.HTMLWidgets.staticRender()
.The JS in the body of the document generated will not run until the JS in the head has finished executing. This will only work on a web server, and not locally, because of CORS. But if you're only running this locally then I'd do the quick-and-dirty option.