Can't recreate null select behavior with external input (select) element
(Note: I'm using vega-lite for the example, but I think this applies to vega, hence why I'm filing here.)
I'm starting from the second example on the bind page, where we plot Miles Per Gallon against Horsepower, colored by Cylinders, and with the option to subset to an origin. The following param definition includes null, and we can see from selecting it that it causes all points to match (instead of e.g. none of them matching):
"params": [{
"name": "org",
"select": {"type": "point", "fields": ["Origin"]},
"bind": {"input": "select", "options": [null, "Europe", "Japan", "USA"]}
}]
Standalone html page if desired (internal input)
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
</head>
<body>
<div id="vis"></div>
<script>
const spec = {
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {"url": "https://raw.githubusercontent.com/vega/vega/main/docs/data/cars.json"},
"params": [
{
"name": "org",
"select": {"type": "point", "fields": ["Origin"]},
"bind": {"input": "select", "options": [null, "Europe", "Japan", "USA"]}
}
],
"mark": "point",
"encoding": {
"x": {"field": "Horsepower", "type": "quantitative"},
"y": {"field": "Miles_per_Gallon", "type": "quantitative"},
"color": {
"condition": {"param": "org", "field": "Cylinders", "type": "ordinal"},
"value": "grey"
}
}
};
vegaEmbed("#vis", spec)
.then(result => console.log(result))
.catch(console.warn);
</script>
</body>
This is great. I want to recreate this using an externally defined select component. I mostly copied the generated html that the above gives to get:
<div>
<label htmlFor="cars">Choose an origin:</label>
<select name="carOrigin" id="testExternal">
<option value="null" selected="true">null</option>
<option value="USA">USA</option>
<option value="Japan">Japan</option>
<option value="Europe">Europe</option>
</select>
</div>
And then referenced it here with a new params definition:
"params": [{
"name": "org",
"select": {"type": "point", "fields": ["Origin"]},
"bind": { "element": "#testExternal" }
}]
Standalone html page if desired (external input)
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
</head>
<body>
<form>
<div>
<label htmlFor="cars">Choose an origin:</label>
<select name="carOrigin" id="testExternal">
<option value="null" selected="true">null</option>
<option value="USA">USA</option>
<option value="Japan">Japan</option>
<option value="Europe">Europe</option>
</select>
</div>
</form>
<div id="vis"></div>
<script>
const spec = {
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {"url": "https://raw.githubusercontent.com/vega/vega/main/docs/data/cars.json"},
"params": [
{
"name": "org",
"select": {"type": "point", "fields": ["Origin"]},
"bind": {"element": "#testExternal"}
}
],
"mark": "point",
"encoding": {
"x": {"field": "Horsepower", "type": "quantitative"},
"y": {"field": "Miles_per_Gallon", "type": "quantitative"},
"color": {
"condition": {"param": "org", "field": "Cylinders", "type": "ordinal"},
"value": "grey"
}
}
};
vegaEmbed("#vis", spec)
.then(result => console.log(result))
.catch(console.warn);
</script>
</body>
This almost works: it starts out with null as the selected value, and all points selected. But if you change the selection to another value and then change it back to null, you get no points selected. Video:
https://user-images.githubusercontent.com/6945891/161145781-6bcb7cd8-a67e-44a8-b709-cb67d822783e.mp4
Is vega doing some extra processing of the internally defined input to make the null "select all" version work? If so, can I recreate that by editing my select component somehow, or do I need to do some transformation within the spec? Less important: why does the external version also work initially?
What else I tried
- I tried copying over more of the vega-generated html, e.g. the
<form class="vega-bindings">etc, didn't help - I tried various other values for the null option:
"null",undefined,null, and"".
Thanks!