# Test zone inputs
from fasthtml.common import to_xml
zone = FocusZone(
id="browser",
item_selector="tr",
data_attributes=("job-id", "plugin-name")
)
inputs = render_zone_hidden_inputs(zone)
assert len(inputs) == 2
html = to_xml(inputs[0])
assert 'id="browser-job-id"' in html
# Name converts hyphens to underscores for Python compatibility
assert 'name="job_id"' in htmlHidden Inputs
Generate hidden inputs for HTMX integration with keyboard navigation.
Zone Data Inputs
Generate hidden inputs for tracking focused item data attributes.
The name attribute converts hyphens to underscores for Python/FastHTML compatibility: - HTML data attribute: data-item-id - Hidden input name: item_id - FastHTML route parameter: item_id
Include Selector Builder
Build hx-include selector for HTMX requests.
build_include_selector
def build_include_selector(
zone:FocusZone, # the zone to include inputs from
include_state:bool=False, # include state inputs
)->str: # CSS selector for hx-include
Build hx-include selector for zone’s hidden inputs.
# Test include selector
zone = FocusZone(
id="browser",
data_attributes=("job-id", "plugin-name")
)
selector = build_include_selector(zone)
assert selector == "#browser-job-id, #browser-plugin-name"
selector_with_state = build_include_selector(zone, include_state=True)
assert "#kb-active-zone" in selector_with_statebuild_all_zones_include_selector
def build_all_zones_include_selector(
manager:ZoneManager, # the zone manager
include_state:bool=False, # include state inputs
)->str: # CSS selector for all zones
Build hx-include selector for all zones’ hidden inputs.
Deduplicates selectors - zones with the same hidden_input_prefix will only include each input once.
# Test all zones selector
selector = build_all_zones_include_selector(manager)
assert "#z1-a" in selector
assert "#z2-b" in selector
assert "#z2-c" in selector# Test deduplication in selector - zones with same prefix
selector = build_all_zones_include_selector(manager_shared)
# Should only have 2 selectors (deduplicated), not 4
assert selector.count("#sd-focused-job-id") == 1
assert selector.count("#sd-focused-plugin-name") == 1
assert selector == "#sd-focused-job-id, #sd-focused-plugin-name"