1function JCTitleSearch(arParams) { 2 var _this = this; 3 4 this.arParams = { 5 'AJAX_PAGE': arParams.AJAX_PAGE, 6 'CONTAINER_ID': arParams.CONTAINER_ID, 7 'INPUT_ID': arParams.INPUT_ID, 8 'MIN_QUERY_LEN': parseInt(arParams.MIN_QUERY_LEN) 9 }; 10 if (arParams.WAIT_IMAGE) 11 this.arParams.WAIT_IMAGE = arParams.WAIT_IMAGE; 12 if (arParams.MIN_QUERY_LEN <= 0) 13 arParams.MIN_QUERY_LEN = 1; 14 15 this.cache = []; 16 this.cache_key = null; 17 18 this.startText = ''; 19 this.running = false; 20 this.runningCall = false; 21 this.currentRow = -1; 22 this.RESULT = null; 23 this.CONTAINER = null; 24 this.INPUT = null; 25 this.WAIT = null; 26 27 this.ShowResult = function (result) { 28 if (BX.type.isString(result)) { 29 _this.RESULT.innerHTML = result; 30 } 31 32 _this.RESULT.style.display = _this.RESULT.innerHTML !== '' ? 'block' : 'none'; 33 var pos = _this.adjustResultNode(); 34 35 //adjust left column to be an outline 36 var res_pos; 37 var th; 38 var tbl = BX.findChild(_this.RESULT, { 'tag': 'table', 'class': 'title-search-result' }, true); 39 if (tbl) { 40 th = BX.findChild(tbl, { 'tag': 'th' }, true); 41 } 42 43 if (th) { 44 var tbl_pos = BX.pos(tbl); 45 tbl_pos.width = tbl_pos.right - tbl_pos.left; 46 47 var th_pos = BX.pos(th); 48 th_pos.width = th_pos.right - th_pos.left; 49 th.style.width = th_pos.width + 'px'; 50 51 _this.RESULT.style.width = (pos.width + th_pos.width) + 'px'; 52 53 //Move table to left by width of the first column 54 _this.RESULT.style.left = (pos.left - th_pos.width - 1) + 'px'; 55 56 //Shrink table when it's too wide 57 if ((tbl_pos.width - th_pos.width) > pos.width) 58 _this.RESULT.style.width = (pos.width + th_pos.width - 1) + 'px'; 59 60 //Check if table is too wide and shrink result div to it's width 61 tbl_pos = BX.pos(tbl); 62 res_pos = BX.pos(_this.RESULT); 63 if (res_pos.right > tbl_pos.right) { 64 _this.RESULT.style.width = (tbl_pos.right - tbl_pos.left) + 'px'; 65 } 66 } 67 68 var fade; 69 if (tbl) fade = BX.findChild(_this.RESULT, { 'class': 'title-search-fader' }, true); 70 if (fade && th) { 71 res_pos = BX.pos(_this.RESULT); 72 fade.style.left = (res_pos.right - res_pos.left - 18) + 'px'; 73 fade.style.width = 18 + 'px'; 74 fade.style.top = 0 + 'px'; 75 fade.style.height = (res_pos.bottom - res_pos.top) + 'px'; 76 fade.style.display = 'block'; 77 } 78 }; 79 80 this.onKeyPress = function (keyCode) { 81 var tbl = BX.findChild(_this.RESULT, { 'tag': 'table', 'class': 'title-search-result' }, true); 82 if (!tbl) 83 return false; 84 85 var i; 86 var cnt = tbl.rows.length; 87 88 switch (keyCode) { 89 case 27: // escape key - close search div 90 _this.RESULT.style.display = 'none'; 91 _this.currentRow = -1; 92 _this.UnSelectAll(); 93 return true; 94 95 case 40: // down key - navigate down on search results 96 if (_this.RESULT.style.display == 'none') 97 _this.RESULT.style.display = 'block'; 98 99 var first = -1; 100 for (i = 0; i < cnt; i++) { 101 if (!BX.findChild(tbl.rows[i], { 'class': 'title-search-separator' }, true)) { 102 if (first == -1) 103 first = i; 104 105 if (_this.currentRow < i) { 106 _this.currentRow = i; 107 break; 108 } 109 else if (tbl.rows[i].className == 'title-search-selected') { 110 tbl.rows[i].className = ''; 111 } 112 } 113 } 114 115 if (i == cnt && _this.currentRow != i) 116 _this.currentRow = first; 117 118 tbl.rows[_this.currentRow].className = 'title-search-selected'; 119 return true; 120 121 case 38: // up key - navigate up on search results 122 if (_this.RESULT.style.display == 'none') 123 _this.RESULT.style.display = 'block'; 124 125 var last = -1; 126 for (i = cnt - 1; i >= 0; i--) { 127 if (!BX.findChild(tbl.rows[i], { 'class': 'title-search-separator' }, true)) { 128 if (last == -1) 129 last = i; 130 131 if (_this.currentRow > i) { 132 _this.currentRow = i; 133 break; 134 } 135 else if (tbl.rows[i].className == 'title-search-selected') { 136 tbl.rows[i].className = ''; 137 } 138 } 139 } 140 141 if (i < 0 && _this.currentRow != i) 142 _this.currentRow = last; 143 144 tbl.rows[_this.currentRow].className = 'title-search-selected'; 145 return true; 146 147 case 13: // enter key - choose current search result 148 if (_this.RESULT.style.display == 'block') { 149 for (i = 0; i < cnt; i++) { 150 if (_this.currentRow == i) { 151 if (!BX.findChild(tbl.rows[i], { 'class': 'title-search-separator' }, true)) { 152 var a = BX.findChild(tbl.rows[i], { 'tag': 'a' }, true); 153 if (a) { 154 window.location = a.href; 155 return true; 156 } 157 } 158 } 159 } 160 } 161 return false;
162 } 163 164 return false; 165 }; 166 167 this.onTimeout = function () { 168 _this.onChange(function () { 169 setTimeout(_this.onTimeout, 500); 170 }); 171 }; 172 173 this.onChange = function (callback) { 174 if (_this.running) { 175 _this.runningCall = true; 176 return; 177 } 178 _this.running = true; 179 180 if (_this.INPUT.value != _this.oldValue && _this.INPUT.value != _this.startText) { 181 _this.oldValue = _this.INPUT.value; 182 if (_this.INPUT.value.length >= _this.arParams.MIN_QUERY_LEN) { 183 _this.cache_key = _this.arParams.INPUT_ID + '|' + _this.INPUT.value; 184 if (_this.cache[_this.cache_key] == null) { 185 if (_this.WAIT) { 186 var pos = BX.pos(_this.INPUT); 187 var height = (pos.bottom - pos.top) - 2; 188 _this.WAIT.style.top = (pos.top + 1) + 'px'; 189 _this.WAIT.style.height = height + 'px'; 190 _this.WAIT.style.width = height + 'px'; 191 _this.WAIT.style.left = (pos.right - height + 2) + 'px'; 192 _this.WAIT.style.display = 'block'; 193 } 194 195 BX.ajax.post( 196 _this.arParams.AJAX_PAGE, 197 { 198 'ajax_call': 'y', 199 'INPUT_ID': _this.arParams.INPUT_ID, 200 'q': _this.INPUT.value, 201 'l': _this.arParams.MIN_QUERY_LEN 202 }, 203 function (result) { 204 _this.cache[_this.cache_key] = result; 205 _this.ShowResult(result); 206 _this.currentRow = -1; 207 _this.EnableMouseEvents(); 208 if (_this.WAIT) 209 _this.WAIT.style.display = 'none'; 210 if (!!callback) 211 callback(); 212 _this.running = false; 213 if (_this.runningCall) { 214 _this.runningCall = false; 215 _this.onChange(); 216 } 217 } 218 ); 219 return; 220 } 221 else { 222 _this.ShowResult(_this.cache[_this.cache_key]); 223 _this.currentRow = -1; 224 _this.EnableMouseEvents(); 225 } 226 } 227 else { 228 _this.RESULT.style.display = 'none'; 229 _this.currentRow = -1; 230 _this.UnSelectAll(); 231 } 232 } 233 if (!!callback) 234 callback(); 235 _this.running = false; 236 }; 237 238 this.onScroll = function () { 239 if (BX.type.isElementNode(_this.RESULT) 240 && _this.RESULT.style.display !== "none" 241 && _this.RESULT.innerHTML !== '' 242 ) { 243 _this.adjustResultNode(); 244 } 245 }; 246 247 this.UnSelectAll = function () { 248 var tbl = BX.findChild(_this.RESULT, { 'tag': 'table', 'class': 'title-search-result' }, true); 249 if (tbl) { 250 var cnt = tbl.rows.length; 251 for (var i = 0; i < cnt; i++) 252 tbl.rows[i].className = ''; 253 } 254 }; 255 256 this.EnableMouseEvents = function () { 257 var tbl = BX.findChild(_this.RESULT, { 'tag': 'table', 'class': 'title-search-result' }, true); 258 if (tbl) { 259 var cnt = tbl.rows.length; 260 for (var i = 0; i < cnt; i++) 261 if (!BX.findChild(tbl.rows[i], { 'class': 'title-search-separator' }, true)) { 262 tbl.rows[i].id = 'row_' + i; 263 tbl.rows[i].onmouseover = function (e) { 264 if (_this.currentRow != this.id.substr(4)) { 265 _this.UnSelectAll(); 266 this.className = 'title-search-selected'; 267 _this.currentRow = this.id.substr(4); 268 } 269 }; 270 tbl.rows[i].onmouseout = function (e) { 271 this.className = ''; 272 _this.currentRow = -1; 273 }; 274 } 275 } 276 }; 277 278 this.onFocusLost = function (hide) { 279 setTimeout(function () { _this.RESULT.style.display = 'none'; }, 250); 280 }; 281 282 this.onFocusGain = function () { 283 if (_this.RESULT.innerHTML.length) 284 _this.ShowResult(); 285 }; 286 287 this.onKeyDown = function (e) { 288 if (!e) 289 e = window.event; 290 291 if (_this.RESULT.style.display == 'block') { 292 if (_this.onKeyPress(e.keyCode)) 293 return BX.PreventDefault(e); 294 } 295 }; 296 297 this.adjustResultNode = function () { 298 if (!(BX.type.isElementNode(_this.RESULT) 299 && BX.type.isElementNode(_this.CONTAINER)) 300 ) { 301 return { top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 }; 302 } 303 304 var pos = BX.pos(_this.CONTAINER); 305 if (window.innerWidth < 1920) { 306 _this.RESULT.style.position = 'absolute'; 307 _this.RESULT.style.top = (pos.bottom + 2) + 'px'; 308 _this.RESULT.style.left = pos.left + 'px'; 309 _this.RESULT.style.width = pos.width + 'px'; 310 } else { 311 _this.RESULT.style.position = 'absolute'; 312 _this.RESULT.style.top = (pos.bottom - 20) + 'px'; 313 _this.RESULT.style.left = pos.left - 100 + 'px'; 314 _this.RESULT.style.width = pos.width + 'px'; 315 316 } 317 318 return pos; 319 }; 320 321 this._onContainerLayoutChange = function () { 322 if (BX.type.isElementNode(_this.RESULT) 323 && _this.RESULT.style.display !== "none" 324 && _this.RESULT.innerHTML !== '' 325 ) { 326 _this.adjustResultNode(); 327 } 328 }; 329 this.Init = function () { 330 this.CONTAINER = document.getElementById(this.arParams.CONTAINER_ID); 331 BX.addCustomEvent(this.CONTAINER, "OnNodeLayoutChange", this._onContainerLayoutChange); 332 333 this.RESULT = document.body.appendChild(document.createElement("DIV")); 334 this.RESULT.className = 'title-search-result'; 335 this.INPUT = document.getElementById(this.arParams.INPUT_ID); 336 this.startText = this.oldValue = this.INPUT.value; 337 BX.bind(this.INPUT, 'focus', function () { _this.onFocusGain() }); 338 BX.bind(this.INPUT, 'blur', function () { _this.onFocusLost() }); 339 this.INPUT.onkeydown = this.onKeyDown; 340 341 if (this.arParams.WAIT_IMAGE) { 342 this.WAIT = document.body.appendChild(document.createElement("DIV")); 343 this.WAIT.style.backgroundImage = "url('" + this.arParams.WAIT_IMAGE + "')"; 344 if (!BX.browser.IsIE()) 345 this.WAIT.style.backgroundRepeat = 'none'; 346 this.WAIT.style.display = 'none'; 347 this.WAIT.style.position = 'absolute'; 348 this.WAIT.style.zIndex = '1100'; 349 } 350 351 BX.bind(this.INPUT, 'bxchange', function () { _this.onChange() }); 352 353 var fixedParent = BX.findParent(this.CONTAINER, BX.is_fixed); 354 if (BX.type.isElementNode(fixedParent)) { 355 BX.bind(window, 'scroll', BX.throttle(this.onScroll, 100, this)); 356 } 357 }; 358 BX.ready(function () { _this.Init(arParams) }); 359}
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.