PageSourceSearch

https://www.xanax.com/-/media/Base-Themes/SearchTheme/Scripts/component-search-page-selector.js

js xanax.com collected 2026-09-24 22:54:55 UTC 18,629 bytes, 391 lines download raw bytes

1/**
2 * Facet page selector component functionality
3 * @module searchPageSelector
4 * @param  {jQuery} $ Instance of jQuery
5 * @param  {Document} document dom document object
6 * @return {Object} list of methods for working with component page selector
7*/
8XA.component.search.pageSelector = (function ($, document) {
9    /**
10    * This object stores all public api methods
11    * @type {Object.<Methods>}
12    * @memberOf module:searchPageSelector
13    */
14    var api = {},
15        queryModel,
16        initialized = false;
17    facetName = "e";
18    /**
19    * @name module:searchPageSelector.SearchPageSelectorModel
20    * @constructor
21    * @augments Backbone.Model
22    */
23    var SearchPageSelectorModel = Backbone.Model.extend(
24        /** @lends module:searchPageSelector.SearchPageSelectorModel.prototype **/
25        {
26            /**
27            * Default model options
28            * @default
29            */
30            defaults: {
31                dataProperties: {},
32                resultsCount: 0,
33                offset: 0,
34                selectedValue: 1,
35                pageSize: 0,
36                repeatRequest: false,
37                template: "<ul class='page-selector-list'> " +
38                    "<li class='page-selector-item-first'><a href='#'><%= data.first %></a></li>" +
39                    "<li class='page-selector-item-previous'><a href='#'><%= data.previous %></a></li>" +
40                    "<% var beforePage = 0; %>" +
41                    "<% _.each(data.pages, function(page){ %>" +
42                    "<% if((beforePage+1) != page.number){ %>" +
43                    "<li><span class='page-selector-more'>...</span></li>" +
44                    "<% } %>" +
45                    "<% beforePage = page.number; %>" +
46                    "<% if(data.selectedValue === page.number){ %>" +
47                    "<% active = 'active'; %>" +
48                    "<% }else { active = '' } %>" +
49                    "<li><a class='page-selector-item-link <%= active %>' data-offset='<%= page.offset %>' data-itemNumber='<%= page.number %>' href='#'><%= page.number %></a></li>" +
50                    "<% }); %>" +
51                    "<li class='page-selector-item-next'><a href='#'><%= data.next %></a></li>" +
52                    "<li class='page-selector-item-last'><a href='#'><%= data.last %></a></li>" +
53                    "</ul>",
54                sig: [],
55                timeStamp: new Date().getTime()
56            }
57        });
58    /**
59     * @name module:searchPageSelector.SearchPageSelectorView
60     * @constructor
61     * @augments Backbone.View
62     */
63    var SearchPageSelectorView = XA.component.search.baseView.extend(
64        /** @lends module:searchPageSelector.SearchPageSelectorView **/
65        {
66            /**
67           * Initially sets data to model and watches events on which
68           * view should be updated
69           * @listens module:searchPageSelector.SearchPageSelectorView~event:change
70           * @listens module:XA.component.search.vent~event:results-loaded
71           * @memberof module:searchPageSelector.SearchPageSelectorView
72           * @alias module:searchPageSelector.SearchPageSelectorView#initialize
73           */
74            initialize: function () {
75                var dataProp = this.$el.data();
76
77                if (dataProp.properties.searchResultsSignature === null) {
78                    dataProp.properties.searchResultsSignature = "";
79                }
80
81                this.model.set("dataProperties", dataProp);
82                this.model.set("sig", this.translateSignatures(dataProp.properties.searchResultsSignature, facetName));
83                this.model.on("change", this.render, this);
84
85                XA.component.search.vent.on("results-loaded", this.handleLoadedData.bind(this));
86
87                //check whether page is opened from disc - if yes then we are in Creative Exchange mode and lets mock some content
88                if (window.location.href.startsWith("file://")) {
89                    this.model.set({
90                        "resultsCount": 10,
91                        "pageSize": 2,
92                        "selectedValue": 2
93                    });
94                }
95            },
96            /**
97             * list of events for Backbone View
98             * @memberof module:searchPageSelector.SearchPageSelectorView
99             * @alias module:searchPageSelector.SearchPageSelectorView#events
100             */
101            events: {
102                'click .page-selector-item-link': "updateSelectedValue",
103                'click .page-selector-item-first a': "showFirstPage",
104                'click .page-selector-item-last a': "showLastPage",
105                'click .page-selector-item-previous a': "showPrevPage",
106                'click .page-selector-item-next a': "showNextPage"
107            },
108            /**
109            * Updates model values with selectedValue
110            * and data object from server response
111            * @param {Object} data Data that contains component properties
112            * @param {Number} selectedValue number of selected page 
113            * @memberOf module:searchPageSelector.SearchPageSelectorView
114            * @alias module:searchPageSelector.SearchPageSelectorView#updateModelAfterSearch
115            */
116            updateModelAfterSearch: function (data, selectedValue) {
117                this.model.set({
118                    "pageSize": parseInt(data.pageSize),
119                    "resultsCount": parseInt(data.dataCount),
120                    "offset": parseInt(data.offset),
121                    "selectedValue": parseInt(selectedValue)
122                });
123                this.model.set("timeStamp", new Date().getTime());
124                this.updateElementCssClass(data);
125            },
126            /**
127            * Function that based on selected component values sets css class
128            * page-selector-empty or page-selector-single-page
129            * @param {Object} data Data that contains component properties
130            * @memberOf module:searchPageSelector.SearchPageSelectorView
131            * @alias module:searchPageSelector.SearchPageSelectorView#updateElementCssClass
132            */
133            updateElementCssClass: function (data) {
134                this.el.classList.remove("page-selector-empty")
135                this.el.classList.remove("page-selector-single-page")
136                if (data.dataCount === 0) {
137                    this.el.classList.add("page-selector-empty")
138                } else if (data.pageSize > data.dataCount || data.offset > data.dataCount) {
139                    this.el.classList.add("page-selector-single-page")
140                }
141            },
142            /**
143            * Updates hash according to changed component value
144            * @param {Event} event Event object that contains target with selected component value
145            * @memberOf module:searchPageSelector.SearchPageSelectorView
146            * @alias module:searchPageSelector.SearchPageSelectorView#updateSelectedValue
147            */
148            updateSelectedValue: function (event) {
149                event.preventDefault();
150
151                var sig = this.model.get("sig"),
152                    dataProp = $(event.target).data();
153
154                queryModel.updateHash(this.updateSignaturesHash(sig, dataProp.offset, {}));
155            },
156            /**
157            * Switches page selector to the first page and updates hash parameters
158            * @param {Event} event Event object that contains target with selected component value
159            * @memberOf module:searchPageSelector.SearchPageSelectorView
160            * @alias module:searchPageSelector.SearchPageSelectorView#showFirstPage
161            */
162            showFirstPage: function (event) {
163                event.preventDefault();
164
165                var sig = this.model.get("sig"),
166                    dataProp = $(event.target).data();
167
168                queryModel.updateHash(this.updateSignaturesHash(sig, 0, {}));
169            },
170            /**
171            * Switches page selector to the last page and updates hash parameters
172            * @param {Event} event Event object that contains target with selected component value
173            * @memberOf module:searchPageSelector.SearchPageSelectorView
174            * @alias module:searchPageSelector.SearchPageSelectorView#showLastPage
175            */
176            showLastPage: function (event) {
177                event.preventDefault();
178                var lastPageItems = this.model.get("resultsCount") % this.model.get("pageSize"),
179                    offset = this.model.get("resultsCount") - ((lastPageItems === 0) ? this.model.get("pageSize") : lastPageItems),
180                    sig = this.model.get("sig");
181
182                queryModel.updateHash(this.updateSignaturesHash(sig, offset, {}));
183            },
184            /**
185            * Switches page selector to the next page and updates hash parameters
186            * @param {Event} event Event object that contains target with selected component value
187            * @memberOf module:searchPageSelector.SearchPageSelectorView
188            * @alias module:searchPageSelector.SearchPageSelectorView#showNextPage
189            */
190            showNextPage: function (event) {
191                event.preventDefault();
192
193                var offset = this.model.get("offset"),
194                    sig = this.model.get("sig");
195
196                if ((offset + this.model.get("pageSize")) < this.model.get("resultsCount")) {
197                    offset += this.model.get("pageSize");
198                }
199
200                queryModel.updateHash(this.updateSignaturesHash(sig, offset, {}));
201            },
202            /**
203            * Switches page selector to the precious page and updates hash parameters
204            * @param {Event} event Event object that contains target with selected component value
205            * @memberOf module:searchPageSelector.SearchPageSelectorView
206            * @alias module:searchPageSelector.SearchPageSelectorView#showPrevPage
207            */
208            showPrevPage: function (event) {
209                event.preventDefault();
210
211                var offset = this.model.get("offset"),
212                    dataProp = $(event.target).data(),
213                    sig = this.model.get("sig");
214
215                if ((offset - this.model.get("pageSize")) >= 0) {
216                    offset -= this.model.get("pageSize");
217                }
218
219                queryModel.updateHash(this.updateSignaturesHash(sig, offset, {}));
220            },
221            /**
222            * Renders view
223            * @memberOf module:searchPageSelector.SearchPageSelectorView
224            * @alias module:searchPageSelector.SearchPageSelectorView#render
225            */
226            render: function () {
227                var inst = this,
228                    dataProp = this.model.get("dataProperties").properties,
229                    resultsCount = this.model.get("resultsCount"),
230                    pageSize = this.model.get("pageSize"),
231                    selectedValue = this.model.get("selectedValue"),
232                    pagesCount = Math.ceil(resultsCount / pageSize),
233                    pages = [],
234                    rangeStart = selectedValue - dataProp.treshold / 2,
235                    rangeEnd = selectedValue + dataProp.treshold / 2,
236                    templateObj;
237
238                if (rangeStart < 0) {
239                    rangeEnd += Math.abs(rangeStart);
240                }
241
242                if (rangeEnd > pagesCount) {
243                    rangeStart -= (rangeEnd - pagesCount);
244                }
245
246                if (dataProp.treshold >= pagesCount) {
247                    for (var i = 0; i < pagesCount; i++) {
248                        pages.push({ number: i + 1, offset: i * pageSize });
249                    }
250                }
251                else {
252                    for (var i = 1; i <= pagesCount; i++) {
253                        if ((i === 1) || (i === pagesCount)) {
254                            pages.push({ number: i, offset: (i - 1) * pageSize });
255                        }
256                        else if ((i >= rangeStart) && (i <= rangeEnd)) {
257                            pages.push({ number: i, offset: (i - 1) * pageSize });
258                        }
259                    }
260                }
261
262                templateObj = {
263                    previous: dataProp.previous,
264                    first: dataProp.first,
265                    next: dataProp.next,
266                    last: dataProp.last,
267                    pages: pages,
268                    selectedValue: selectedValue
269                };
270                var template = _.template(inst.model.get("template"));
271                var templateResult = template({ data: templateObj });
272                this.$el.html(templateResult);
273
274                this.handleButtonState(selectedValue, pagesCount);
275            },
276            /**
277            * Sets up page selectors buttons state depending on selected values
278            * @param {Number} selectedPage number of selected page
279            * @param {Number} pageCount number of pages
280            * @memberOf module:searchPageSelector.SearchPageSelectorView
281            * @alias module:searchPageSelector.SearchPageSelectorView#handleButtonState
282            */
283            handleButtonState: function (selectedPage, pageCount) {
284                this.$el.find(".page-selector-item-last, .page-selector-item-next").removeClass("inactive");
285                this.$el.find(".page-selector-item-first, .page-selector-item-previous").removeClass("inactive");
286
287
288                if (pageCount == 0) {
289                    this.$el.find(".page-selector-item-first, .page-selector-item-previous").addClass("inactive");
290                    this.$el.find(".page-selector-item-last, .page-selector-item-next").addClass("inactive");
291                }
292                else {
293                    if (selectedPage == 1) {
294                        this.$el.find(".page-selector-item-first, .page-selector-item-previous").addClass("inactive");
295                    }
296                    if (selectedPage == pageCount) {
297                        this.$el.find(".page-selector-item-last, .page-selector-item-next").addClass("inactive");
298                    }
299                }
300            },
301            /**
302            * Updates hash and model based on data object
303            * @param {Object} data Data that contains component properties
304            * @memberOf module:searchPageSelector.SearchPageSelectorView
305            * @alias module:searchPageSelector.SearchPageSelectorView#handleLoadedData
306            */
307            handleLoadedData: function (data) {
308                var that = this,
309                    sig = this.model.get("dataProperties").properties.searchResultsSignature.split(','),
310                    hash = queryModel.parseHashParameters(window.location.hash),
311                    newSelectedValue,
312                    param,
313                    hashObj,
314                    i;
315
316                if (typeof data.offset === 'undefined') {
317                    data.offset = 0;
318                }
319
320                for (i = 0; i < sig.length; i++) {
321                    if (encodeURIComponent(sig[i]) === data.searchResultsSignature) {
322                        if (data.pageSize > data.dataCount || data.offset > data.dataCount) {
323                            //When we have less results then page size then show first page
324                            this.updateModelAfterSearch(data, 1);
325                            //Wait till all requests are done and go to first page
326                            setTimeout(function () {
327                                //queryModel.updateHash({e: 0}); //- this will work, but doesn't give us proper browser history
328                                hashObj = queryModel.parseHashParameters(window.location.hash);
329                                param = data.searchResultsSignature !== "" ? data.searchResultsSignature + "_e" : "e";
330                                if (hash[param] !== "0") {
331                                    hashObj[param] = 0;
332                                    Backbone.history.navigate(that.createFirstPageUrlHash(hashObj), { trigger: true, replace: true });
333                                }
334                            }, 100);
335                        } else {
336                            newSelectedValue = Math.ceil(data.offset / data.pageSize) + 1;
337                            this.updateModelAfterSearch(data, newSelectedValue);
338                        }
339                    }
340                }
341            },
342            /**
343            * Calculates hash parameters for first page
344            * @param {Object} data Data that contains component properties
345            * @memberOf module:searchPageSelector.SearchPageSelectorView
346            * @alias module:searchPageSelector.SearchPageSelectorView#createFirstPageUrlHash
347            * @returns {String} hash parameter for first page
348            */
349            createFirstPageUrlHash: function (hashObj) {
350                var hashStr = "";
351
352                var i = 0;
353                _.each(hashObj, function (item, key) {
354                    if (i > 0) {
355                        hashStr += "&";
356                    }
357                    i++;
358                    hashStr += key + "=" + item;
359                });
360
361                return hashStr;
362            }
363        });
364
365    /**
366    * For each page selector on a page creates instance of 
367    * ["SearchPageSelectorModel"]{@link module:searchPageSelector.SearchPageSelectorModel} and 
368    * ["SearchPageSelectorView"]{@link module:searchPageSelector.SearchPageSelectorView} 
369    * @memberOf module:searchPageSelector
370    * @alias module:searchPageSelector.SearchPageSelectorView.init
371    */
372    api.init = function () {
373        if ($("body").hasClass("on-page-editor") || initialized) {
374            return;
375        }
376
377        queryModel = XA.component.search.query;
378
379        var searchPageSelector = $(".page-selector");
380        _.each(searchPageSelector, function (elem) {
381            new SearchPageSelectorView({ el: $(elem), model: new SearchPageSelectorModel });
382        });
383
384        initialized = true;
385    };
386
387    return api;
388
389}(jQuery, document));
390
391XA.register('searchPageSelector', XA.component.search.pageSelector);

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.