diff --git a/fasthtml/components.py b/fasthtml/components.py index 68ae3978..f82ed9a0 100644 --- a/fasthtml/components.py +++ b/fasthtml/components.py @@ -121,7 +121,10 @@ def _fill_item(item, obj): if val is not None and not 'skip' in attr: if tag=='input': if attr.get('type', '') == 'checkbox': - if val: attr['checked'] = '1' + if isinstance(val, list): + if attr['value'] in val: attr['checked'] = '1' + else: attr.pop('checked', '') + elif val: attr['checked'] = '1' else: attr.pop('checked', '') elif attr.get('type', '') == 'radio': if val and val == attr['value']: attr['checked'] = '1' @@ -129,8 +132,13 @@ def _fill_item(item, obj): else: attr['value'] = val if tag=='textarea': cs=(val,) if tag == 'select': - option = next((o for o in cs if o.tag=='option' and o.get('value')==val), None) - if option: option.selected = '1' + if isinstance(val, list): + for opt in cs: + if opt.tag == 'option' and opt.get('value') in val: + opt.selected = '1' + else: + option = next((o for o in cs if o.tag=='option' and o.get('value')==val), None) + if option: option.selected = '1' return FT(tag,cs,attr,void_=item.void_) # %% ../nbs/api/01_components.ipynb diff --git a/nbs/api/01_components.ipynb b/nbs/api/01_components.ipynb index bd5e0a52..0361f3fd 100644 --- a/nbs/api/01_components.ipynb +++ b/nbs/api/01_components.ipynb @@ -447,7 +447,10 @@ " if val is not None and not 'skip' in attr:\n", " if tag=='input':\n", " if attr.get('type', '') == 'checkbox':\n", - " if val: attr['checked'] = '1'\n", + " if isinstance(val, list):\n", + " if attr['value'] in val: attr['checked'] = '1'\n", + " else: attr.pop('checked', '')\n", + " elif val: attr['checked'] = '1'\n", " else: attr.pop('checked', '')\n", " elif attr.get('type', '') == 'radio':\n", " if val and val == attr['value']: attr['checked'] = '1'\n", @@ -455,8 +458,13 @@ " else: attr['value'] = val\n", " if tag=='textarea': cs=(val,)\n", " if tag == 'select':\n", - " option = next((o for o in cs if o.tag=='option' and o.get('value')==val), None)\n", - " if option: option.selected = '1'\n", + " if isinstance(val, list):\n", + " for opt in cs:\n", + " if opt.tag == 'option' and opt.get('value') in val:\n", + " opt.selected = '1'\n", + " else:\n", + " option = next((o for o in cs if o.tag=='option' and o.get('value')==val), None)\n", + " if option: option.selected = '1'\n", " return FT(tag,cs,attr,void_=item.void_)" ] }, @@ -516,6 +524,83 @@ "form" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "1513cf64", + "metadata": {}, + "outputs": [ + { + "data": { + "text/markdown": [ + "```html\n", + "
\n", + "```" + ], + "text/plain": [ + "form((select((option(('a',),{'value': 'a', 'selected': '1'}), option(('b',),{'value': 'b'}), option(('c',),{'value': 'c', 'selected': '1'})),{'multiple': '1', 'name': 'items'}),),{})" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "@dataclass\n", + "class MultiSelect:\n", + " items: list[str]\n", + "\n", + "multiselect = MultiSelect(items=['a', 'c'])\n", + "multiform = Form(Select(Option('a', value='a'), Option('b', value='b'), Option('c', value='c'), multiple='1', name='items'))\n", + "multiform = fill_form(multiform, multiselect)\n", + "assert '' in to_xml(multiform)\n", + "assert '' in to_xml(multiform)\n", + "assert '' in to_xml(multiform)\n", + "multiform" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dd316f94-0695-44bf-96c2-45128a8b0644", + "metadata": {}, + "outputs": [ + { + "data": { + "text/markdown": [ + "```html\n", + "\n", + "```" + ], + "text/plain": [ + "form((fieldset((label((input((),{'type': 'checkbox', 'name': 'items', 'value': 'a', 'checked': '1'}), 'a'),{}), label((input((),{'type': 'checkbox', 'name': 'items', 'value': 'b'}), 'b'),{}), label((input((),{'type': 'checkbox', 'name': 'items', 'value': 'c', 'checked': '1'}), 'c'),{})),{}),),{})" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "@dataclass\n", + "class MultiCheck:\n", + " items: list[str]\n", + "\n", + "multicheck = MultiCheck(items=['a', 'c'])\n", + "multiform = Form(Fieldset(Label(Input(type='checkbox', name='items', value='a'), 'a'),\n", + " Label(Input(type='checkbox', name='items', value='b'), 'b'),\n", + " Label(Input(type='checkbox', name='items', value='c'), 'c')))\n", + "multiform = fill_form(multiform, multicheck)\n", + "assert '' in to_xml(multiform)\n", + "assert '' in to_xml(multiform)\n", + "assert '' in to_xml(multiform)\n", + "multiform" + ] + }, { "cell_type": "code", "execution_count": null,