1mse2Config = mse2Config || {}; 2var mSearch2 = { 3 initialized: false, 4 loading: false, 5 reached: false, 6 options: { 7 wrapper: '#mse2_mfilter', 8 9 results: '#mse2_results', 10 total: '#mse2_total', 11 limit: '#mse2_limit', 12 slider: '.mse2_number_slider', 13 14 filters: '#mse2_filters', 15 filter_title: '.filter_title', 16 filter_wrapper: 'fieldset', 17 18 pagination: '.mse2_pagination', 19 pagination_link: '.mse2_pagination a', 20 21 sort: '#mse2_sort', 22 sort_link: '#mse2_sort a', 23 24 tpl: '#mse2_tpl', 25 tpl_link: '#mse2_tpl a', 26 27 selected: '#mse2_selected', 28 selected_tpl: '<a href="#" data-id="_id_" class="mse2_selected_link"><em>_title_</em><sup>x</sup></a>', 29 selected_wrapper_tpl: '<strong>_title_:</strong>', 30 selected_filters_delimeter: '; ', 31 selected_values_delimeter: ' ', 32 33 more: '.btn_more', 34 more_tpl: '<button class="btn btn-default btn_more">' + mse2Config['moreText'] + '</button>', 35 36 active_class: 'active', 37 disabled_class: 'disabled', 38 disabled_class_fieldsets: 'disabled_fieldsets', 39 loading_class: 'loading', 40 reset_skip: ['limit', 'sort', 'tpl'], 41 prefix: 'mse2_', 42 suggestion: 'sup', // inside filter item, e.g. #mse2_filters 43 autoLoad: true, 44 }, 45 sliders: {}, 46 numbers: {}, 47 selections: {}, 48 elements: ['filters', 'results', 'pagination', 'total', 'sort', 'selected', 'limit', 'tpl'], 49 initialize: function (selector) { 50 if (this.initialized) { 51 return false; 52 } 53 var i; 54 if (mse2Config['filterOptions'] != undefined && Object.keys(mse2Config['filterOptions']).length > 0) { 55 for (i in mse2Config['filterOptions']) { 56 if (mse2Config['filterOptions'].hasOwnProperty(i)) { 57 this.options[i] = mse2Config['filterOptions'][i]; 58 } 59 } 60 } 61 for (i in this.elements) { 62 if (this.elements.hasOwnProperty(i)) { 63 var elem = this.elements[i]; 64 this[elem] = $(selector).find(this.options[elem]); 65 } 66 } 67 // Get ready for old chunk 68 if (this['pagination'].length == 0) { 69 this.options['pagination'] = '#mse2_pagination'; 70 this.options['pagination_link'] = '#mse2_pagination a'; 71 this['pagination'] = $(selector).find(this.options['pagination']); 72 } 73 this.handlePagination(); 74 this.handleSort(); 75 this.handleTpl(); 76 this.handleNumbers(); 77 this.handleSlider(); 78 this.handleLimit(); 79 80 var submit = $(this.options.filters + ' [type="submit"]'); 81 if (this.options.autoLoad) { 82 $(document).on('change', this.options.filters, function () { 83 return mSearch2.submit(); 84 }); 85 submit.addClass('hidden'); 86 } 87 else { 88 submit.removeClass('hidden'); 89 } 90 91 $(document).on('submit', this.options.filters, function () { 92 return mSearch2.submit(); 93 }); 94 95 this.btn_reset = $(this.options.filters + ' [type="reset"]'); 96 $(document).on('reset', this.options.filters, function () { 97 return mSearch2.reset(); 98 }); 99 100 for (i in this.startParams) { 101 if (this.startParams.hasOwnProperty(i) && this.options.reset_skip.indexOf(i) === -1) { 102 this.btn_reset.removeClass('hidden'); 103 break; 104 } 105 } 106 107 if (this.selected) { 108 this.selections[this.selected.text().replace(/\s+$/, '').replace(/:$/, '')] = []; 109 var selectors = [ 110 this.options.filters + ' input[type="checkbox"]', 111 this.options.filters + ' input[type="radio"]', 112 this.options.filters + ' select' 113 ]; 114 $(document).on('change', selectors.join(', '), function () { 115 mSearch2.handleSelected($(this)); 116 }); 117 118 selectors = [ 119 'input[type="checkbox"]:checked', 120 'input[type="radio"]:checked', 121 'select' 122 ]; 123 this.filters.find(selectors.join(', ')).each(function () { 124 mSearch2.handleSelected($(this)); 125 }); 126 127 $(document).on('click', this.options.selected + ' a', function () { 128 var id = $(this).data('id').replace(mse2Config['filter_delimeter'], "\\" + mse2Config['filter_delimeter']); 129 var elem = $('#' + id); 130 if (elem[0]) { 131 switch (elem[0].tagName) { 132 case 'INPUT': 133 elem.prop('checked', false).trigger('change'); 134 break; 135 case 'SELECT': 136 elem.val(elem.find('option:first').prop('value')).trigger('change'); 137 break; 138 } 139 } 140 return false;
141 }); 142 } 143 mSearch2.setEmptyFieldsets(); 144 mSearch2.setTotal(this.total.text()); 145 146 if (!mSearch2.Hash.oldbrowser()) { 147 history.replaceState({mSearch2: window.location.href}, '', document.location.href); 148 } 149 window.setTimeout(function() { 150 $(window).on('popstate', function (e) { 151 if (e.originalEvent.state && e.originalEvent.state['mSearch2']) { 152 var params = {}; 153 var tmp = e.originalEvent.state['mSearch2'].split('?'); 154 if (tmp[1]) { 155 tmp = tmp[1].split('&'); 156 for (var i in tmp) { 157 if (tmp.hasOwnProperty(i)) { 158 var tmp2 = tmp[i].split('='); 159 params[tmp2[0]] = tmp2[1]; 160 } 161 } 162 } 163 mSearch2.setFilters(params); 164 mSearch2.load(params); 165 } 166 }); 167 }, 1000); 168 169 this.initialized = true; 170 }, 171 172 handlePagination: function () { 173 var pcre = new RegExp(mse2Config['pageVar'] + '[=|\/|-](\\d+)'); 174 switch (mse2Config['mode']) { 175 case 'button': 176 this.pagination.hide(); 177 // Add more button 178 this.results.after(this.options['more_tpl']); 179 var more = $(this.options['more']); 180 181 var has_results = false; 182 $(this.options['pagination_link']).each(function () { 183 var href = $(this).prop('href'); 184 var match = href.match(pcre); 185 var page = !match ? 1 : match[1]; 186 if (page > mse2Config['page']) { 187 has_results = true; 188 return false; 189 } 190 }); 191 if (!has_results) { 192 more.hide(); 193 } 194 if (mse2Config['page'] > 1) { 195 mse2Config['page'] = ''; 196 mSearch2.Hash.remove('page'); 197 mSearch2.load(); 198 } 199 200 $(document).on('click', this.options['wrapper'] + ' ' + this.options['more'], function (e) { 201 e.preventDefault(); 202 mSearch2.addPage(); 203 }); 204 break; 205 206 case 'scroll': 207 this.pagination.hide(); 208 var wrapper = $(this.options['wrapper']); 209 var $window = $(window); 210 $window.on('scroll', function () { 211 if (!mSearch2.reached && $window.scrollTop() > wrapper.height() - $window.height()) { 212 mSearch2.reached = true; 213 mSearch2.addPage(); 214 } 215 }); 216 217 if (mse2Config['page'] > 1) { 218 mse2Config['page'] = ''; 219 mSearch2.Hash.remove('page'); 220 mSearch2.load(); 221 } 222 break; 223 224 default: 225 $(document).on('click', this.options.pagination_link, function () { 226 if (!$(this).hasClass(mSearch2.options.active_class)) { 227 $(mSearch2.options.pagination).removeClass(mSearch2.options.active_class); 228 $(this).addClass(mSearch2.options.active_class); 229 230 var tmp = $(this).prop('href').match(pcre); 231 var page = tmp && tmp[1] ? Number(tmp[1]) : 1; 232 mse2Config['page'] = (page != mse2Config['start_page']) ? page : ''; 233 234 var params = mSearch2.getFilters(); 235 mSearch2.Hash.set(params); 236 mSearch2.load(params, function () { 237 $('html, body').animate({ 238 scrollTop: $(mSearch2.options.wrapper).position().top || 0 239 }, 0); 240 }); 241 } 242 243 return false;
244 }); 245 } 246 }, 247 248 handleSort: function () { 249 var params = this.Hash.get(); 250 if (params.sort) { 251 var sorts = params.sort.split(mse2Config['values_delimeter']); 252 for (var i = 0; i < sorts.length; i++) { 253 var tmp = sorts[i].split(mse2Config['method_delimeter']); 254 if (tmp[0] && tmp[1]) { 255 $(this.options.sort_link + '[data-sort="' + tmp[0] + '"]').data('dir', tmp[1]).attr('data-dir', tmp[1]).addClass(this.options.active_class); 256 } 257 } 258 } 259 260 $(document).on('click', this.options.sort_link, function () { 261 if ($(this).hasClass(mSearch2.options.active_class) && $(this).data('dir') == '') { 262 return false; 263 } 264 $(mSearch2.options.sort_link).removeClass(mSearch2.options.active_class); 265 $(this).addClass(mSearch2.options.active_class); 266 var dir; 267 if ($(this).data('dir') == '') { 268 dir = $(this).data('default'); 269 } 270 else { 271 dir = $(this).data('dir') == 'desc' 272 ? 'asc' 273 : 'desc'; 274 } 275 $(mSearch2.options.sort_link).data('dir', '').attr('data-dir', ''); 276 $(this).data('dir', dir).attr('data-dir', dir); 277 278 var sort = $(this).data('sort'); 279 if (dir) { 280 sort = sort.replace( 281 new RegExp(mse2Config['method_delimeter'] + '.*?' + mse2Config['values_delimeter']), 282 mse2Config['method_delimeter'] + dir + mse2Config['values_delimeter'] 283 ); 284 sort += mse2Config['method_delimeter'] + dir; 285 } 286 mse2Config['sort'] = (sort != mse2Config['start_sort']) ? sort : ''; 287 var params = mSearch2.getFilters(); 288 if (mse2Config['page'] > 1 && (mse2Config['mode'] == 'scroll' || mse2Config['mode'] == 'button')) { 289 mse2Config['page'] = ''; 290 delete(params['page']); 291 } 292 mSearch2.Hash.set(params); 293 mSearch2.load(params); 294 295 return false; 296 }); 297 }, 298 299 handleTpl: function () { 300 $(document).on('click', this.options.tpl_link, function () { 301 if (!$(this).hasClass(mSearch2.options.active_class)) { 302 $(mSearch2.options.tpl_link).removeClass(mSearch2.options.active_class); 303 $(this).addClass(mSearch2.options.active_class); 304 305 var tpl = $(this).data('tpl'); 306 mse2Config['tpl'] = (tpl != mse2Config['start_tpl'] && tpl != 0) ? tpl : ''; 307 308 var params = mSearch2.getFilters(); 309 if (mse2Config['page'] > 1 && (mse2Config['mode'] == 'scroll' || mse2Config['mode'] == 'button')) { 310 mse2Config['page'] = ''; 311 delete(params['page']); 312 } 313 mSearch2.Hash.set(params); 314 mSearch2.load(params); 315 } 316 317 return false; 318 }); 319 }, 320 321 handleSlider: function () { 322 if (!$(mSearch2.options.slider).length) { 323 return false; 324 } 325 else if (!$.ui || !$.ui.slider) { 326 return mSearch2.loadJQUI(mSearch2.handleSlider); 327 } 328 $(mSearch2.options.slider).each(function () { 329 var $this = $(this); 330 var fieldset = $(this).parents('fieldset'); 331 var imin = fieldset.find('input:first'); 332 var imax = fieldset.find('input:last'); 333 var vmin = Number(imin.attr('value')); 334 var vmax = Number(imax.attr('value')); 335 var cmin = Number(imin.data('current-value')); 336 var cmax = Number(imax.data('current-value')); 337 // Check for decimals 338 var ival = imin.val(); 339 var decimal = ival.indexOf('.') != -1; 340 var decimals = decimal 341 ? Number(ival.substr(ival.indexOf('.') + 1).length) 342 : 0; 343 var delimiter = 1; 344 for (var i = 1; i <= decimals; i++) { 345 delimiter *= 10; 346 } 347 348 var name = imin.prop('name'); 349 $this.slider({ 350 min: vmin,
351 max: vmax, 352 values: [vmin, vmax], 353 range: true, 354 step: 1 / delimiter, 355 stop: function (e, ui) { 356 imin.val(ui.values[0].toFixed(decimals)); 357 imax.val(ui.values[1].toFixed(decimals)); 358 imin.add(imax).trigger('change'); 359 mSearch2.sliders[name]['user_changed'] = true; 360 }, 361 change: function (e, ui) { 362 if (mSearch2.sliders[name] != undefined && mSearch2.sliders[name]['values'] != undefined) { 363 mSearch2.sliders[name]['changed'] = mSearch2.sliders[name]['values'][0] != ui.values[0].toFixed(decimals) || 364 mSearch2.sliders[name]['values'][1] != ui.values[1].toFixed(decimals); 365 } 366 }, 367 slide: function (e, ui) { 368 if (decimal) { 369 imin.val(ui.values[0].toFixed(decimals)); 370 imax.val(ui.values[1].toFixed(decimals)); 371 } else { 372 imin.val(ui.values[0]); 373 imax.val(ui.values[1]); 374 } 375 } 376 }); 377 378 var changed = mSearch2.Hash.get()[name] !== undefined; 379 mSearch2.sliders[name] = { 380 changed: changed, 381 user_changed: changed 382 }; 383 384 var values = mSearch2.Hash.get(); 385 if (values[name]) { 386 var tmp = values[name].split(mse2Config['values_delimeter']); 387 if (tmp[0].match(/(?!^-)[^0-9\.]/g)) { 388 tmp[0] = tmp[0].replace(/(?!^-)[^0-9\.]/g, ''); 389 } 390 if (tmp.length > 1) { 391 if (tmp[1].match(/(?!^-)[^0-9\.]/g)) { 392 tmp[1] = tmp[1].replace(/(?!^-)[^0-9\.]/g, ''); 393 } 394 } 395 imin.val(tmp[0]); 396 imax.val(tmp.length > 1 ? tmp[1] : tmp[0]); 397 } 398 399 //imin.attr('readonly', true); 400 imin.attr('data-decimal', decimals); 401 imin.on('change keyup input click', function (e) { 402 if (this.value.match(/(?!^-)[^0-9\.]/g)) { 403 this.value = this.value.replace(/(?!^-)[^0-9\.]/g, ''); 404 } 405 if (e.type != 'keyup' && e.type != 'input') { 406 if (this.value > vmax) { 407 this.value = vmax; 408 } 409 else if (this.value < vmin) { 410 this.value = vmin; 411 } 412 } 413 if (e.type == 'change') { 414 mSearch2.sliders[name]['user_changed'] = true; 415 } 416 $this.slider('values', 0, this.value); 417 }); 418 //imax.attr('readonly', true); 419 imax.attr('data-decimal', decimals); 420 imax.on('change keyup input click', function (e) { 421 if (this.value.match(/(?!^-)[^0-9\.]/g)) { 422 this.value = this.value.replace(/(?!^-)[^0-9\.]/g, ''); 423 } 424 if (e.type != 'keyup' && e.type != 'input') { 425 if (this.value > vmax) { 426 this.value = vmax; 427 } 428 else if (this.value < vmin) { 429 this.value = vmin; 430 } 431 } 432 if (e.type == 'change') { 433 mSearch2.sliders[name]['user_changed'] = true; 434 } 435 $this.slider('values', 1, this.value); 436 }); 437 438 if (values[name]) { 439 imin.add(imax).trigger('click'); 440 } 441 442 mSearch2.sliders[name]['values'] = [vmin, vmax]; 443 if (!isNaN(cmin) && !isNaN(cmax)) { 444 if (cmin != 0 && cmin != vmin) { 445 $this.slider('values', 0, cmin); 446 imin.val(cmin); 447 } 448 if (cmax != 0 && cmax != vmax) { 449 $this.slider('values', 1, cmax); 450 imax.val(cmax); 451 }
452 mSearch2.sliders[name]['changed'] = mSearch2.Hash.get()[name] !== undefined; 453 } 454 }); 455 return true; 456 }, 457 458 handleLimit: function () { 459 $(document).on('change', this.options.limit, function () { 460 var limit = $(this).val(); 461 mse2Config['page'] = ''; 462 if (limit == mse2Config['start_limit']) { 463 mse2Config['limit'] = ''; 464 } 465 else { 466 mse2Config['limit'] = limit; 467 } 468 var params = mSearch2.getFilters(); 469 if (mse2Config['page'] > 1 && (mse2Config['mode'] == 'scroll' || mse2Config['mode'] == 'button')) { 470 mse2Config['page'] = ''; 471 delete(params['page']); 472 } 473 mSearch2.Hash.set(params); 474 mSearch2.load(params); 475 }); 476 }, 477 478 handleSelected: function (input) { 479 if (!input[0]) { 480 return; 481 } 482 var id = input.prop('id'); 483 var title = ''; 484 var elem; 485 486 var filter = input.parents(this.options['filter_wrapper']); 487 var filter_title = ''; 488 var tmp; 489 if (filter.length) { 490 tmp = filter.find(this.options['filter_title']); 491 if (tmp.length > 0) { 492 filter_title = tmp.text(); 493 } 494 } 495 if (filter_title == '') { 496 //noinspection LoopStatementThatDoesntLoopJS 497 for (filter_title in this.selections) { 498 break; 499 } 500 } 501 502 switch (input[0].tagName) { 503 case 'INPUT': 504 var label = mSearch2.filters.find('label[for="' + input.prop('id') + '"]'); 505 var sup = label.find('sup').text(); 506 var text = label.text().trim(); 507 if (sup) { 508 title = text.replace(new RegExp(sup.replace('+', '\\+') + '$'), ''); 509 } else { 510 title = text; 511 } 512 $('[data-id="' + id + '"]', this.selected).remove(); 513 if (input.is(':checked')) { 514 elem = this.options['selected_tpl'] 515 .replace('[[+id]]', id).replace('[[+title]]', title) 516 .replace('_id_', id).replace('_title_', title); 517 } 518 break; 519 520 case 'SELECT': 521 var option = input.find('option:selected'); 522 $('[data-id="' + id + '"]', this.selected).remove(); 523 if (input.val() != '') { 524 title = ' ' + option.text().replace(/(\(.*\)$)/, ''); 525 elem = this.options['selected_tpl'] 526 .replace('[[+id]]', id).replace('[[+title]]', title) 527 .replace('_id_', id).replace('_title_', title); 528 } 529 break; 530 } 531 532 if (elem != undefined) { 533 if (this.selections[filter_title] == undefined || input[0].type == 'radio') { 534 this.selections[filter_title] = {}; 535 } 536 this.selections[filter_title][id] = elem; 537 } 538 else if (this.selections[filter_title] != undefined && this.selections[filter_title][id] != undefined) { 539 delete this.selections[filter_title][id]; 540 } 541 542 this.selected.html(''); 543 var count = 0; 544 var selected = []; 545 for (var i in this.selections) { 546 if (!this.selections.hasOwnProperty(i) || !Object.keys(this.selections).length) { 547 continue; 548 } 549 if (Object.keys(this.selections[i]).length) { 550 tmp = []; 551 for (var i2 in this.selections[i]) { 552 if (!this.selections[i].hasOwnProperty(i2)) { 553 continue; 554 } 555 tmp.push(this.selections[i][i2]); 556 count++; 557 } 558 title = this.options['selected_wrapper_tpl'] 559 .replace('[[+title]]', i) 560 .replace('_title_', i); 561 selected.push(title + tmp.join(this.options['selected_values_delimeter'])); 562 } 563 } 564 565 if (count) { 566 this.selected.append(selected.join(this.options['selected_filters_delimeter'])).show(); 567 } 568 else { 569 this.selected.hide(); 570 } 571 }, 572 573 handleNumbers: function () { 574 var groups = {}; 575 $('input[type="text"],input[type="number"]', mSearch2.filters).each(function() { 576 var $this = $(this); 577 var name = $this.attr('name'); 578 if (groups[name] == undefined) { 579 groups[name] = [$this]; 580 } else { 581 groups[name].push($this); 582 } 583 }); 584 585 var data = this.Hash.get(); 586 for (var name in groups) { 587 if (!groups.hasOwnProperty(name)) { 588 continue; 589 } 590 var group = groups[name]; 591 if (group.length == 2) { 592 var $min = group[0]; 593 var $max = group[1]; 594 var vmin = $min.val(); 595 var vmax = $max.val(); 596 $min.attr('data-original-value', vmin); 597 $max.attr('data-original-value', vmax); 598 this.numbers[name] = { 599 values: [vmin, vmax], 600 }; 601 if (data[name] != undefined) { 602 var values = data[name].split(mse2Config['values_delimeter']); 603 if (values.length == 2) { 604 $min.val(values[0]); 605 $max.val(values[1]); 606 } 607 } 608 } 609 } 610 }, 611 612 load: function (params, callback, append) { 613 if (this.loading) { 614 return false;
615 } else { 616 this.loading = true; 617 } 618 619 this.btn_reset.addClass('hidden'); 620 for (var i in params) { 621 if (params.hasOwnProperty(i) && this.options.reset_skip.indexOf(i) === -1) { 622 this.btn_reset.removeClass('hidden'); 623 break; 624 } 625 } 626 627 if (!params || !Object.keys(params).length) { 628 params = this.getFilters(); 629 } 630 params.action = 'filter'; 631 params.pageId = mse2Config['pageId']; 632 633 this.beforeLoad(); 634 params.key = mse2Config['key']; 635 //noinspection JSUnresolvedFunction 636 $.post(mse2Config['actionUrl'], params, function (response) { 637 mSearch2.loading = false; 638 mSearch2.afterLoad(); 639 if (response['success']) { 640 mSearch2.Message.success(response['message']); 641 mSearch2.pagination.html(response['data']['pagination']); 642 if (append) { 643 mSearch2.results.append(response['data']['results']); 644 } 645 else { 646 mSearch2.results.html(response['data']['results']); 647 } 648 649 if (mse2Config['mode'] == 'button') { 650 if (response['data']['pages'] == response['data']['page']) { 651 $(mSearch2.options['more']).hide(); 652 } 653 else { 654 $(mSearch2.options['more']).show(); 655 } 656 } 657 else if (mse2Config['mode'] == 'scroll') { 658 mSearch2.reached = response['data']['pages'] == response['data']['page']; 659 } 660 661 mSearch2.setTotal(response['data']['total']); 662 if (callback && $.isFunction(callback)) { 663 callback.call(this, response, params); 664 } 665 mSearch2.setSuggestions(response['data']['suggestions']); 666 mSearch2.setEmptyFieldsets(); 667 if (response['data'].log) { 668 $('.mFilterLog').html(response['data'].log); 669 } 670 mSearch2.updateTitle(response['data']); 671 $(document).trigger('mse2_load', response); 672 } 673 else { 674 mSearch2.Message.error(response['message']); 675 } 676 }, 'json'); 677 }, 678 679 getFilters: function () { 680 var params = {}; 681 // Disabled friendly urls 682 var hash = this.Hash.get(); 683 if (hash[mse2Config['idVar']] != undefined) { 684 params[mse2Config['idVar']] = hash[mse2Config['idVar']]; 685 } 686 // Other params 687 if (mse2Config[mse2Config['queryVar']] != '') { 688 params[mse2Config['queryVar']] = mse2Config[mse2Config['queryVar']]; 689 } 690 if (mse2Config[mse2Config['parentsVar']] != '') { 691 params[mse2Config['parentsVar']] = mse2Config[mse2Config['parentsVar']]; 692 } 693 if (mse2Config['sort'] != '') { 694 params.sort = mse2Config['sort']; 695 } 696 if (mse2Config['tpl'] != '') { 697 params.tpl = mse2Config['tpl']; 698 } 699 if (mse2Config['page'] > 0) { 700 params.page = mse2Config['page']; 701 } 702 if (mse2Config['limit'] > 0) { 703 params.limit = mse2Config['limit']; 704 } 705 // Filters 706 $.map(this.filters.serializeArray(), function (n) { 707 if (n.value === '') { 708 return; 709 } 710 if (params[n.name]) { 711 params[n.name] += mse2Config['values_delimeter'] + n.value; 712 } 713 else { 714 params[n.name] = n.value; 715 } 716 }); 717 var i; 718 for (i in this.sliders) { 719 if (this.sliders.hasOwnProperty(i) && params[i]) { 720 if (!this.sliders[i]['changed']) { 721 delete params[i]; 722 } 723 } 724 } 725 for (i in this.numbers) { 726 if (this.numbers.hasOwnProperty(i) && params[i]) { 727 if (this.numbers[i]['values'].join(mse2Config['values_delimeter']) == params[i]) { 728 delete params[i]; 729 } 730 } 731 } 732 733 return params; 734 }, 735 736 setFilters: function (params) { 737 if (!params) { 738 params = {}; 739 } 740 for (var i in this.elements) { 741 if (!this.elements.hasOwnProperty(i)) { 742 continue; 743 } 744 var elem = this.elements[i]; 745 if (typeof(this[elem]) == 'undefined') { 746 continue; 747 } 748 var item, name, values, val, type; 749 switch (elem) { 750 case 'limit': 751 if (params['limit'] == undefined) { 752 this.limit.val(mse2Config['start_limit']); 753 mse2Config['limit'] = ''; 754 } 755 else { 756 this.limit.val(params['limit']); 757 } 758 break; 759 case 'pagination': 760 mse2Config['page'] = params['page'] == undefined 761 ? '' 762 : params['page']; 763 break;
764 case 'sort': 765 var sorts = {}; 766 values = params['sort']; 767 if (values == undefined) { 768 values = mse2Config['start_sort']; 769 mse2Config['sort'] = ''; 770 } 771 if (typeof(values) != 'object' && values != '') { 772 values = values.split(mse2Config['values_delimeter']); 773 for (i in values) { 774 if (!values.hasOwnProperty(i)) { 775 continue; 776 } 777 name = values[i].split(mse2Config['method_delimeter']); 778 if (name[0] && name[1]) { 779 sorts[name[0]] = name[1]; 780 } 781 } 782 } 783 $(document).find(this.options['sort_link']).each(function () { 784 item = $(this); 785 name = item.data('sort'); 786 if (sorts[name]) { 787 item.data('dir', sorts[name]).attr('data-dir', sorts[name]); 788 item.addClass(mSearch2.options['active_class']); 789 } 790 else { 791 item.data('dir', '').attr('data-dir', ''); 792 item.removeClass(mSearch2.options['active_class']); 793 } 794 }); 795 break; 796 case 'tpl': 797 values = params['tpl'] != undefined 798 ? params['tpl'] 799 : 0; 800 $(document).find(this.options['tpl_link']).each(function () { 801 item = $(this); 802 if (item.data('tpl') == values) { 803 item.addClass(mSearch2.options['active_class']); 804 mse2Config['tpl'] = values; 805 } 806 else { 807 item.removeClass(mSearch2.options['active_class']); 808 } 809 }); 810 break; 811 case 'filters': 812 this['filters'].find('input').each(function () { 813 item = $(this); 814 name = item.prop('name'); 815 type = item.prop('type'); 816 values = params[name]; 817 if (values != undefined && typeof(values) != 'object') { 818 values = values.split(mse2Config['values_delimeter']); 819 } 820 switch (type) { 821 case 'checkbox': 822 case 'radio': 823 var checked = item.is(':checked'); 824 if (params[name] != undefined) { 825 item.prop('checked', values.indexOf(String(item.val())) != -1); 826 } 827 else { 828 item.prop('checked', false); 829 } 830 if (item.is(':checked') != checked) { 831 mSearch2.handleSelected(item); 832 } 833 break; 834 default: 835 if (mSearch2.sliders[name]) { 836 if (item.prop('id').match(/.*?_0$/)) { 837 val = (values != undefined && values[0] != undefined) 838 ? values[0] 839 : mSearch2.sliders[name]['values'][0]; 840 } 841 else { 842 val = (values != undefined && values[1] != undefined) 843 ? values[1] 844 : mSearch2.sliders[name]['values'][1]; 845 } 846 if (val != item.val()) { 847 item.val(val).trigger('click'); 848 } 849 } else { 850 var original = item.data('original-value'); 851 if (original != undefined) { 852 item.val(original); 853 } 854 } 855 } 856 }); 857 this['filters'].find('select').each(function () { 858 item = $(this); 859 name = item.prop('name'); 860 type = item.prop('type'); 861 values = params[name]; 862 if (values != undefined) { 863 if (typeof(values) != 'object') { 864 values = values.split(mse2Config['values_delimeter']); 865 } 866 item.find('option').each(function () { 867 var option = $(this); 868 val = option.prop('value'); 869 var selected = option.is(':selected'); 870 $(this).prop('selected', values.indexOf(String(val)) != -1); 871 if (option.is(':selected') != selected) { 872 mSearch2.handleSelected(item); 873 } 874 }); 875 } 876 else { 877 item.val(''); 878 } 879 /* 880 if (params[name] != undefined) { 881 item.prop('checked', values.indexOf(String(item.val())) != -1); 882 } 883 else { 884 item.prop('checked', false); 885 } 886 */ 887 }); 888 break; 889 } 890 } 891 }, 892 893 setSuggestions: function (suggestions) { 894 var aliases = mse2Config['aliases'] || {}; 895 var alias, value; 896 for (var filter in suggestions) { 897 if (!suggestions.hasOwnProperty(filter)) { 898 continue; 899 } 900 var is_slider = typeof(this.sliders[filter]) != 'undefined'; 901 var is_number = typeof(this.numbers[filter]) != 'undefined'; 902 var arr = suggestions[filter]; 903 alias = filter; 904 if (typeof(aliases[filter]) != 'undefined') { 905 filter = aliases[filter]; 906 } 907 var count, selector, input; 908 if (is_slider && !this.sliders[alias]['user_changed']) { 909 var vmin = null; 910 var vmax = null; 911 for (value in arr) { 912 if (!arr.hasOwnProperty(value)) { 913 continue; 914 } 915 count = arr[value]; 916 if (typeof(count) != 'number') { 917 continue; 918 } 919 if (count > 0 && (vmin === null || vmin > value)) { 920 vmin = Number(value); 921 } 922 if (count > 0 && vmax < value) { 923 vmax = Number(value); 924 } 925 } 926 selector = filter.replace(mse2Config['filter_delimeter'], "\\" + mse2Config['filter_delimeter']); 927 var imin = $('#' + mSearch2.options.prefix + selector + '_0', mSearch2.filters); 928 if (imin.length) { 929 if (vmin == null) { 930 vmin = Number(imin.data('original-value')); 931 } 932 imin.val(vmin.toFixed(imin.data('decimal'))).trigger('click'); 933 } 934 var imax = $('#' + mSearch2.options.prefix + selector + '_1', mSearch2.filters); 935 if (imax.length) { 936 if (vmax == null) { 937 vmax = Number(imax.data('original-value')); 938 } 939 imax.val(vmax.toFixed(imax.data('decimal'))).trigger('click'); 940 } 941 this.sliders[alias]['values'] = [vmin, vmax];
942 this.sliders[alias]['changed'] = false; 943 } 944 else if (is_number) { 945 // Do nothing 946 } 947 else { 948 for (value in arr) { 949 if (!arr.hasOwnProperty(value)) { 950 continue; 951 } 952 count = arr[value]; 953 selector = CSS.escape(filter); 954 input = $('#' + mSearch2.options.prefix + selector, mSearch2.filters).find('[value="' + value.replace(/"/g, '\\"') + '"]'); 955 if (!input[0]) { 956 continue; 957 } 958 959 switch (input[0].tagName) { 960 case 'INPUT': 961 var proptype = input.prop('type'); 962 if (proptype != 'checkbox' && proptype != 'radio') { 963 continue; 964 } 965 var label = $('#' + mSearch2.options.prefix + selector, mSearch2.filters).find('label[for="' + input.prop('id') + '"]'); 966 var elem = input.parent().find(mSearch2.options.suggestion); 967 elem.text(count); 968 969 if (count == 0) { 970 if (input.is(':not(:checked)')) { 971 input.prop('disabled', true); 972 label.addClass(mSearch2.options.disabled_class); 973 mSearch2.handleSelected(input); 974 } 975 } 976 else { 977 input.prop('disabled', false); 978 label.removeClass(mSearch2.options.disabled_class); 979 } 980 981 if (input.is(':checked')) { 982 elem.hide(); 983 } 984 else { 985 elem.show(); 986 } 987 break; 988 989 case 'OPTION': 990 var text = input.text(); 991 var matches = text.match(/\([^\)]+\)$/); 992 var src = matches 993 ? matches[0] 994 : ''; 995 var dst = ''; 996 997 if (!count) { 998 input.prop('disabled', true).addClass(mSearch2.options.disabled_class); 999 /* 1000 if (input.is(':selected')) { 1001 input.prop('selected', false); 1002 mSearch2.handleSelected(input); 1003 } 1004 */ 1005 } 1006 else { 1007 dst = ' (' + count + ')'; 1008 input.prop('disabled', false).removeClass(mSearch2.options.disabled_class); 1009 } 1010 1011 if (input.is(':selected')) { 1012 dst = ''; 1013 } 1014 1015 if (src) { 1016 text = text.replace(src, dst); 1017 } 1018 else { 1019 text += dst; 1020 } 1021 input.text(text); 1022 1023 mSearch2.handleSelected(input.parent()); 1024 break; 1025 } 1026 } 1027 } 1028 } 1029 }, 1030 1031 setEmptyFieldsets: function () { 1032 this.filters.find('fieldset').each(function () { 1033 var all_children_disabled = $(this).find('label:not(.' + mSearch2.options.disabled_class + ')').length == 0; 1034 if (all_children_disabled) { 1035 $(this).addClass(mSearch2.options.disabled_class_fieldsets); 1036 } 1037 if (!all_children_disabled && $(this).hasClass(mSearch2.options.disabled_class_fieldsets)) { 1038 $(this).removeClass(mSearch2.options.disabled_class_fieldsets); 1039 } 1040 }); 1041 }, 1042 1043 setTotal: function (total) { 1044 if (this.total.length != 0) { 1045 if (!total || total == 0) { 1046 this.total.parent().hide(); 1047 this.limit.parent().hide(); 1048 this.sort.hide(); 1049 this.total.text(0); 1050 } 1051 else { 1052 this.total.parent().show(); 1053 this.limit.parent().show(); 1054 this.sort.show(); 1055 this.total.text(total); 1056 } 1057 } 1058 }, 1059 1060 beforeLoad: function () { 1061 $(this.options['wrapper']).addClass(this.options['loading_class']); 1062 this.results.css('opacity', .5); 1063 this.filters.find('input, select').prop('readonly', true).addClass(this.options.disabled_class); 1064 }, 1065 1066 afterLoad: function () { 1067 $(this.options['wrapper']).removeClass(this.options['loading_class']); 1068 this.results.css('opacity', 1); 1069 this.filters.find('.' + this.options.disabled_class).prop('readonly', false).removeClass(this.options.disabled_class); 1070 }, 1071 1072 loadJQUI: function (callback, parameters) { 1073 $('<link/>', { 1074 rel: 'stylesheet', 1075 type: 'text/css', 1076 href: mse2Config['cssUrl'] + 'jquery-ui/jquery-ui.min.css' 1077 }).appendTo('head'); 1078 1079 return $.getScript(mse2Config['jsUrl'] + 'lib/jquery-ui.min.js', function () { 1080 if (typeof callback == 'function') { 1081 callback(parameters); 1082 } 1083 }); 1084 }, 1085 1086 submit: function (params) { 1087 if (this.loading) { 1088 return false;
1089 } 1090 else if (!params || !Object.keys(params).length) { 1091 params = this.getFilters(); 1092 } 1093 else { 1094 delete(params['action']); 1095 delete(params['key']); 1096 delete(params['pageId']); 1097 } 1098 delete(params['page']); 1099 1100 var action = $(this.options.filters).attr('action'); 1101 if (!mSearch2.options.autoLoad) { 1102 var vars = ''; 1103 for (var i in params) { 1104 if (params.hasOwnProperty(i)) { 1105 vars += '&' + i + '=' + params[i]; 1106 } 1107 } 1108 if (!action.match(/\?/)) { 1109 document.location = action + vars.replace(/^&/, '?'); 1110 } 1111 else { 1112 document.location = action + vars; 1113 } 1114 return false; 1115 } 1116 else { 1117 mse2Config['page'] = ''; 1118 mSearch2.Hash.set(params); 1119 mSearch2.load(params); 1120 return false; 1121 } 1122 }, 1123 1124 reset: function () { 1125 if (this.loading) { 1126 return false; 1127 } 1128 var hash = this.Hash.get(); 1129 var data = {}; 1130 this.Hash.clear(); 1131 for (var i in this.options.reset_skip) { 1132 if (!this.options.reset_skip.hasOwnProperty(i)) { 1133 continue; 1134 } 1135 var item = this.options.reset_skip[i]; 1136 if (hash[item] != undefined) { 1137 data[item] = hash[item]; 1138 } 1139 } 1140 this.setFilters(data); 1141 for (var value in this.sliders) { 1142 if (this.sliders.hasOwnProperty(value)) { 1143 this.sliders[value]['changed'] = 1144 this.sliders[value]['user_changed'] = false; 1145 } 1146 } 1147 1148 return this.submit(); 1149 }, 1150 1151 addPage: function () { 1152 var pcre = new RegExp(mse2Config['pageVar'] + '[=|\/|-](\\d+)'); 1153 var current = mse2Config['page'] || 1; 1154 $(this.options['pagination_link']).each(function () { 1155 var href = $(this).prop('href'); 1156 var match = href.match(pcre); 1157 var page = !match ? 1 : Number(match[1]); 1158 if (page > current) { 1159 mse2Config['page'] = (page != mse2Config['start_page']) ? page : ''; 1160 var tmp = mSearch2.getFilters(); 1161 delete(tmp['page']); 1162 mSearch2.Hash.set(tmp); 1163 1164 var params = mSearch2.getFilters(); 1165 mSearch2.load(params, null, true); 1166 return false; 1167 } 1168 }); 1169 }, 1170 1171 updateTitle: function (response) { 1172 if (typeof(pdoTitle) == 'undefined') { 1173 return; 1174 } 1175 var $title = $('title'); 1176 var separator = pdoTitle['separator'] || ' / '; 1177 var tpl = pdoTitle['tpl']; 1178 1179 var title = []; 1180 var items = $title.text().split(separator); 1181 var pcre = new RegExp('^' + tpl.split(' ')[0] + ' '); 1182 for (var i = 0; i < items.length; i++) { 1183 if (i === 1 && response['page'] && response['page'] > 1) { 1184 title.push(tpl.replace('{page}', response['page']).replace('{pageCount}', response['pages'])); 1185 } 1186 if (!items[i].match(pcre)) { 1187 title.push(items[i]); 1188 } 1189 } 1190 $title.text(title.join(separator)); 1191 }, 1192 1193}; 1194 1195mSearch2.Form = { 1196 initialized: false, 1197 initialize: function (selector) { 1198 if (this.initialized || typeof(mse2FormConfig) == 'undefined') { 1199 return false; 1200 } 1201 $(selector).each(function () { 1202 var form = $(this); 1203 var config = mse2FormConfig[form.data('key')]; 1204 var cache = {}; 1205 1206 if (config.autocomplete == '0' || config.autocomplete == 'false') { 1207 return false; 1208 } 1209 else if (!$.ui || !$.ui.autocomplete) { 1210 return mSearch2.loadJQUI(mSearch2.Form.initialize, selector); 1211 } 1212 1213 form.find('input[name="' + config['queryVar'] + '"]').autocomplete({ 1214 source: function (request, callback) { 1215 if (request.term in cache) { 1216 callback(cache[request.term]); 1217 return; 1218 } 1219 var data = { 1220 action: 'search', 1221 key: form.data('key'), 1222 pageId: config.pageId 1223 }; 1224 data[config['queryVar']] = request.term; 1225 //noinspection JSUnresolvedFunction 1226 $.post(mse2Config['actionUrl'], data, function (response) { 1227 if (response['data']['log']) { 1228 $('.mSearchFormLog').html(response['data']['log']); 1229 } 1230 else { 1231 $('.mSearchFormLog').html(''); 1232 } 1233 cache[request.term] = response['data']['results']; 1234 callback(response['data']['results']) 1235 }, 'json'); 1236 }, 1237 minLength: config['minQuery'] || 3, 1238 select: function (event, ui) { 1239 if (ui.item.url) { 1240 document.location.href = ui.item.url; 1241 } 1242 else { 1243 setTimeout(function () { 1244 form.submit(); 1245 }, 100); 1246 } 1247 } 1248 }).data("ui-autocomplete")._renderItem = 1249 function (ul, item) { 1250 return $('<li>') 1251 .data("item.autocomplete", item) 1252 .addClass("mse2-ac-wrapper") 1253 .append($("<div>").addClass('mse2-ac-link').html(item.label)) 1254 //.append("<a class=\"mse2-ac-link\">" + item.label + "</a>") 1255 .appendTo(ul); 1256 }; 1257
1258 //noinspection JSPotentiallyInvalidConstructorUsage,JSUnresolvedVariable 1259 jQuery.ui.autocomplete.prototype._resizeMenu = function () { 1260 var ul = this.menu.element; 1261 ul.outerWidth(this.element.outerWidth()); 1262 }; 1263 1264 return true; 1265 }); 1266 this.initialized = true; 1267 } 1268}; 1269 1270mSearch2.Message = { 1271 success: function (message) { 1272 }, 1273 error: function (message) { 1274 alert(message); 1275 } 1276}; 1277 1278mSearch2.Hash = { 1279 get: function () { 1280 var vars = {}, hash, splitter, hashes; 1281 if (!this.oldbrowser()) { 1282 var pos = window.location.href.indexOf('?'); 1283 hashes = (pos != -1) ? decodeURIComponent(window.location.href.substr(pos + 1)) : ''; 1284 splitter = '&'; 1285 } 1286 else { 1287 hashes = decodeURIComponent(window.location.hash.substr(1)); 1288 splitter = '/'; 1289 } 1290 1291 if (hashes.length == 0) { 1292 return vars; 1293 } 1294 else { 1295 hashes = hashes.split(splitter); 1296 } 1297 1298 for (var i in hashes) { 1299 if (hashes.hasOwnProperty(i)) { 1300 hash = hashes[i].split('='); 1301 if (typeof hash[1] == 'undefined') { 1302 vars['anchor'] = hash[0]; 1303 } 1304 else { 1305 vars[hash[0]] = hash[1]; 1306 } 1307 } 1308 } 1309 return vars; 1310 }, 1311 set: function (vars) { 1312 var hash = ''; 1313 var i; 1314 for (i in vars) { 1315 if (vars.hasOwnProperty(i)) { 1316 hash += '&' + i + '=' + vars[i]; 1317 } 1318 } 1319 if (!this.oldbrowser()) { 1320 if (hash.length != 0) { 1321 hash = '?' + hash.substr(1); 1322 var specialChars = {"%": "%25", "+": "%2B"}; 1323 for (i in specialChars) { 1324 if (specialChars.hasOwnProperty(i) && hash.indexOf(i) !== -1) { 1325 hash = hash.replace(new RegExp('\\' + i, 'g'), specialChars[i]); 1326 } 1327 } 1328 } 1329 window.history.pushState({mSearch2: document.location.pathname + hash}, '', document.location.pathname + hash); 1330 } 1331 else { 1332 window.location.hash = hash.substr(1); 1333 } 1334 }, 1335 add: function (key, val) { 1336 var hash = this.get(); 1337 hash[key] = val; 1338 this.set(hash); 1339 }, 1340 remove: function (key) { 1341 var hash = this.get(); 1342 delete hash[key]; 1343 this.set(hash); 1344 }, 1345 clear: function () { 1346 this.set({}); 1347 }, 1348 oldbrowser: function () { 1349 return !(window.history && history.pushState); 1350 } 1351}; 1352 1353mSearch2.startParams = mSearch2.Hash.get();
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.