1/** 2 * Managed Range Facet component functionality 3 * @module managedrange 4 * @param {jQuery} $ Instance of jQuery 5 * @param {Document} document dom document object 6 * @return {Object} list of methods for working with managed range component 7*/ 8XA.component.search.facet.managedrange = (function ($, document) { 9 /** 10 * This object stores all public api methods 11 * @type {Object.<Methods>} 12 * @memberOf module:managedrange 13 */ 14 var api = {}, 15 urlHelperModel, 16 queryModel, 17 apiModel, 18 initialized = false; 19 /** 20 * @name module:managedrange.FacetManagedRangeModel 21 * @constructor 22 * @augments Backbone.Model 23 */ 24 var FacetManagedRangeModel = Backbone.Model.extend( 25 /** @lends module:managedrange.FacetManagedRangeModel.prototype **/ 26 27 { 28 /** 29 * Default model options 30 * @default 31 */ 32 defaults: { 33 dataProperties: {}, 34 sig: [] 35 } 36 }); 37 /** 38 * @name module:managedrange.FacetManagedRangeView 39 * @constructor 40 * @augments Backbone.View 41 */ 42 var FacetManagedRangeView = XA.component.search.baseView.extend( 43 /** @lends module:managedrange.FacetManagedRangeView.prototype **/ 44 45 { 46 /** 47 * Initially sets data to model and watches events on which 48 * view should be updated 49 * @listens module:managedrange.FacetManagedRangeView~event:change 50 * @listens module:XA.component.search.vent~event:hashChanged 51 * @memberof module:managedrange.FacetManagedRangeView 52 */ 53 initialize: function () { 54 this.properties = this.$el.data().properties; 55 56 if (this.model) { 57 this.model.set({ dataProperties: this.properties }); 58 this.model.set("sig", this.translateSignatures(this.properties.searchResultsSignature, this.properties.f)); 59 } 60 61 if (this.$el.find(".filterButton").length === 0) { 62 //If there is no filter button, we still have to have the possibility to use manual ranges 63 this.$el.find('.manualRangeMin').on('blur', this.textBoxChange.bind(this, [])); 64 this.$el.find('.manualRangeMax').on('blur', this.textBoxChange.bind(this, [])); 65 } 66 this.model.on("change", this.render, this); 67 68 XA.component.search.vent.on("hashChanged", this.updateComponent.bind(this)); 69 }, 70 /** 71 * list of events for Backbone View 72 * @memberof module:managedrange.FacetManagedRangeView 73 * @alias module:managedrange.FacetManagedRangeView#events 74 */ 75 events: { 76 'click .faceLink': 'linkClick', 77 'click .facetRadio': 'radioClick', 78 'click .facetCheckbox': 'checkBoxClick', 79 'click .filterButton': 'filter', 80 'click .bottom-remove-filter, .clear-filter': 'clearFilter', 81 'keyup .manualRangeMin, .manualRangeMax': 'configureKeyCodes' 82 }, 83 /** 84 * On enter click calls 85 * ["filter"]{@link module:managedrange.FacetManagedRangeView.filter} method 86 * @param {Event} e Event object 87 * @memberof module:managedrange.FacetManagedRangeView 88 * @alias module:managedrange.FacetManagedRangeView#configureKeyCodes 89 */ 90 configureKeyCodes: function (e) { 91 if (e.keyCode == 13) { 92 this.filter(); 93 } 94 }, 95 /** 96 * Helper function that will take all ranges selected on a page and 97 * update hash parameters according to this value 98 * @param {Array<DomElement>} foundRangeControls List of range controls on a page 99 * @memberof module:managedrange.FacetManagedRangeView 100 * @alias module:managedrange.FacetManagedRangeView#updateHash 101 */ 102 updateHash: function (foundRangeControls) { 103 var sig = this.model.get('sig'), 104 ranges = []; 105 106 _.each(foundRangeControls, function (range) { 107 var $range = $(range); 108 ranges.push($range.data().minvalue + "|" + $range.data().maxvalue); 109 }); 110 111 this.$el.find('.manualRangeMin').val(''); 112 this.$el.find('.manualRangeMax').val(''); 113
114 queryModel.updateHash(this.updateSignaturesHash(sig, ranges.join(','), {})); 115 }, 116 /** 117 * Render view 118 * @memberof module:managedrange.FacetManagedRangeView 119 * @alias module:managedrange.FacetManagedRangeView#render 120 */ 121 render: function () { 122 var hashObj = queryModel.parseHashParameters(window.location.hash), 123 facetClose = this.$el.find(".facet-heading > span"), 124 sig = this.model.get('sig'), 125 inst = this, 126 ranges, 127 i; 128 129 for (i = 0; i < sig.length; i++) { 130 if (hashObj.hasOwnProperty(sig[i]) && hashObj[sig[i]] !== '') { 131 ranges = hashObj[sig[i]].split(","); 132 133 facetClose.addClass('has-active-facet'); 134 _.each(ranges, function (range) { 135 var r = range.split('|'), 136 minValue = r[0], 137 maxValue = r[1], 138 selector, 139 $component; 140 141 if (minValue === "" && maxValue === "") { 142 return; 143 } else if (minValue !== "" && maxValue !== "") { 144 selector = ".facetCheckbox[data-minvalue='" + minValue + "'][data-maxvalue='" + maxValue + "'], .facetRadio[data-minvalue='" + minValue + "'][data-maxvalue='" + maxValue + "']"; 145 } else if (minValue !== "" && maxValue === "") { 146 selector = ".facetCheckbox[data-minvalue='" + minValue + "'], .facetRadio[data-minvalue='" + minValue + "']"; 147 } else if (minValue === "" && maxValue !== "") { 148 selector = ".facetCheckbox[data-maxvalue='" + maxValue + "'], .facetRadio[data-maxvalue='" + maxValue + "']"; 149 } 150 151 $component = $(selector); 152 153 if ($component.length > 0) { 154 $component.attr("checked", "checked"); 155 } else { 156 inst.$el.find('.manualRangeMin').val(r[0]); 157 inst.$el.find('.manualRangeMax').val(r[1]); 158 } 159 }); 160 } 161 } 162 }, 163 /** 164 * Updates Hash base on selected element by calling 165 * ["updateHash"]{@link module:managedrange.FacetManagedRangeView.updateHash} 166 * @param {Event} param Event that contains 167 * currentTarget element 168 * @memberof module:managedrange.FacetManagedRangeView 169 * @alias module:managedrange.FacetManagedRangeView#radioClick 170 */ 171 radioClick: function (param) { 172 //fix for radio buttons groups in the ASP.NET repeater control 173 var radio = $(param.currentTarget); 174 $('.facetRadio').attr("name", radio.attr("name")); 175 this.updateHash(radio); 176 }, 177 /** 178 * Clears values for manualRangeMin and manualRangeMax elements 179 * @param {Event} param Event that contains 180 * currentTarget element 181 * @memberof module:managedrange.FacetManagedRangeView 182 * @alias module:managedrange.FacetManagedRangeView#checkBoxClick 183 */ 184 checkBoxClick: function (param) { 185 var checkbox = $(param.currentTarget); 186 if (checkbox.is(":checked")) { 187 this.$el.find('.manualRangeMin').val(""); 188 this.$el.find('.manualRangeMax').val(""); 189 } 190 }, 191 /** 192 * Manages checked status for facetCheckbox 193 * Clears values for manualRangeMin and manualRangeMax elements 194 * and updates hash value 195 * @param {Event} param Event that contains 196 * currentTarget element 197 * @memberof module:managedrange.FacetManagedRangeView 198 * @alias module:managedrange.FacetManagedRangeView#linkClick 199 */ 200 linkClick: function (param) { 201 var $link = $(param.currentTarget), 202 hashValue = $link.data().minvalue + "|" + $link.data().maxvalue; 203 204 this.$el.find(".facetCheckbox[data-shortid!=" + $link.data().shortid + "]").removeAttr("checked"); 205 this.$el.find(".facetCheckbox[data-shortid=" + $link.data().shortid + "]").attr("checked", "checked"); 206 this.$el.find('.manualRangeMin').val(""); 207 this.$el.find('.manualRangeMax').val(""); 208
209 queryModel.updateHash(this.updateSignaturesHash(sig, hashValue, {})); 210 }, 211 /** 212 * If minRange or maxRange value set 213 * ["queryModel updateHash"]{@link module:searchQuery.updateHash} method 214 * If checked CheckBox or RadioButton called 215 * ["managedrange updateHash"]{@link module:managedrange.FacetManagedRangeView.updateHash} 216 * If multiply selection disabled call 217 * ["radioClick"]{@link module:managedrange.FacetManagedRangeView.radioClick} 218 * @memberof module:managedrange.FacetManagedRangeView 219 * @alias module:managedrange.FacetManagedRangeView.filter 220 */ 221 filter: function () { 222 var multipleSelection = this.model.get('dataProperties').multipleSelection, 223 checkedCheckBoxes = this.$el.find('.facetCheckbox:checked'), 224 checkedRadioButton = this.$el.find('.facetRadio:checked'), 225 minRange = this.$el.find('.manualRangeMin'), 226 maxRange = this.$el.find('.manualRangeMax'), 227 sig = this.model.get('sig'), 228 maxRange, minRange, minValue, maxValue; 229 230 //Gets values from text boxes 231 minValue = minRange.length > 0 && minRange.val() !== "" ? minRange.val() : ""; 232 maxValue = maxRange.length > 0 && maxRange.val() !== "" ? maxRange.val() : ""; 233 234 if (minValue !== "" || maxValue !== "") { 235 //Clears all selected radio buttons and checkboxes 236 this.$el.find(".facetRadio").removeAttr("checked"); 237 this.$el.find(".facetCheckbox").removeAttr("checked"); 238 239 //Auto update hash after text box change when there is no filter button 240 queryModel.updateHash(this.updateSignaturesHash(sig, minValue + "|" + maxValue, {})); 241 } else if (checkedCheckBoxes.length > 0 || checkedRadioButton.length > 0) { 242 if (multipleSelection) { 243 this.updateHash(checkedCheckBoxes); 244 } else { 245 this.radioClick({ currentTarget: checkedRadioButton }); 246 } 247 } 248 }, 249 /** 250 * Clears selected filter and updates hash 251 * @memberof module:managedrange.FacetManagedRangeView 252 * @alias module:managedrange.FacetManagedRangeView#clearFilter 253 * 254 */ 255 clearFilter: function () { 256 var minRange = this.$el.find('.manualRangeMin'), 257 maxRange = this.$el.find('.manualRangeMax'), 258 properties = this.model.get('dataProperties'), 259 facetClose = this.$el.find('.facet-heading > span'), 260 hash = queryModel.parseHashParameters(window.location.hash), 261 sig = this.model.get('sig'), 262 shouldClear = false, 263 facetData, 264 i; 265 266 for (i = 0; i < sig.length; i++) { 267 facetData = sig[i]; 268 if (typeof hash[facetData] !== "undefined" && hash[facetData] !== "") { 269 delete properties[facetData]; 270 hash[facetData] = ""; 271 shouldClear = true; 272 } 273 } 274 275 if (!shouldClear) { 276 return; 277 } 278 279 queryModel.updateHash(hash); 280 281 this.model.set({ dataProperties: properties }); 282 283 this.$el.find('.facetCheckbox').removeAttr("checked"); 284 this.$el.find('.facetRadio').removeAttr("checked"); 285 286 facetClose.removeClass('has-active-facet'); 287 288 if (minRange.length > 0) { 289 minRange.val(minRange.data().defaultvalue); 290 } 291 if (maxRange.length > 0) { 292 maxRange.val(maxRange.data().defaultvalue); 293 } 294 }, 295 /** 296 * Updates hash on checkbox or radio button changes 297 * @memberof module:managedrange.FacetManagedRangeView 298 * @alias module:managedrange.FacetManagedRangeView#clearFilter 299 * 300 */ 301 textBoxChange: function () { 302 var minRange = this.$el.find('.manualRangeMin'), 303 maxRange = this.$el.find('.manualRangeMax'), 304 minValue = minRange.length > 0 && minRange.val() !== "" ? minRange.val() : "", 305 maxValue = maxRange.length > 0 && maxRange.val() !== "" ? maxRange.val() : "", 306 sig = this.model.get('sig'); 307 308 //Clears all selected radio buttons and checkboxes 309 this.$el.find(".facetRadio").removeAttr("checked"); 310 this.$el.find(".facetCheckbox").removeAttr("checked"); 311 312 if (minValue !== "" || maxValue !== "") { 313 //Auto updates hash after text box change when there is no filter button
314 queryModel.updateHash(this.updateSignaturesHash(sig, minValue + "|" + maxValue, {})); 315 } else { 316 //Clears all radio buttons and checkbox hash parameters 317 queryModel.updateHash(this.updateSignaturesHash(sig, "", {})); 318 } 319 }, 320 /** 321 * Updates component 322 * @memberof module:managedrange.FacetManagedRangeView 323 * @alias module:managedrange.FacetManagedRangeView#clearFilter 324 * 325 */ 326 updateComponent: function (hash) { 327 var sig = this.model.get('sig'), 328 facetPart, 329 i; 330 for (i = 0; i < sig.length; i++) { 331 facetPart = sig[i].toLowerCase(); 332 if (hash.hasOwnProperty(facetPart)) { 333 this.render(); 334 } else { 335 this.clearFilter(); 336 } 337 } 338 } 339 }); 340 /** 341 * For each search managed range component on a page creates instance of 342 * ["FacetManagedRangeModel"]{@link module:managedrange.FacetManagedRangeModel} and 343 * ["FacetManagedRangeView"]{@link module:managedrange.FacetManagedRangeView} 344 * @memberOf module:managedrange 345 * @alias module:managedrange.init 346 */ 347 api.init = function () { 348 if ($("body").hasClass("on-page-editor") || initialized) { 349 return; 350 } 351 352 queryModel = XA.component.search.query; 353 apiModel = XA.component.search.ajax; 354 urlHelperModel = XA.component.search.url; 355 356 var facetManagedRangesList = $(".facet-managed-range"); 357 _.each(facetManagedRangesList, function (elem) { 358 var model = new FacetManagedRangeModel(), 359 view = new FacetManagedRangeView({ el: $(elem), model: model }); 360 view.render(); 361 }); 362 363 initialzied = true; 364 }; 365 366 return api; 367 368}(jQuery, document)); 369 370XA.register('managedrange', XA.component.search.facet.managedrange);
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.