Annotating Search and Filters
Search and filter controls combine a read operation with several optional parameters. Annotate the form once: its controls are harvested into parameters, with their names, types, labels and HTML constraints.
Search with filters — form-level annotation
<form axag-intent="product.search" axag-entity="product" axag-action-type="read"
axag-scope="public" axag-risk-level="none" axag-idempotent="true">
<label for="q">Search</label>
<input id="q" name="query" axag-parameter-required="true" />
<label for="category">Category</label>
<select id="category" name="category"
axag-parameter-enum='["electronics","clothing","home"]'>
<option value="">All Categories</option>
</select>
<label for="price_min">Minimum price</label>
<input id="price_min" name="price_min" type="number" min="0" step="0.01" />
<label for="price_max">Maximum price</label>
<input id="price_max" name="price_max" type="number" min="0" step="0.01" />
<button type="submit">Search</button>
</form>
The manifest this produces declares every filter, without any of them being listed on the annotation:
Harvested parameters
{
"intent": "product.search",
"required_parameters": [
{ "name": "query", "type": "string", "description": "Search", "source": "harvested:html" }
],
"optional_parameters": [
{ "name": "category", "type": "string", "description": "Category",
"enum": ["electronics", "clothing", "home"], "source": "harvested:html" },
{ "name": "price_min", "type": "number", "min": 0, "description": "Minimum price", "source": "harvested:html" },
{ "name": "price_max", "type": "number", "min": 0, "description": "Maximum price", "source": "harvested:html" }
]
}
Notes on what the harvester read:
- The control's
namebecomes the parameter name, and its<label>becomes the description an agent reads. type="number"with a decimalstepbecomesnumber; without one it becomesinteger.minandmaxcarry over.- A control is required when the HTML says so (
required) or whenaxag-parameter-required="true"says so. axag-parameter-*attributes fill what the markup can't express — here, the category values, since the<option>list is a placeholder plus a server-rendered set.
A filter that isn't a form control at all — a set of chips, a custom dropdown — can't be harvested. Declare those in axag-optional-parameters on the annotation.