| 2483 | 2483 | infoBlock.innerHTML = ''; |
| 2484 | 2484 | } |
| 2485 | 2485 | } |
| 2486 | + |
| 2487 | +/** |
| 2488 | + * Provides a matcher function for select2 that matches both the text and value of options. |
| 2489 | + * @param {import('select2').SearchOptions} params |
| 2490 | + * @param {import('select2').OptGroupData|import('select2').OptionData} data |
| 2491 | + * @return {import('select2').OptGroupData|import('select2').OptionData|null} |
| 2492 | + */ |
| 2493 | +export function textValueMatcher(params, data) { |
| 2494 | + // Always return the object if there is nothing to compare |
| 2495 | + if (params.term == null || params.term.trim() === '') { |
| 2496 | + return data; |
| 2497 | + } |
| 2498 | + |
| 2499 | + // Do a recursive check for options with children |
| 2500 | + if (data.children && data.children.length > 0) { |
| 2501 | + // Clone the data object if there are children |
| 2502 | + // This is required as we modify the object to remove any non-matches |
| 2503 | + const match = $.extend(true, {}, data); |
| 2504 | + |
| 2505 | + // Check each child of the option |
| 2506 | + for (let c = data.children.length - 1; c >= 0; c--) { |
| 2507 | + const child = data.children[c]; |
| 2508 | + |
| 2509 | + const matches = textValueMatcher(params, child); |
| 2510 | + |
| 2511 | + // If there wasn't a match, remove the object in the array |
| 2512 | + if (matches == null) { |
| 2513 | + match.children.splice(c, 1); |
| 2514 | + } |
| 2515 | + } |
| 2516 | + |
| 2517 | + // If any children matched, return the new object |
| 2518 | + if (match.children.length > 0) { |
| 2519 | + return match; |
| 2520 | + } |
| 2521 | + |
| 2522 | + // If there were no matching children, check just the plain object |
| 2523 | + return textValueMatcher(params, match); |
| 2524 | + } |
| 2525 | + |
| 2526 | + const textMatch = compareIgnoreCaseAndAccents(data.text, params.term, (a, b) => a.indexOf(b) > -1); |
| 2527 | + const valueMatch = data.element instanceof HTMLOptionElement && compareIgnoreCaseAndAccents(data.element.value, params.term, (a, b) => a.indexOf(b) > -1); |
| 2528 | + |
| 2529 | + if (textMatch || valueMatch) { |
| 2530 | + return data; |
| 2531 | + } |
| 2532 | + |
| 2533 | + // If it doesn't contain the term, don't return anything |
| 2534 | + return null; |
| 2535 | +} |