The idea with viewof is that there’s both a view and a value. Your swatches here aren’t really views — they’re just values (that happen to be DOM elements). The typical use case of views is for values that are controlled interactively by the user, such as text inputs and sliders, where the view is an input element and the value is a string or a number. As a rule of thumb, the view is what the user sees whereas the value is what the code sees. If those things are the same (i.e., they’re both DOM elements), then you don’t need viewof.
So, the first change I’d make is to remove the unneeded viewofs from the swatch declarations. I.e., change this:
viewof score_1 = swatch("rgb(0, 0, 255)")
to this
score_1 = swatch("rgb(0, 0, 255)")
The second problem is that a DOM element can’t exist in more than one place in the DOM at a time. You’re currently referencing the swatch elements in four places: when they are declared (score1
), in the value1
cell, in the value2
cells, and lastly in the htmlview
cell (because the latter references value1
and value2
, which are already shown in the DOM).
Probably the cleanest way to fix this would be to reference a value that’s not a DOM element. I.e., change this:
score_1 = swatch("rgb(0, 0, 255)")
to this
score_1 = "rgb(0, 0, 255)"
And then correspondingly update the htmlview
definition to create the swatches inline:
htmlview = html`
Result 1: ${swatch(value1)} <br />
Result 2: ${swatch(value2)}
`
Side note, if you want your slider to only have a fixed number of options, you could also consider defining your scores as an array:
scores = [
"rgb(0, 0, 255)",
"rgb(137, 0, 225)",
"rgb(224, 0, 149)",
"rgb(246, 111, 187)",
"rgb(255, 188, 203)"
]
And then changing your slider definition:
viewof value1_calc = slider({
min: 0,
max: scores.length - 1,
step: 1,
value: 0,
})
And then simplifying your value definition:
value1 = scores[value1_calc]
In fact, you can combine this into your slider definition using the getValue option:
viewof value1 = slider({
min: 0,
max: scores.length - 1,
step: 1,
value: 0,
getValue: i => scores[i.valueAsNumber]
})