SearchPanel
SearchPanel from vertigo-forms is an input with results loaded for the typed query. It takes:
query- aValuewith the typed text,cache- anAutoMapgiving a resource for every query, usually aLazyCache,render_results- a function rendering the loaded results,params- texts and the minimal number of characters needed to start searching.
use std::rc::Rc; use vertigo::{dom, AutoJsJson, AutoMap, DomNode, RequestBuilder, Value}; use vertigo_forms::{SearchPanel, SearchPanelParams}; #[derive(AutoJsJson, Clone, PartialEq)] pub struct City { name: String, country: String, } let query = Value::new(String::new()); // A cached request for every query let cache = AutoMap::new(|_, query: &String| { RequestBuilder::get(format!("/api/cities?q={query}")) .ttl_minutes(10) .lazy_cache(|status, body| { if status == 200 { Some(body.into::<Vec<City>>()) } else { None } }) }); let render_results: Rc<dyn Fn(Rc<Vec<City>>) -> DomNode> = Rc::new(|cities| { dom! { <ul> {..cities.iter().map(|city| dom! { <li>{&city.name} ", " {&city.country}</li> })} </ul> } }); dom! { <SearchPanel query={query} cache={cache} render_results={render_results} params={SearchPanelParams { prompt: "City: ".to_string(), min_chars: 2, ..Default::default() }} i:placeholder="Type a city name" /> }
Until enough characters are typed, the panel shows a hint, then a loading text, and finally the results or the "No results" text. As the AutoMap keeps every query, going back to a previous query shows its results instantly, without a request (until the cache expires).
Remember to encode the query if it can contain characters with a special meaning in URLs, like & or #.
The look can be adjusted with attribute groups: c: for the container, i: for the input, pc: for the results and ei: for the "No results" element, like the i:placeholder above.
See it in action, along with other components, in the storybook.