|
13 | 13 | */ |
14 | 14 |
|
15 | 15 | import { FilterType } from './filterTypes.js'; |
16 | | -import { h, RemoteData } from '/js/src/index.js'; |
| 16 | +import { h, RemoteData, DropdownComponent } from '/js/src/index.js'; |
17 | 17 |
|
18 | 18 | /** |
19 | 19 | * Builds a filter element. If options to show, selector filter element; otherwise, input element. |
@@ -136,6 +136,73 @@ export const groupedDropdownComponent = ({ |
136 | 136 | ]); |
137 | 137 | }; |
138 | 138 |
|
| 139 | +/** |
| 140 | + * Builds a filter element. If options to show, selector filter element; otherwise, input element. |
| 141 | + * @param {object} config - Configuration object for building the filter element. |
| 142 | + * @param {string} config.queryLabel - The key used to query the storage with this parameter. |
| 143 | + * @param {string} config.placeholder - The placeholder text to be displayed in the input field. |
| 144 | + * @param {string} config.id - The unique identifier for the input field. |
| 145 | + * @param {object} config.filterMap - Map of the current filter values. |
| 146 | + * @param {string} [config.type='text'] - The type of the filter element (e.g., 'text', 'number'). |
| 147 | + * @param {Record<string, object>} [config.options={}] - List of options for an input with dropdown selector (optional). |
| 148 | + * @param {(filterId: string, value: string, setUrl: boolean) => void} config.onChangeCallback |
| 149 | + * - Callback to be triggered on the change event of the filter. |
| 150 | + * @param {(filterId: string, value: string, setUrl: boolean) => void} config.onInputCallback |
| 151 | + * - Callback to be triggered on the input event. |
| 152 | + * @param {(filterId: string, value: string, setUrl: boolean) => void} config.onEnterCallback |
| 153 | + * - Callback to be triggered when the Enter key is pressed. |
| 154 | + * @param {string} [config.width='.w-20'] - The CSS class that defines the width of the filter. |
| 155 | + * @returns {vnode} A virtual node element representing the filter element. |
| 156 | + */ |
| 157 | +export const inputWithDropdownComponent = ({ |
| 158 | + queryLabel, |
| 159 | + placeholder, |
| 160 | + id, |
| 161 | + filterMap, |
| 162 | + options = {}, |
| 163 | + onChangeCallback, |
| 164 | + onInputCallback, |
| 165 | + onEnterCallback, |
| 166 | + type = 'text', |
| 167 | + width = '.w-20', |
| 168 | +}) => { |
| 169 | + const dropdownOptions = Object.keys(options); |
| 170 | + if (!dropdownOptions.length) { |
| 171 | + return filterInput({ queryLabel, placeholder, id, filterMap, onInputCallback, onEnterCallback, type, width }); |
| 172 | + } |
| 173 | + const dropdownComponent = DropdownComponent( |
| 174 | + filterInput({ |
| 175 | + queryLabel, |
| 176 | + placeholder, |
| 177 | + id, |
| 178 | + filterMap, |
| 179 | + type, |
| 180 | + onInputCallback, |
| 181 | + onEnterCallback, |
| 182 | + width: '.w-100', |
| 183 | + }), |
| 184 | + h('', { |
| 185 | + id: `${queryLabel?.toLowerCase()}-dropdown`, |
| 186 | + style: 'max-height: 300px; overflow-y: auto;', |
| 187 | + }, Object.entries(options) |
| 188 | + .filter(([option]) => option.toLowerCase().includes(filterMap[queryLabel]?.toLowerCase() ?? '')) |
| 189 | + .sort(([a], [b]) => b.localeCompare(a)) |
| 190 | + .map(([option, htmlOptions]) => h( |
| 191 | + 'button.btn.d-block.w-100', |
| 192 | + { |
| 193 | + onclick: () => { |
| 194 | + onChangeCallback(queryLabel, option, true); |
| 195 | + dropdownComponent.state.hidePopover(); |
| 196 | + }, |
| 197 | + ...htmlOptions ?? {}, |
| 198 | + }, |
| 199 | + [option, Object.keys(htmlOptions).length > 0 ? ' (frozen)' : ''], |
| 200 | + ))), |
| 201 | + ); |
| 202 | + |
| 203 | + return h(`${width}`, dropdownComponent); |
| 204 | +}; |
| 205 | + |
139 | 206 | /** |
140 | 207 | * Builds a filter input element that allows the user to specify a parameter to be used when querying objects. |
141 | 208 | * This function renders a text input element with event handling for input and Enter key press. |
|
0 commit comments