PageSourceSearch

https://www.surgeons.org/-/media/Themes/RACS/surgeons-org/Custom/S…&hash=06A7478B3E09AD15C953D348213A2153

js surgeons.org collected 2026-09-24 17:09:59 UTC 9,001 bytes, 270 lines download raw bytes

1
2XA.component.sitecoreSearch = (function($) {
3    let api = {};
4    let config = {
5        widgetId: '',
6        sourceId: '',
7        sources: [],
8        facets: [],
9        filterMap: {},
10        apiKey: '',
11        apiUrl: '',
12        defaultPageSize: 6,
13        suggestions: '',
14        sortorder: '',
15        permanentFilters: []
16    };
17
18    api.configure = function(options) {
19        config = $.extend(true, {}, config, options);
20    };
21
22    function buildFilterObject(inputArray, permanentFilters) {
23        // Initialize the main AND filter that will contain all filter groups
24        let mainFilter = {
25            type: "and",
26            filters: []
27        };
28
29        // Process user input filters if they exist
30        if (Array.isArray(inputArray) && inputArray.length > 0) {
31            // Group filters by name
32            const grouped = inputArray.reduce((acc, item) => {
33                if (!acc[item.name]) acc[item.name] = [];
34                acc[item.name].push(item.value);
35                return acc;
36            }, {});
37
38            // Create OR filters for each group
39            Object.entries(grouped).forEach(([name, values]) => {
40                if (values.length > 1) {
41                    mainFilter.filters.push({
42                        type: "or",
43                        filters: values.map(value => ({
44                            name,
45                            type: "eq",
46                            value
47                        }))
48                    });
49                } else {
50                    mainFilter.filters.push({
51                        name,
52                        type: "eq",
53                        value: values[0]
54                    });
55                }
56            });
57        }
58
59        // Process permanent filters if they exist
60        if (Array.isArray(config.permanentFilters) && config.permanentFilters.length > 0) {
61            // Group permanent filters by name
62            const groupedPermanent = config.permanentFilters.reduce((acc, item) => {
63                const name = item.name;
64                const type = item.type ?? "eq";
65                const value = item.value;
66
67                if (!acc[name]) acc[name] = [];
68                acc[name].push({ type, value });
69                return acc;
70            }, {});
71
72            // Create OR filters for each permanent filter group
73            // Create OR filters for each permanent filter group
74            Object.entries(groupedPermanent).forEach(([name, entries]) => {
75                if (entries.length > 1) {
76                    mainFilter.filters.push({
77                        type: "or",
78                        filters: entries.map(({ type, value }) => ({
79                            name,
80                            type: type ?? "eq",
81                            value
82                        }))
83                    });
84                } else {
85                    mainFilter.filters.push({
86                        name,
87                        type: entries[0].type ?? "eq",
88                        value: entries[0].value
89                    });
90                }
91            });
92        }
93
94        // If no filters were added, return null
95        if (mainFilter.filters.length === 0) {
96            return null;
97        }
98
99        return mainFilter;
100    }
101
102    function buildRequest(query, filters, pagesize = config.defaultPageSize, offset = 0) {
103        let requestSources = [];
104        if(config.sources.length > 0) requestSources = config.sources
105        else requestSources = [config.sourceId]
106        let requestItem = {
107            rfk_id: config.widgetId,
108            entity: "content",
109            sources: requestSources,
110            search: {
111                content: {},
112                limit: pagesize,
113                offset: offset,
114                query: {},
115                
116            }
117        };
118        if (config.facets.length > 0){
119            requestItem.search.facet = {
120                all: true,
121                    types: config.facets.map(facet => ({ name: facet }))
122            };
123        }
124        
125        if(config.sortorder !== ''){
126            requestItem.search.sort = {
127                value: [
128                    {"name": config.sortorder}
129                ]
130            }
131        };
132
133        if (query && query.length > 0) {
134            requestItem.search.query.keyphrase = query;
135        }
136
137        if ((filters && filters.length > 0) || (config.permanentFilters && config.permanentFilters.length > 0)) {
138            const filterObject = buildFilterObject(filters, config.permanentFilters);
139            if (filterObject) {
140                requestItem.search.filter = filterObject;
141            }
142        }
143
144        return {
145            widget: {
146                items: [requestItem]
147            }
148        };
149    }
150
151    function buildSuggestionRequest(query, filters) {
152        let requestSources = [];
153        if(config.sources.length > 0) requestSources = config.sources
154        else requestSources = [config.sourceId]
155        let requestItem = {
156            widget: {
157                items: [{
158                    rfk_id: config.widgetId,
159                    entity: "content",
160                    sources: requestSources,
161                    search: {
162                        content: {},
163                        query: {
164                            keyphrase: query
165                        },
166                        suggestion: [{
167                            name: config.suggestions
168                        }]
169                    }
170                }]
171            }
172        };
173
174        if ((filters && filters.length > 0) || (config.permanentFilters && config.permanentFilters.length > 0)) {
175            const filterObject = buildFilterObject(filters, config.permanentFilters);
176            if (filterObject) {
177                requestItem.widget.items[0].search.filter = filterObject;
178            }
179        }
180        
181        return requestItem;
182    }
183
184    api.search = function(query = '', filters = [], pagesize = config.defaultPageSize, offset = 0) {
185        const request = buildRequest(query, filters, pagesize, offset);
186
187        //console. log('Search request:', JSON.stringify(request));
188
189        return $.ajax({
190            type: "POST",
191            url: config.apiUrl,
192            dataType: 'json',
193            data: JSON.stringify(request),
194            beforeSend: function(xhr) {
195                xhr.setRequestHeader('Authorization', 'Bearer ' + config.apiKey);
196            }
197        });
198    };
199
200    api.getSuggestions = function(query) {
201        if(config.suggestions === '') return;
202
203        if (!query || query.length < 2) {
204            return Promise.resolve({ widgets: [] });
205        }
206
207        const request = buildSuggestionRequest(query);
208
209        return $.ajax({
210            type: "POST",
211            url: config.apiUrl,
212            dataType: 'json',
213            data: JSON.stringify(request),
214            beforeSend: function(xhr) {
215                xhr.setRequestHeader('Authorization', 'Bearer ' + config.apiKey);
216            }
217        });
218    };
219
220    api.buildPagination = function(totalItems, limit, currentPage) {
221        const totalPages = Math.ceil(totalItems / limit);
222        const pages = new Set();
223        const result = [];
224
225        if (totalPages <= 7) {
226            for (let i = 1; i <= totalPages; i++) pages.add(i);
227        } else if (currentPage <= 5) {
228            for (let i = 1; i <= 5; i++) pages.add(i);
229            pages.add(totalPages);
230        } else if (currentPage >= totalPages - 4) {
231            pages.add(1);
232            for (let i = totalPages - 4; i <= totalPages; i++) pages.add(i);
233        } else {
234            pages.add(1);
235            for (let i = currentPage - 2; i <= currentPage + 2; i++) pages.add(i);
236            pages.add(totalPages);
237        }
238
239        const sortedPages = Array.from(pages).sort((a, b) => a - b);
240
241        if (currentPage > 1) {
242            result.push({ type: "previous", page: currentPage - 1, offset: (currentPage - 2) * limit });
243        }
244
245        for (let i = 0; i < sortedPages.length; i++) {
246            const page = sortedPages[i];
247            result.push({
248                type: "page",
249                page,
250                offset: (page - 1) * limit,
251                isCurrent: page === currentPage
252            });
253
254            const next = sortedPages[i + 1];
255            if (next && next - page > 1) {
256                result.push({ type: "ellipsis" });
257            }
258        }
259
260        if (currentPage < totalPages) {
261            result.push({ type: "next", page: currentPage + 1, offset: currentPage * limit });
262        }
263
264        return result;
265    };
266
267    return api;
268})(jQuery);
269
270XA.register("sitecoreSearch", XA.component.sitecoreSearch);

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.