Skip to content

Commit

Permalink
Merge pull request #566 from lnoor/main
Browse files Browse the repository at this point in the history
fixing issue #565, improper initialization of multiple select and checkbox arrays
  • Loading branch information
jph00 authored Nov 19, 2024
2 parents 067d318 + 611d713 commit 803d974
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 6 deletions.
14 changes: 11 additions & 3 deletions fasthtml/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,24 @@ 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'
else: attr.pop('checked', '')
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
Expand Down
91 changes: 88 additions & 3 deletions nbs/api/01_components.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -447,16 +447,24 @@
" 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",
" else: attr.pop('checked', '')\n",
" 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_)"
]
},
Expand Down Expand Up @@ -516,6 +524,83 @@
"form"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1513cf64",
"metadata": {},
"outputs": [
{
"data": {
"text/markdown": [
"```html\n",
"<form><select multiple=\"1\" name=\"items\"><option value=\"a\" selected=\"1\">a</option><option value=\"b\">b</option><option value=\"c\" selected=\"1\">c</option></select></form>\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 '<option value=\"a\" selected=\"1\">a</option>' in to_xml(multiform)\n",
"assert '<option value=\"b\">b</option>' in to_xml(multiform)\n",
"assert '<option value=\"c\" selected=\"1\">c</option>' 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",
"<form><fieldset><label> <input type=\"checkbox\" name=\"items\" value=\"a\" checked=\"1\">\n",
"a</label><label> <input type=\"checkbox\" name=\"items\" value=\"b\">\n",
"b</label><label> <input type=\"checkbox\" name=\"items\" value=\"c\" checked=\"1\">\n",
"c</label></fieldset></form>\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 '<input type=\"checkbox\" name=\"items\" value=\"a\" checked=\"1\">' in to_xml(multiform)\n",
"assert '<input type=\"checkbox\" name=\"items\" value=\"b\">' in to_xml(multiform)\n",
"assert '<input type=\"checkbox\" name=\"items\" value=\"c\" checked=\"1\">' in to_xml(multiform)\n",
"multiform"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down

0 comments on commit 803d974

Please sign in to comment.