PageSourceSearch

https://www.standard-advisory.com/assets/utils/filter_serializer

js standard-advisory.com collected 2026-10-09 22:37:11 UTC 2,970 bytes, 91 lines download raw bytes

1
2/**
3 * Extracts the value from a filter row based on type and operator.
4 * Handles:
5 * - between (from/to inputs)
6 * - multi-select (Choices.js or standard)
7 * - single values
8 * 
9 * @param {HTMLElement} row - The .filter-row element
10 * @param {Object} context - { datasetKey: String, defsByField: Object }
11 * @returns {Object|null} - { dataset: String, field: String, op: String, value: Any } or null if invalid
12 */
13export function serializeFilterRow(row, { datasetKey, defsByField } = {}) {
14    const fieldSelect = row.querySelector('.filter-field')
15
16    // Safety check
17    if (!fieldSelect || !fieldSelect.value) return null
18
19    const field = fieldSelect.value
20
21    // Strict requirement: Definitions must be present to ensure type safety (multiple, type, etc)
22    if (!defsByField) return null
23
24    const def = defsByField[field]
25
26    // Determine Type/Multiple from definition (or fallback to logic if missing, but defs expected)
27    const isMultiple = !!(def && def.multiple)
28
29    const opSelect = row.querySelector('.filter-op')
30    let op = opSelect ? opSelect.value : null
31    if (!op) {
32        op = isMultiple ? 'in' : 'eq'
33    }
34
35    let val = null
36
37    if (op === 'between') {
38        const fromInput = row.querySelector('.filter-value-from')
39        const toInput = row.querySelector('.filter-value-to')
40        const v1 = fromInput ? fromInput.value : ''
41        const v2 = toInput ? toInput.value : ''
42
43        // Save if at least one bound is present
44        if (v1 !== '' || v2 !== '') {
45            val = { from: v1, to: v2 }
46        }
47    } else {
48        const valInput = row.querySelector('.filter-value')
49        if (valInput) {
50            if (isMultiple && valInput.options) {
51                // Handle Multi-select (Choices.js or native)
52                // If Choices.js is active, usually it updates the underlying select options
53
54                val = Array.from(valInput.options)
55                    .filter(opt => opt.selected)
56                    .map(opt => opt.value)
57                    .filter(v => v !== "")
58
59                if (val.length === 0) val = null
60            } else {
61                // Single value or fallback if multiple but text input
62                val = valInput.value
63                // Empty string check
64                if (val === '') val = null
65
66                // If multiple but text, maybe split by comma? 
67                // For robustness, let's splits if multiple
68                if (isMultiple && val && typeof val === 'string') {
69                    val = val.split(',').map(s => s.trim()).filter(s => s)
70                }
71            }
72        }
73    }
74
75    if (val === null) return null
76
77    const result = {
78        dataset: datasetKey, // Keep for UI Restoration context
79        op,
80        value: val
81    }
82
83    // V2.1: If field is namespaced, it's a dimension
84    if (field.includes('.')) {
85        result.dimension = field
86    } else {
87        result.field = field
88    }
89
90    return result
91};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.