1/** 2 * Includes functionality for daterange component 3 * @module facetDateRange 4 * @param {jQuery} $ Instance of jQuery 5 * @param {Document} document dom document object 6 * @return {Object} list of methods for working with date range component 7*/ 8XA.component.search.facet.daterange = (function ($, document) { 9 /** 10 * This object stores all public api methods 11 * @type {Object.<Methods>} 12 * @memberOf module:facetDateRange 13 * */ 14 var api = {}, queryModel, urlHelperModel, initialized = false, toUrlDate, fromUrlDate; 15 /** 16 * format date 17 * @param {String} date date that should be formatted 18 * @private 19 * @memberof module:facetDateRange 20 * @alias module:facetDateRange.toUrlDate 21 * @returns {String} date in format 'yymmdd' 22 */ 23 toUrlDate = function (date) { 24 return date !== null && date !== "" ? $.datepicker.formatDate('yymmdd', date) : ""; 25 }; 26 /** 27 * format date from url 28 * @private 29 * @param {String} dateString date that should be formatted 30 * @memberof module:facetDateRange 31 * @alias module:facetDateRange.fromUrlDate 32 * @returns {Date} date 33 */ 34 fromUrlDate = function (dateString) { 35 var y = dateString.substr(0, 4), 36 m = dateString.substr(4, 2) - 1, 37 d = dateString.substr(6, 2), 38 D = new Date(y, m, d); 39 40 if (dateString === "") { 41 return; 42 } 43 44 if (D.getFullYear() == y && D.getMonth() == m && D.getDate() == d) 45 return D; 46 else 47 throw "Invalid date: " + dateString; 48 }; 49 /** 50 * @name module:facetDateRange.FacetDateRangeModel 51 * @constructor 52 * @augments Backbone.Model 53 */ 54 var FacetDateRangeModel = Backbone.Model.extend( 55 /** @lends module:facetDateRange.FacetDateRangeModel.prototype **/ 56 { 57 /** 58 * Default model options 59 * @default 60 */ 61 defaults: { 62 dataProperties: {}, 63 sig: [] 64 } 65 }); 66 /** 67 * @name module:facetDateRange.FacetDateRangeView 68 * @constructor 69 * @augments Backbone.View 70 */ 71 var FacetDateRangeView = XA.component.search.baseView.extend( 72 /** @lends module:facetDateRange.FacetDateRangeView.prototype **/ 73 { 74 /** 75 * Initially sets data to model and watches events on which 76 * view should be updated 77 * @listens module:facetDateRange.FacetDateRangeView~event:change 78 * @listens module:XA.component.search.vent~event:hashChanged 79 * @memberof module:facetDateRange.FacetDateRangeView 80 */ 81 initialize: function () { 82 this.properties = this.$el.data().properties; 83 if (this.model) { 84 this.model.set({ dataProperties: this.properties }); 85 this.model.set("sig", this.translateSignatures(this.properties.searchResultsSignature, this.properties.f)); 86 } 87 this.model.on("change", this.render, this); 88 89 XA.component.search.vent.on("hashChanged", this.updateComponent.bind(this)); 90 }, 91 /** 92 * list of events for Backbone View 93 * @memberof module:facetDateRange.FacetDateRangeView 94 * @alias module:facetDateRange.FacetDateRangeView#events 95 */ 96 events: { 97 'change .startDate': 'updateFacet', 98 'change .endDate': 'updateFacet', 99 'click .bottom-remove-filter, .clear-filter': 'clearFilter' 100 }, 101 /** 102 * Renders view. Use jquery ui datepicker 103 * @memberof module:facetDateRange.FacetDateRangeView 104 * @alias module:facetDateRange.FacetDateRangeView#render 105 */ 106 render: function () { 107 var fromDateDefaultOffset = parseInt(this.model.get('dataProperties').fromDateDefaultOffset), 108 toDateDefaultOffset = parseInt(this.model.get('dataProperties').toDateDefaultOffset), 109 fromDateFormat = this.model.get('dataProperties').fromDateDisplayFormat, 110 toDateFormat = this.model.get('dataProperties').toDateDisplayFormat, 111 fromDateMonthsShown = this.model.get('dataProperties').fromDateMonthsShown, 112 toDateMonthsShown = this.model.get('dataProperties').toDateMonthsShown, 113 fromDatePastDays = this.model.get('dataProperties').fromDatePastDays, 114 toDateFutureDays = this.model.get('dataProperties').toDateFutureDays, 115 fromDateVisible = this.model.get('dataProperties').fromDateVisible, 116 toDateVisible = this.model.get('dataProperties').toDateVisible, 117 $fromDate = this.$el.find('.startDate'), 118 $toDate = this.$el.find('.endDate'), 119 hashObj = queryModel.parseHashParameters(window.location.hash), 120 sig = this.model.get('sig'), 121 lang = $("html").attr("lang") ? $("html").attr("lang") : "", 122 dates, i; 123 124 if (toDateFormat) { 125 toDateFormat = toDateFormat.replace(/yy/g, "y"); 126 } 127 if (fromDateFormat) { 128 fromDateFormat = fromDateFormat.replace(/yy/g, "y"); 129 } 130 131 if (fromDateVisible) { 132 $fromDate.datepicker({ 133 dateFormat: fromDateFormat, 134 changeMonth: fromDateMonthsShown, 135 changeYear: fromDateMonthsShown, 136 minDate: fromDatePastDays ? (fromDateDefaultOffset != '' ? -1 * fromDateDefaultOffset : new Date(1900, 1, 1)) : new Date() 137 }); 138 } 139 140 if (toDateVisible) { 141 $toDate.datepicker({ 142 dateFormat: toDateFormat, 143 changeMonth: toDateMonthsShown, 144 changeYear: toDateMonthsShown, 145 maxDate: toDateFutureDays ? (toDateDefaultOffset != '' ? toDateDefaultOffset : new Date(2100, 1, 1)) : new Date() 146 }); 147 } 148 $xa.datepicker.setDefaults($xa.datepicker.regional[lang]); 149 for (i = 0; i < sig.length; i++) { 150 if (hashObj.hasOwnProperty(sig[i]) && hashObj[sig[i]] != '') { 151 dates = hashObj[sig[i]].split("|"); 152 $fromDate.datepicker("setDate", fromUrlDate(dates[0])); 153 $toDate.datepicker("setDate", fromUrlDate(dates[1])); 154 } 155 } 156 }, 157 /** 158 * Updates hash by calling ["updateHash"]{@link module:searchQuery.updateHash} 159 * @memberof module:facetDateRange.FacetDateRangeView 160 * @alias module:facetDateRange.FacetDateRangeView#updateFacet 161 */ 162 updateFacet: function (param) { 163 var $facetClose = this.$el.find('.facet-heading > span'), 164 $fromDate = this.$el.find('.startDate'), 165 $toDate = this.$el.find('.endDate'), 166 fromDate = $fromDate.length > 0 ? $fromDate.datepicker("getDate") : null, 167 toDate = $toDate.length > 0 ? $toDate.datepicker("getDate") : null, 168 sig = this.model.get('sig'); 169
170 queryModel.updateHash(this.updateSignaturesHash(sig, toUrlDate(fromDate) + "|" + toUrlDate(toDate), {})); 171 $facetClose.addClass('has-active-facet'); 172 }, 173 /** 174 * Clears selected filter in component 175 * @param {Object} param 176 * @memberof module:facetDateRange.FacetDateRangeView 177 * @alias module:facetDateRange.FacetDateRangeView#clearFilter 178 */ 179 clearFilter: function (param) { 180 var properties = this.model.get('dataProperties'), 181 $facetClose = this.$el.find('.facet-heading > span'), 182 hash = queryModel.parseHashParameters(window.location.hash), 183 sig = this.model.get('sig'), 184 shouldClear = false, 185 facetData, 186 i; 187 188 $facetClose.removeClass('has-active-facet'); 189 190 for (i = 0; i < sig.length; i++) { 191 facetData = sig[i]; 192 if (typeof hash[facetData] !== "undefined" && hash[facetData] !== "") { 193 delete properties[facetData]; 194 shouldClear = true; 195 } 196 } 197 198 if (!shouldClear) { 199 return; 200 } 201 202 queryModel.updateHash(this.updateSignaturesHash(sig, "", hash)); 203 204 this.model.set({ dataProperties: properties }); 205 206 this.$el.find('.startDate').val(""); 207 this.$el.find('.endDate').val(""); 208 }, 209 /** 210 * Updates component after changes in hash 211 * @param {Object} hash object that stores hash values 212 * @memberof module:facetDateRange.FacetDateRangeView 213 * @alias module:facetDateRange.FacetDateRangeView#updateComponent 214 */ 215 updateComponent: function (hash) { 216 var $fromDate = this.$el.find('.startDate'), 217 $toDate = this.$el.find('.endDate'), 218 sig = this.model.get('sig'), 219 facetPart, 220 dates, 221 i; 222 223 for (i = 0; i < sig.length; i++) { 224 facetPart = sig[i].toLowerCase(); 225 if (hash.hasOwnProperty(facetPart) && hash[facetPart] !== '') { 226 dates = hash[facetPart].split("|"); 227 if (dates[0] !== "") { 228 this.handleDate($fromDate, dates[0]); 229 } 230 if (dates[1] !== "") { 231 this.handleDate($toDate, dates[1]); 232 } 233 } else { 234 this.clearFilter(); 235 } 236 } 237 }, 238 /** 239 * Updates datepicker date 240 * @param {jQuery<DomElement>} control element where start date specified 241 * @param {String} value date that should be set 242 * @memberof module:facetDateRange.FacetDateRangeView 243 * @alias module:facetDateRange.FacetDateRangeView#handleDate 244 */ 245 handleDate: function (control, value) { 246 var $facetClose = this.$el.find('.facet-heading > span'); 247 if (control.length !== 0 && toUrlDate(control.datepicker('getDate')) !== value) { 248 control.datepicker("setDate", fromUrlDate(value)); 249 $facetClose.addClass('has-active-facet'); 250 } else if (value === "") { 251 control.datepicker('setDate', null); 252 } 253 } 254 }); 255 256 /** 257 * For each search date range on a page creates instance of 258 * ["FacetDateRangeModel"]{@link module:facetDateRange.FacetDateRangeModel} and 259 * ["FacetDateRangeView"]{@link module:facetDateRange.FacetDateRangeView} 260 * @memberOf module:facetDateRange 261 * @alias module:facetDateRange.init 262 */ 263 api.init = function () { 264 if ($("body").hasClass("on-page-editor") || initialized) { 265 return; 266 } 267
268 queryModel = XA.component.search.query; 269 urlHelperModel = XA.component.search.url; 270 271 var facetDateRangesList = $(".facet-date-range"); 272 _.each(facetDateRangesList, function (elem) { 273 var model = new FacetDateRangeModel(), 274 view = new FacetDateRangeView({ el: $(elem), model: model }); 275 view.render(); 276 }); 277 278 initialzied = true; 279 }; 280 281 return api; 282 283}(jQuery, document)); 284 285XA.register('facetDateRange', XA.component.search.facet.daterange);
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.