1(function ($, window) { 2 3 $.dnnSearchBox = function (options, element) { 4 this.$el = $(element); 5 this._init(options); 6 }; 7 8 $.dnnSearchBox.defaults = { 9 defaultText: "Enter Search term", 10 advancedText: 'Advanced', 11 seemoreText: 'See more results', 12 noresultText: 'No any results', 13 showAdvanced: false, 14 advancedId: null, 15 enablePreview: true, 16 refreshSearchResult: false, 17 refreshSearchResultDelay: 400, 18 refreshSearchResultMinChars: 2, 19 previewUrl: null, 20 previewMinChars: 2, 21 previewDelay: 400, 22 previewQueryParamName: 'keywords', 23 previewOnError: null, 24 searchQueryParamName: 'search', 25 searchFiltersParamName: 'filter', 26 searchFunction: null 27 }; 28 29 $.dnnSearchBox.prototype = { 30 _init: function (options) { 31 this.options = $.extend(true, {}, $.dnnSearchBox.defaults, options); 32 this._generateTemplate(); 33 this._attachEvents(); 34 }, 35 36 _generateTemplate: function () { 37 var originalVal = this.$el.val(); 38 var markup = '<div class="dnnSearchBox">'; 39 var advancedEnabled = this.options.showAdvanced && this.options.advancedId && $('#' + this.options.advancedId).length; 40 if (advancedEnabled) { 41 markup += '<span class="dnnSearchBox_advanced_query" /><a class="dnnSearchBoxClearAdvanced"></a>'; 42 } 43 markup += '<input id="' + this.options.id + '_input" type="text" autocomplete="off" aria-label="Search" />' + 44 '<a class="dnnSearchBoxClearText"></a>'; 45 46 markup += '<a class="dnnSearchButton"></a>'; 47 48 if (advancedEnabled) { 49 markup += '<div class="dnnSearchBox_advanced">' + 50 '<a class="dnnSearchBox_advanced_label">' + this.options.advancedText + '</a>' + 51 '<div class="dnnSearchBox_advanced_dropdown">'; 52 markup += '</div></div>'; 53 } 54 55 markup += '<div class="dnnClear"></div>' + 56 '</div>'; 57 58 this.$el.hide(); 59 this.$wrap = $(markup).insertAfter(this.$el); 60 var wrapWidth = this.$wrap.width(); 61 this.realInput = $('#' + this.options.id + '_input'); 62 63 this.realInput.val(originalVal); 64 65 var realInputRight = 50; 66 var advancedDropdown = $('.dnnSearchBox_advanced_dropdown', this.$wrap); 67 var advancedForm = $('#' + this.options.advancedId); 68 if (advancedEnabled) { 69 advancedForm.appendTo(advancedDropdown); 70 var w = $('.dnnSearchBox_advanced', this.$wrap).width(); 71 var w2 = $('.dnnSearchBox_advanced_query', this.$wrap).width(); 72 realInputRight = w + w2 + 50; 73 $('.dnnSearchBox_advanced_query', this.$wrap).hide(); 74 } 75 this.realInput.css({ right: realInputRight, width: wrapWidth - realInputRight - 8 }); 76 if (originalVal) { 77 this.realInput.next().addClass('dnnShow').css({ right: realInputRight - 15}); 78 } 79 }, 80 81 _makeUrl: function (param, service) { 82 var url = this.options.previewUrl ? this.options.previewUrl : 83 service ? service.getServiceRoot('internalservices') + 'searchService/preview' : null; 84 if (!url) return null; 85 86 var params = {}; 87 params[this.options.previewQueryParamName] = param.replace(/^\s+|\s+$/g, ''); 88 var urlAppend = []; 89 $.each(params, function (index, value) { 90 urlAppend.push([index, encodeURIComponent(value)].join('=')); 91 }); 92 93 if (urlAppend.length) { 94 url += url.indexOf('?') === -1 ? '?' : '&'; 95 url += urlAppend.join('&'); 96 } 97 return url; 98 }, 99 100 _generatePreviewTemplate: function (keyword, data) { 101 var preview = $('.dnnSearchBox_preview', this.$wrap); 102 if (preview.length) 103 preview.remove(); 104 105 var markup = '<ul class="dnnSearchBox_preview">'; 106 if (data && data.length) { 107 108 for (var i = 0; i < data.length; i++) { 109 var group = data[i]; 110 if (group.Results && group.Results.length) { 111 var groupTitle = group.ContentItemTypeName; 112 markup += '<li class="dnnSearchBox_preview_group">' + groupTitle + '</li>'; 113 for (var j = 0; j < group.Results.length; j++) { 114 var item = group.Results[j]; 115 var itemTitle = item.Title; 116 var itemUrl = item.DocumentUrl; 117 var itemSnippet = item.Snippet; 118 markup += '<li data-url="' + itemUrl
118+ '"><span>' + itemTitle + '</span>'; 119 if (itemSnippet) 120 markup += '<p>' + itemSnippet + '</p></li>'; 121 else 122 markup += '</li>'; 123 124 } // end for group items 125 } 126 } // end for group 127 markup += '<li><a href="javascript:void(0)" class="dnnSearchBox_preview_more">' + this.options.seemoreText + '</a></li>'; 128 markup += '</ul>'; 129 } 130 else { 131 markup += '<li>' + this.options.noresultText + '</li><ul>'; 132 } 133 134 this.$wrap.append(markup); 135 preview = $('.dnnSearchBox_preview', this.$wrap); 136 137 //attach click event 138 $('li', preview).on('click', function () { 139 var navigateUrl = $(this).attr('data-url'); 140 if (navigateUrl) { 141 window.location.href = navigateUrl; 142 } 143 return false; 144 }); 145 146 //attach see more 147 var searchBtn = $('.dnnSearchButton', this.$wrap); 148 $('.dnnSearchBox_preview_more', this.$wrap).on('click', function () { 149 searchBtn.triggerHandler('click'); 150 return false; 151 }); 152 }, 153 154 _search: function (val) { 155 if (this.options.searchFunction && typeof this.options.searchFunction == 'function') { 156 var params = {}; 157 params[this.options.searchQueryParamName] = encodeURIComponent(val); 158 var urlAppend = []; 159 $.each(params, function (index, value) { 160 urlAppend.push([index, encodeURIComponent(value)].join('=')); 161 }); 162 urlAppend.push([this.options.searchFiltersParamName, ''].join('=')); 163 164 this.options.searchFunction(val, urlAppend); 165 } 166 }, 167 168 _ignoreKeyCodes: [9, 13, 16, 17, 18, 19, 20, 27, 33, 34, 35, 36, 37, 38, 39, 40, 45], 169 170 _attachEvents: function () { 171 var self = this; 172 var realInput = this.realInput; 173 var clearTextBtn = $('a.dnnSearchBoxClearText', this.$wrap); 174 var advanced = $('.dnnSearchBox_advanced', this.$wrap); 175 176 // placeholder stuff 177 var placeholderSupported = ('placeholder' in document.createElement('input')); 178 if (placeholderSupported) 179 realInput.attr('placeholder', this.options.defaultText); 180 else { 181 realInput.on('focus', function () { 182 if (realInput.hasClass('dnnPlaceholder')) 183 realInput.val('').removeClass('dnnPlaceholder'); 184 }) 185 .on('blur', function () { 186 var val = realInput.val(); 187 if (!val) 188 realInput.val(self.options.defaultText).addClass('dnnPlaceholder'); 189 else 190 realInput.removeClass('dnnPlaceholder'); 191 }) 192 .blur(); 193 } 194 195 // clear textbox button 196 realInput.on('keyup', function (e) { 197 var k = e.keyCode || e.witch; 198 if ($.inArray(k, self._ignoreKeyCodes) > -1) return; 199 200 var val = realInput.val(); 201 var right = parseInt(realInput.css('right').replace('px', '')) - 15; 202 if (!val) { 203 clearTextBtn.removeClass('dnnShow'); 204 // hide preview 205 $('.dnnSearchBox_preview', this.$wrap).remove(); 206 } 207 else { 208 clearTextBtn.css({ 209 right: right 210 }).addClass('dnnShow'); 211 if (self.options.enablePreview && 212 val.length >= self.options.previewMinChars) { 213 // enable preview 214 if (self.throttle) { 215 clearTimeout(self.throttle); 216 delete self.throttle; 217 } 218 self.throttle = setTimeout(function () { 219 220 var service = self.options.moduleId ? ($.dnnSF ? $.dnnSF(self.options.moduleId) : null) : null; 221 var url = self._makeUrl(val, service); 222 if (url) { 223 $.ajax({
224 url: url, 225 beforeSend: service ? service.setModuleHeaders : null, 226 success: function (result) { 227 if (result) 228 self._generatePreviewTemplate(val, result); 229 }, 230 error: function (jqXhr, textStatus, errorThrown) { 231 if ($.isFunction(self.options.previewOnError)) { 232 self.options.previewOnError(jqXhr, textStatus, errorThrown); 233 } 234 }, 235 type: 'GET', 236 dataType: 'json', 237 contentType: "application/json" 238 }); 239 } 240 }, self.options.previewDelay); 241 } 242 else if (self.options.refreshSearchResult && 243 self.options.searchFunction && 244 typeof self.options.searchFunction == 'function' && 245 val.length >= self.options.refreshSearchResultMinChars) { 246 247 // enable auto search refresh 248 if (self.throttle) { 249 clearTimeout(self.throttle); 250 delete self.throttle; 251 } 252 253 self.throttle = setTimeout(function () { 254 self.options.searchFunction(val); 255 }, self.options.refreshSearchResultDelay); 256 } 257 } 258 }) 259 260 .on('paste', function () { 261 realInput.triggerHandler('keyup'); 262 }) 263 264 .on('keypress', function (e) { 265 var k = e.keyCode || e.witch; 266 if (k == 13) { 267 $('.dnnSearchButton', this.$wrap).trigger('click'); 268 e.preventDefault(); 269 } 270 }); 271 272 clearTextBtn.on('click', function () { 273 realInput.val('').focus(); 274 clearTextBtn.removeClass('dnnShow'); 275 $('.dnnSearchBox_preview', this.$wrap).remove(); 276 return false; 277 }); 278 279 if (this.options.showAdvanced) { 280 var advancedLabel = $('.dnnSearchBox_advanced_label', advanced); 281 var advancedContent = $('.dnnSearchBox_advanced_dropdown', advanced); 282 283 advancedLabel.on('click', function () { 284 advancedLabel.toggleClass('dnnExpanded'); 285 advancedContent.toggle(); 286 return false; 287 }).mouseup(function () { 288 return false; 289 }); 290 291 $('body').mouseup(function () { 292 if (advancedContent.is(':visible')) { 293 advancedContent.hide(); 294 advancedLabel.removeClass('dnnExpanded'); 295 } 296 }); 297 298 advancedContent.mouseup(function () { 299 return false; 300 }); 301 realInput.mouseup(function() { 302 return false; 303 }); 304 } 305 306 // search button hit 307 $('.dnnSearchButton', this.$wrap).on('click', function () { 308 // already auto refresh search result, no need to go to search result page 309 if (self.options.refreshSearchResult) { 310 if (self.options.beforeRefreshSearchResult && typeof self.options.beforeRefreshSearchResult == 'function') 311 self.options.beforeRefreshSearchResult(); 312 313 self.realInput.triggerHandler('keyup'); 314 return false; 315 } 316 317 var val = realInput.val(); 318 if (val) { 319 self._search(val); 320 } 321 return false; 322 }); 323 } 324 }; 325 326 $.fn.dnnSearchBox = function (options) { 327 var instance = $.data(this, 'dnnSearchBox'); 328 329 if (instance) { 330 instance._init(); 331 } 332 else { 333 instance = $.data(this, 'dnnSearchBox', new $.dnnSearchBox(options, this)); 334 } 335 }; 336 337})(jQuery, window);
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.