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