---
# System prepended metadata

title: Controllable Select

---

# Controllable Select Issues

The current implementation requires adding (and serializing) effects for every option in the select. And it makes sense, because every option could be doing something different on selectedValueChange
```jsx
<select>
  <option value="AL" selectedValue:=input.value>Alabama</>
  <option value="AK" selectedValue:=input.value selectedValueChange() { console.log("too cold!") }>Alaska</>
  <option value="AZ" selectedValue=input.value selectedValueChange() { console.log("too hot!") }>Arizona</>
  <option value="AR" selectedValue:=input.value>Arkansas</>
  <option value="CA">California</>
</>
```

We can't easily restrict all options to have the same selectedValueChange, because you'd be forced to hoist functions where you wouldn't otherwise.  The following despite having the same implementation has a different instance of selectedValueChange for each iteration of the `<for>`
```jsx
<select>
  <for|{ name, code }| of=input.states>
    <option value=code selectedValue=input.value selectedValueChange(v) { input.value = v }>${name}</option>
  </for>
</select>
```

What if instead, we could have a single valueChange for the select element?
```jsx
<select value:=input.value>
  <option value="AL">Alabama</>
  <option value="AK">Alaska</>
  <option value="AZ">Arizona</>
  <option value="AR">Arkansas</>
  <option value="CA">California</>
</>
```


Could flush a script tag after the select to set the value
```jsx
<select value:=input.value>
  <option value="AL">Alabama</>
</>
<script>document.currentScript.previousElementSibling.value = ${JSON.stringify(input.value)}</script>
```

But not sure that works with the new html writer implementation
```jsx
<select value:=input.value>
  <await|states| from=getStates()>
    <for|{ name, code }| of=states>
      <option value=code>${name}</option>
    </>
  </>
</>
// this would be flushed before the await is resolved. 
// when does it execute? 
// does it have the currentScript?
<script>document.currentScript.previousElementSibling.value = ${JSON.stringify(input.value)}</script> 
```

We could store a select's value in a context variable... somehow and then have a helper for the option's `value` attribute that can also set `selected`
```jsx
export function optionValueAttr(val: unknown) {
  return stringAttr("style", val) + (val === ctx.select.value ? " selected" : "");
}
```