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