1 2/** 3 * Facet summary component functionality 4 * @module facetSummary 5 * @param {jQuery} $ Instance of jQuery 6 * @param {Document} document dom document object 7 * @return {Object} list of methods for working with component facet summary 8*/ 9XA.component.search.facet.summary = (function ($, document) { 10 /** 11 * This object stores all public api methods 12 * @type {Object.<Methods>} 13 * @memberOf module:facetSummary 14 */ 15 var api = {}, 16 urlHelperModel = XA.component.search.url, 17 queryModel = XA.component.search.query, 18 apiModel = XA.component.search.ajax, 19 facetName = "summary"; 20 21 /** 22 * @name module:facetSummary.FacetSummaryModel 23 * @constructor 24 * @augments Backbone.Model 25 */ 26 var FacetSummaryModel = Backbone.Model.extend( 27 /** @lends module:facetSummary.FacetSummaryModel.prototype **/ 28 29 { 30 /** 31 * Default model options 32 * @default 33 * @param {Object} properties properties of ajax call and callback 34 */ 35 defaults: { 36 dataProperties: {}, 37 sig: [], 38 hash: '' 39 }, 40 /** 41 * Listens to changes on facets and hash 42 * @listens module:XA.component.search.vent~event:facet-data-loaded 43 * @listens module:XA.component.search.vent~event:facet-data-filtered 44 * @listens module:XA.component.search.vent~event:facet-data-partial-filtered 45 * @listens module:XA.component.search.vent~event:hashChanged 46 */ 47 initialize: function () { 48 var that = this; 49 this.set('resultData', {}) 50 //Event to get data at the begining or in case that there are no hash parameters in the url - one request for all controls 51 XA.component.search.vent.on("facet-data-loaded", that.processData.bind(that)); 52 // //If the url hash contains this control facet name (someone clicked this control), then we have to listen for partial filtering 53 XA.component.search.vent.on("facet-data-partial-filtered", that.processData.bind(that)); 54 // //When we are not filtering by this control (not clicked) 55 XA.component.search.vent.on("facet-data-filtered", that.processData.bind(that)); 56 57 }, 58 /** 59 * Finds all facets that have same name as facetName in Control Data and return them 60 * @param {Object} facetData 61 * @param {*} controlData 62 * @returns {Array} Filtered facet data 63 * @memberof module:facetSummary.FacetSummaryModel 64 * @alias module:facetSummary.FacetSummaryModel.requestFacetData 65 */ 66 requestFacetData: function (facetData, controlData) { 67 return _.find(facetData, function (f) { 68 return f.Key.toLowerCase() === controlData.facetName.toLowerCase(); 69 }); 70 }, 71 /** 72 * Concatenates signature and facet name in order to build proper hash parameter name 73 * @param {*} rawSignature 74 * @param {*} f 75 */ 76 translateSignatures: function (rawSignature, f) { 77 var signatures, i; 78 79 f = f.toLowerCase(); 80 81 if (typeof rawSignature === "undefined" || rawSignature === null) { 82 return [f]; 83 } 84 85 signatures = rawSignature.split(','); 86 87 if (rawSignature === "") { 88 return [f]; 89 } else { 90 for (i = 0; i < signatures.length; i++) { 91 signatures[i] = signatures[i] + "_" + f; 92 } 93 return signatures; 94 } 95 }, 96 /** 97 * Processes data that comes as parameter. Update 98 * model and store all facets that are active and have 99 * same signature 100 * @param {Object} data Data from server with facet values
101 * @memberof module:facetSummary.FacetSummaryModel 102 * @alias module:facetSummary.FacetSummaryModel.processData 103 */ 104 processData: function (data) { 105 var hashObj = queryModel.parseHashParameters(window.location.hash), 106 requestFacedData, 107 that = this, 108 displayName, 109 facetData = [], requestData = {}, facetControl, control; 110 var facets = XA.component.search.facet; 111 112 for (facetControl in facets) { 113 control = XA.component.search.facet[facetControl]; 114 if (typeof (control.getFacetDataRequestInfo) === "function") { 115 facetData = control.getFacetDataRequestInfo(); 116 for (var facetIndex = 0; facetIndex < facetData.length; facetIndex++) { 117 var controlData = facetData[facetIndex]; 118 var signaturesArray = controlData.signature.split(','); 119 for (var signatureIndex = 0; signatureIndex < signaturesArray.length; signatureIndex++) { 120 var signature = signaturesArray[signatureIndex]; 121 if (data.Signature == signature && that.get('sig') == signature) { 122 requestFacedData = that.requestFacetData(data.Facets, controlData); 123 if (typeof requestFacedData !== "undefined") { 124 displayName = requestFacedData.Name; 125 var currResults = this.get('resultData'); 126 var facetHashNames = that.translateSignatures(signature, requestFacedData.Key.toLowerCase()) 127 for (var facetHashNameIndex = 0; facetHashNameIndex < facetHashNames.length; facetHashNameIndex++) { 128 var facetHashName = facetHashNames[facetHashNameIndex]; 129 if (hashObj[facetHashName]) { 130 currResults[displayName] = { 131 "value": hashObj[facetHashName], 132 "key": requestFacedData.Key, 133 "signature": data.Signature, 134 "facetHashName": facetHashName 135 } 136 } else { 137 delete currResults[displayName]; 138 } 139 } 140 this.set('resultData', currResults); 141 this.trigger('change', this) 142 143 } 144 } 145 } 146 147 } 148 } 149 } 150 } 151 }); 152 /** 153 * @name module:facetSummary.FacetSummaryView 154 * @constructor 155 * @augments Backbone.View 156 */ 157 var FacetSummaryView = XA.component.search.baseView.extend( 158 /** @lends module:facetSummary.FacetSummaryView.prototype **/ 159 160 { 161 tagName: "div", 162 className: "facet-search-summary", 163 template: 164 "<% if(Object.keys(resultData).length){ %> <div class='facet-summary-wrapper clearfix'>" + 165 "<% _.forEach(resultData, function(obj,key){ %>" + 166 "<div class='active-facet-summary-element' data-hash='" + "<%=obj.facetHashName%>" + "' data-key='" + "<%=obj.key%>" + "' data-signature='" + "<%=obj.signature%>" + "'>" + 167 "<span class='facet-summary-name'><%= key %>:</span> " + "<%= renderFacetValues(obj.value) %>" + 168 "</div>" + 169 "<% }); %>" + 170 "</div><% }%>", 171 172 renderFacetValues: function (value) { 173 var params = value.split("||") 174 175 return params.map(function (p) { 176 var template = '<div class=\'facet-summary-value\' data-value=' + encodeURIComponent(p) + '>' 177 + '<p>' + p + '</p>' 178 + '<span class=\'removeFacetValue\'>x</span>' 179 + '</div>' 180 181 return template; 182 }).join(' ') 183 }, 184 /** 185 * Initially sets data to model and watches events on which 186 * view should be updated 187 * @listens module:facetSummary.FacetSummaryView~event:change 188 * @memberof module:facetSummary.FacetSummaryView 189 * @alias module:facetSummary.FacetSummaryView#initialize 190 */ 191 clearButtons: function (event) { 192 var $target = $(event.currentTarget), 193 $facetSummary = $target.closest(".facet-summary"); 194 $facetSummary.find('.clear-all-active-facets').trigger('click'); 195 196 }, 197 /** 198 * Initializes the view by assigning events to the buttons and rendering component 199 * @memberof module:facetSummary.FacetSummaryView 200 * @alias module:facetSummary.FacetSummaryView#events 201 */ 202 initialize: function () { 203 var dataProperties = this.$el.data(), 204 that = this, 205 properties = dataProperties.properties, 206 signatures; 207 Backbone.$('.facet-summary .clear-filter').on('click', function (event) { 208 that.clearButtons(event) 209 210 }) 211 Backbone.$('.facet-summary .bottom-remove-filter').on('click', function (event) { 212 that.clearButtons(event) 213 214 }) 215 signatures = this.translateSignatures(properties.searchResultsSignature, facetName); 216 this.model.set("sig", properties.searchResultsSignature); 217 dataProperties = this.$el.data("properties"), 218 this.model.on("change", this.render, this); 219 this.render(); 220 }, 221 /** 222 * list of events for Backbone View 223 * @memberof module:facetSummary.FacetSummaryView 224 * @alias module:facetSummary.FacetSummaryView#events 225 */ 226 events: { 227 'click .removeFacetValue': 'removeFacetValue', 228 'click .clear-filter': 'clearAllActiveFacets', 229 'click .bottom-remove-filter button': 'clearAllActiveFacets' 230 }, 231 /** 232 * Prepares hash string based on hash object 233 * @param {Object} hashObj Object created from hash parameters 234 * @memberof module:facetSummary.FacetSummaryView 235 * @alias module:facetSummary.FacetSummaryView#createHash 236 * @returns {String}
236 hash as a string 237 */ 238 createHash: function (hashObj) { 239 var result = "#"; 240 for (option in hashObj) { 241 result += option + "=" + hashObj[option] + "&"; 242 } 243 return result; 244 }, 245 /** 246 * Updates current location 247 * @param {Object} hashObj 248 */ 249 updateLocation: function (hashObj) { 250 XA.component.search.query.updateHash(hashObj); 251 }, 252 /** 253 * Returns facet params 254 * @param {Jquery} el jquery event target element 255 */ 256 getFacetParams: function (el) { 257 var summaryEl = $(el).closest(".active-facet-summary-element"); 258 259 return { 260 key: summaryEl.data('key'), 261 signature: summaryEl.data('signature') 262 } 263 }, 264 /** 265 * Clears all active facets that are stored under summary component 266 * @memberof module:facetSummary.FacetSummaryView 267 * @alias module:facetSummary.FacetSummaryView#clearAllActiveFacets 268 */ 269 clearAllActiveFacets: function () { 270 var self = this; 271 var hashObj = queryModel.parseHashParameters(window.location.hash); 272 273 this.$el.find('.active-facet-summary-element').each(function () { 274 var facetParams = self.getFacetParams($(this)); 275 var facetHashNames = self.translateSignatures(facetParams.signature, facetParams.key) 276 277 _.each(facetHashNames, function (facetHashName) { 278 hashObj[facetHashName]=""; 279 }) 280 }) 281 282 self.updateLocation(hashObj); 283 }, 284 /** 285 * Removes selected facet value and updates hash 286 * @param {Event} event Event object where stored clicked element 287 */ 288 removeFacetValue: function (event) { 289 var facetValueElem = $(event.currentTarget).closest(".facet-summary-value") 290 291 var selectedFacetValue = decodeURIComponent(facetValueElem.data('value')) 292 var facetParams = this.getFacetParams(event.currentTarget) 293 294 var hashObj = queryModel.parseHashParameters(window.location.hash); 295 var facetHashNames = this.translateSignatures(facetParams.signature, facetParams.key) 296 297 var removeSelectedValue = function (facetHashName) { 298 hashObj[facetHashName] = hashObj[facetHashName] 299 .split("||") 300 .filter(function(val) { 301 return val !== selectedFacetValue 302 }) 303 .join("||"); 304 } 305 306 _.each(facetHashNames, removeSelectedValue) 307 308 this.updateLocation(hashObj); 309 }, 310 /** 311 * Renders view 312 * @memberof module:facetSummary.FacetSummaryView 313 * @alias module:facetSummary.FacetSummaryView#render 314 */ 315 render: function () { 316 var inst = this, 317 resultData = this.model.get("resultData"), 318 template, templateResult; 319 var dataProperties = this.$el.data(); 320 this.properties = dataProperties.properties; 321 this.manageVisibilityByData(this.$el, resultData) 322 if (this.model) { 323 this.model.set({ dataProperties: this.properties }); 324 this.model.set("sig", this.properties.searchResultsSignature); 325 } 326 //checks whether page is opened from disc - if yes then we are in Creative Exchange mode 327 if (window.location.href.startsWith("file://")) { 328 return; 329 } 330 331 if (resultData !== undefined) { 332 template = _.template(this.template, { 333 imports: { renderFacetValues: this.renderFacetValues } 334 }); 335 336 templateResult = template({ 337 "resultData": resultData 338 }); 339 } 340 341 inst.$el.find(".facet-summary-placeholder").html(templateResult); 342 } 343 344 }); 345 /** 346 * For each search dropdown component on a page creates instance of
347 * ["FacetSummaryModel"]{@link module:facetSummary.FacetSummaryModel} and 348 * ["FacetSummaryView"]{@link module:facetSummary.FacetSummaryView} 349 * @memberOf module:facetSummary 350 * @alias module:facetSummary.init 351 */ 352 api.init = function () { 353 if ($("body").hasClass("on-page-editor")) { 354 return; 355 } 356 357 queryModel = XA.component.search.query; 358 apiModel = XA.component.search.ajax; 359 urlHelperModel = XA.component.search.url; 360 361 var facetSummary = $(".facet-summary:not(.initialized)"); 362 363 _.each(facetSummary, function (elem) { 364 var $el = $(elem), 365 model = new FacetSummaryModel(), 366 view = new FacetSummaryView({ el: $el, model: model }); 367 368 $el.addClass("initialized"); 369 }); 370 }; 371 372 return api; 373 374}(jQuery, document)); 375 376XA.register('facetSummary', XA.component.search.facet.summary);
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.