Open modernserf opened 8 years ago
It looks like selected
wasn't included in the list of boolean attributes, that is now fixed.
Give this a try:
const select = (options, value) =>
yo`<select>
${options.map((o) =>
yo`<option value="${o.value}"
selected="${value === o.value}">
${o.label}
</option>`
)}
</select>`
More documentation on boolean attributes would be good!
That's still not working for me. I'll put together a demo when I get a chance.
@modernserf Try npm cache clean && rm -rf node_modules && npm i
to get the latest dependency tree.
$ npm ls bel
└─┬ yo-yo@1.2.2
└── bel@4.4.3
this should work?
Hmm yep, 4.4.3
should work. A demo of what's not working would be great then. Thanks!
FYI, this works for me
/**
* Create a <select> element
* @param {string[]|Object[]} items List of value strings or objects with value and label properties
* @param {string} selected Value of selected item
* @param {Object} attributes Object of attributes to apply to <select> element
*/
module.exports = ({ items = [], selected, attributes = {} }) => {
return html`
<select ${attributes}>
${items.map((item) => {
const optAttributes = {
value: item.value || item
}
if (selected && selected === optAttributes.value) {
optAttributes.selected = 'selected'
}
const label = item.label || item
return html`<option ${optAttributes}>${label}</option>`
})}
</select>`
}
Thanks! I'll take a look and see if I can find out why it's not working. I wonder if it's related to Babel parsing the template strings?
The main reason I prefer the syntax that supplies the attributes <option selected="${isSelected}">
over an expression <option ${attrs}>
is because we can parse the HTML attributes if they're not in an expression. This allows us to make better optimizations when converting the template literal into elements.
Agreed @shama, actually the only reason I used an expression is because selected="false"
still renders as selected. Though I may be thinking of checked
. Basically, there's no false
value technically for them in html
I've also found that both select.value
and option.selected
is needed to be able to programmatically select an option (such as when the options are rendered first, and then an async action is selecting one of the options).
I guess is has to do with yo-yo copying the value of the existing select
element to the new one (https://github.com/maxogden/yo-yo/blob/master/index.js#L29).
@Hihaj I'm not sure I follow: what issue are you experiencing?
@yoshuawuyts I was just making the same observation as @modernserf in the original question; that you need to use both (select.value
+ option.selected
) in order to control which option should be selected via some other action than the user actually picking it in the dropdown. For example if the <select>
first renders with a couple of options and you (a little bit later) want to set one of the options as selected (based on some logic).
@Hihaj thanks; that makes sense - feel we should address this indeed :sparkles:
More of a documentation request than a feature request -- this is how to do a "controlled" (in the React parlance) version of a select tag:
Note that you need to both set a value on the
<select>
tag and set theselected
attribute on the selected<option>
.