pub struct OptionsBy {
pub field: String,
pub options: BTreeMap<String, Vec<SelectOption>>,
}Expand description
A select whose options depend on another column: the browser looks the row’s
value of field up in options. A value with no entry offers no choices.
Fields§
§field: String§options: BTreeMap<String, Vec<SelectOption>>Implementations§
Source§impl OptionsBy
impl OptionsBy
Sourcepub fn new(field: impl Into<String>) -> Self
pub fn new(field: impl Into<String>) -> Self
Examples found in repository?
examples/library/main.rs (line 133)
125 fn schema(&self, ctx: &Context) -> Result<Schema, ApiError> {
126 let genres = Self::genres(ctx)?;
127 let branches = Self::branches(ctx)?;
128
129 let mut names: Vec<&str> = genres.iter().map(|g| g.genre.as_str()).collect();
130 names.sort_unstable();
131 names.dedup();
132
133 let mut by_genre = OptionsBy::new("genre");
134 for genre in &names {
135 let subgenres: Vec<&str> = genres
136 .iter()
137 .filter(|g| g.genre == *genre)
138 .map(|g| g.subgenre.as_str())
139 .collect();
140 by_genre.insert(*genre, subgenres);
141 }
142
143 // Wide enough for the longest subgenre there is, computed here so the
144 // browser does not have to measure anything. It is the count of
145 // characters, nothing more: what the control puts around them is the
146 // bundle's business.
147 let widest = genres.iter().map(|g| g.subgenre.len()).max().unwrap_or(0);
148 let width_ch = u16::try_from(widest.max(8)).unwrap_or(u16::MAX);
149
150 // A key that shows a branch's name and stores its code.
151 let branch_keys: Vec<SelectOption> = branches
152 .iter()
153 .map(|b| SelectOption::labelled(&b.code, &b.name))
154 .collect();
155
156 let mut publishers: Vec<String> = ctx
157 .optional_rows::<Book>(BOOKS_FILE)?
158 .iter()
159 .map(|b| b.publisher.trim().to_string())
160 .filter(|p| !p.is_empty())
161 .collect();
162 publishers.sort_unstable();
163 publishers.dedup();
164
165 Ok(Schema::new([
166 Column::string("title", "Title").width_ch(30),
167 Column::string("author_first", "First").width_ch(12),
168 Column::string("author_last", "Last").width_ch(14),
169 Column::select("genre", "Genre", names)
170 .allow_empty()
171 .cascades_to(["subgenre"]),
172 Column::select_by("subgenre", "Subgenre", by_genre)
173 .allow_empty()
174 .width_ch(width_ch),
175 Column::select(
176 "edition",
177 "Edition",
178 [
179 SelectOption::labelled("1", "First (1)"),
180 SelectOption::labelled("2", "Second (2)"),
181 SelectOption::labelled("3", "Third (3)"),
182 ],
183 )
184 .allow_empty()
185 .numeric_value(),
186 // A year is a whole number; a rating is not, which is what the
187 // absence of int_only means.
188 Column::number("year", "Year").int_only().width_ch(4),
189 Column::number("copies", "Copies").int_only().width_ch(3),
190 Column::number("rating", "Rating").width_ch(3),
191 Column::boolean("lent", "Lent"),
192 Column::string("publisher", "Publisher")
193 .width_ch(20)
194 .datalist("publishers"),
195 Column::string("donor", "Donated by")
196 .width_ch(20)
197 .datalist("reader-names"),
198 Column::spaced_string("call_number", "Call no.").width_ch(14),
199 Column::string("pronunciation", "Say")
200 .width_ch(16)
201 .speak(Speak::new(
202 "http://127.0.0.1:8765/say?text={value}",
203 "table-editor-speech-url",
204 )),
205 Column::map(
206 "shelved",
207 "Shelved",
208 MapSpec::new("Branch", "Copies")
209 .chips_show_key()
210 .key_options(branch_keys)
211 .value_options([
212 SelectOption::labelled("one", "One"),
213 SelectOption::labelled("several", "Several"),
214 SelectOption::labelled("many", "Many"),
215 ]),
216 ),
217 Column::string("due", "Due").width_ch(10),
218 Column::string("link", "Catalogue").width_ch(30),
219 Column::computed("shelf", "Shelf mark", "shelf").width_ch(18),
220 Column::text("notes", "Notes").wide(),
221 ])
222 .sortable()
223 .datalist("publishers", Datalist::fixed(publishers))
224 .datalist(
225 "reader-names",
226 Datalist::from_rows(["author_last", "author_first"], ", "),
227 )
228 .new_row(
229 NewRow::new()
230 .with("title", "")
231 .with("author_first", "")
232 .with("author_last", "")
233 .with("genre", "")
234 .with("subgenre", "")
235 .with("publisher", "")
236 .with("donor", "")
237 .with("call_number", "")
238 .with("pronunciation", "")
239 .with("due", "")
240 .with("link", "")
241 .with("notes", "")
242 .with("copies", 1)
243 .carry_forward(["genre", "subgenre", "publisher"]),
244 ))
245 }pub fn with( self, value: impl Into<String>, options: impl IntoIterator<Item = impl Into<SelectOption>>, ) -> Self
Sourcepub fn insert(
&mut self,
value: impl Into<String>,
options: impl IntoIterator<Item = impl Into<SelectOption>>,
)
pub fn insert( &mut self, value: impl Into<String>, options: impl IntoIterator<Item = impl Into<SelectOption>>, )
Examples found in repository?
examples/library/main.rs (line 140)
125 fn schema(&self, ctx: &Context) -> Result<Schema, ApiError> {
126 let genres = Self::genres(ctx)?;
127 let branches = Self::branches(ctx)?;
128
129 let mut names: Vec<&str> = genres.iter().map(|g| g.genre.as_str()).collect();
130 names.sort_unstable();
131 names.dedup();
132
133 let mut by_genre = OptionsBy::new("genre");
134 for genre in &names {
135 let subgenres: Vec<&str> = genres
136 .iter()
137 .filter(|g| g.genre == *genre)
138 .map(|g| g.subgenre.as_str())
139 .collect();
140 by_genre.insert(*genre, subgenres);
141 }
142
143 // Wide enough for the longest subgenre there is, computed here so the
144 // browser does not have to measure anything. It is the count of
145 // characters, nothing more: what the control puts around them is the
146 // bundle's business.
147 let widest = genres.iter().map(|g| g.subgenre.len()).max().unwrap_or(0);
148 let width_ch = u16::try_from(widest.max(8)).unwrap_or(u16::MAX);
149
150 // A key that shows a branch's name and stores its code.
151 let branch_keys: Vec<SelectOption> = branches
152 .iter()
153 .map(|b| SelectOption::labelled(&b.code, &b.name))
154 .collect();
155
156 let mut publishers: Vec<String> = ctx
157 .optional_rows::<Book>(BOOKS_FILE)?
158 .iter()
159 .map(|b| b.publisher.trim().to_string())
160 .filter(|p| !p.is_empty())
161 .collect();
162 publishers.sort_unstable();
163 publishers.dedup();
164
165 Ok(Schema::new([
166 Column::string("title", "Title").width_ch(30),
167 Column::string("author_first", "First").width_ch(12),
168 Column::string("author_last", "Last").width_ch(14),
169 Column::select("genre", "Genre", names)
170 .allow_empty()
171 .cascades_to(["subgenre"]),
172 Column::select_by("subgenre", "Subgenre", by_genre)
173 .allow_empty()
174 .width_ch(width_ch),
175 Column::select(
176 "edition",
177 "Edition",
178 [
179 SelectOption::labelled("1", "First (1)"),
180 SelectOption::labelled("2", "Second (2)"),
181 SelectOption::labelled("3", "Third (3)"),
182 ],
183 )
184 .allow_empty()
185 .numeric_value(),
186 // A year is a whole number; a rating is not, which is what the
187 // absence of int_only means.
188 Column::number("year", "Year").int_only().width_ch(4),
189 Column::number("copies", "Copies").int_only().width_ch(3),
190 Column::number("rating", "Rating").width_ch(3),
191 Column::boolean("lent", "Lent"),
192 Column::string("publisher", "Publisher")
193 .width_ch(20)
194 .datalist("publishers"),
195 Column::string("donor", "Donated by")
196 .width_ch(20)
197 .datalist("reader-names"),
198 Column::spaced_string("call_number", "Call no.").width_ch(14),
199 Column::string("pronunciation", "Say")
200 .width_ch(16)
201 .speak(Speak::new(
202 "http://127.0.0.1:8765/say?text={value}",
203 "table-editor-speech-url",
204 )),
205 Column::map(
206 "shelved",
207 "Shelved",
208 MapSpec::new("Branch", "Copies")
209 .chips_show_key()
210 .key_options(branch_keys)
211 .value_options([
212 SelectOption::labelled("one", "One"),
213 SelectOption::labelled("several", "Several"),
214 SelectOption::labelled("many", "Many"),
215 ]),
216 ),
217 Column::string("due", "Due").width_ch(10),
218 Column::string("link", "Catalogue").width_ch(30),
219 Column::computed("shelf", "Shelf mark", "shelf").width_ch(18),
220 Column::text("notes", "Notes").wide(),
221 ])
222 .sortable()
223 .datalist("publishers", Datalist::fixed(publishers))
224 .datalist(
225 "reader-names",
226 Datalist::from_rows(["author_last", "author_first"], ", "),
227 )
228 .new_row(
229 NewRow::new()
230 .with("title", "")
231 .with("author_first", "")
232 .with("author_last", "")
233 .with("genre", "")
234 .with("subgenre", "")
235 .with("publisher", "")
236 .with("donor", "")
237 .with("call_number", "")
238 .with("pronunciation", "")
239 .with("due", "")
240 .with("link", "")
241 .with("notes", "")
242 .with("copies", 1)
243 .carry_forward(["genre", "subgenre", "publisher"]),
244 ))
245 }Trait Implementations§
impl Eq for OptionsBy
impl StructuralPartialEq for OptionsBy
Auto Trait Implementations§
impl Freeze for OptionsBy
impl RefUnwindSafe for OptionsBy
impl Send for OptionsBy
impl Sync for OptionsBy
impl Unpin for OptionsBy
impl UnsafeUnpin for OptionsBy
impl UnwindSafe for OptionsBy
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more