1// page init 2 3var path_theme = jQuery('#path-theme').val(); 4 5jQuery(function(){ 6 7 "use strict"; 8 9 initVideoPlayer(); 10 11 initNumCounter(); 12 13 initFitVids(); 14 15 initCarousel(); 16 17 initCountDown(); 18 19 initSlideShow(); 20 21 initAccordion(); 22 23 initFlickrPhotos(); 24 25 initVimeoPlayer(); 26 27 initAudioPlayer(); 28 29 initCustomForms(); 30 31 initAnimatedProgressbars(); 32 33 initYoutubePlayer(); 34 35 initCycleCarousel(); 36 37 initFormValidation(); 38 39 initGoToTop(); 40 41 initJqureyAnimation(); 42 43 initGoToTopScroll(); 44 45 initPieCharts(); 46 47 initInstagramPics('2311561473.1677ed0.4e364b1ee1664889b061b4bb21612abe', ' e37e5979509b44cb811a8be2b1067f11'); 48 49 initFlexSlider(); 50 51 initOwlSlider(); 52 53}); 54 55jQuery(window).on('load', function() { 56 57 "use strict"; 58 59 MegaMenu(); 60 61 initPreLoader(); 62 63 initTabs(); 64 65 initMarquee(); 66 67 initIsotope(); 68 69 initLightbox(); 70 71 initAjaxLoad(); 72 73 initGoogleMap(); 74 75 initMobileNav(); 76 77 initSameHeight(); 78 79 initParallaxBg(); 80 81 initStyleChanger(); 82 83 initHasDropClasses(); 84 85 initStickyHeader(); 86 87 initIsotopControl(); 88 89 initBackgroundResize(); 90 91 jQuery('input, textarea').placeholder(); 92 93 initAnchors(); 94 95}); 96 97 98 99jQuery(window).scroll(function() { 100 101 initPieCharts(); 102 103 initGoToTopScroll(); 104 105 initAnimatedProgressbars(); 106 107}); 108 109 110 111// FlexSlider init 112 113function initFlexSlider() { 114 115 jQuery('.flexslider').flexslider({ 116 117 animation: "slide" 118 119 }); 120 121} 122 123 124 125// OwlSlider init 126 127function initOwlSlider() { 128 129 jQuery('#owl-example').owlCarousel({ 130 131 autoPlay: true 132 133 }); 134 135} 136 137 138 139// sticky header init 140 141function initStickyHeader() { 142 143 var win = jQuery(window), 144 145 stickyClass = 'fixed-position'; 146 147 148 149 jQuery('#header').each(function() { 150 151 var header = jQuery(this); 152 153 var headerOffset = header.offset().top || 0; 154 155 var flag = true; 156 157 158 159 function scrollHandler() { 160 161 if (win.scrollTop() > headerOffset) { 162 163 if (flag){ 164 165 flag = false; 166 167 header.addClass(stickyClass); 168 169 } 170 171 } else { 172 173 if (!flag) { 174 175 flag = true; 176 177 header.removeClass(stickyClass); 178 179 } 180 181 } 182 183 184 185 ResponsiveHelper.addRange({ 186 187 '..767': { 188 189 on: function() { 190 191 header.removeClass(stickyClass); 192 193 } 194 195 } 196 197 }); 198 199 } 200 201 202 203 scrollHandler(); 204 205 win.on('scroll resize orientationchange', scrollHandler); 206 207 }); 208 209} 210 211 212 213// instagram photos init 214 215function initInstagramPics(instaToken, instaID) { 216 217 var instaBox = jQuery('.instagram-photos'); 218 219 220 221 jQuery.fn.spectragram.accessData = { 222 223 accessToken: instaToken, 224 225 clientID: instaID 226 227 }; 228 229 230 231 instaBox.each(function() { 232 233 var item = jQuery(this); 234 235 var userName = item.attr('data-user'); 236 237 var limit = item.attr('data-count') ? Number(item.attr('data-count')) : 8; 238 239 240 241 item.spectragram('getPopular',{ 242 243 max: limit, 244 245 size: 'medium', 246 247 wrapEachWith: ' ' 248 249 }); 250 251 }); 252 253} 254 255 256 257// animation init 258 259function initJqureyAnimation() { 260 261 var sections = jQuery('[data-animate]'); 262 263 var pageBody = jQuery('body'); 264 265 266 267 sections.each(function() { 268 269 var item = jQuery(this); 270 271 var delay = item.attr('data-delay') ? Number(item.attr('data-delay')) + 500 : 500; 272 273 var animation = item.attr('data-animate'); 274 275 276 277 if(!item.hasClass('animated')) { 278 279 item.addClass('not-animated'); 280 281 item.appear(function () { 282 283 setTimeout(function() { 284 285 item.removeClass('not-animated').addClass(animation + ' animated'); 286 287 }, delay); 288 289 },{accX: 0, accY: -120},'easeInCubic'); 290 291 } 292 293 }); 294 295} 296 297 298 299// flickr feed init 300 301function initFlickrPhotos() { 302 303 var flickrBox = jQuery('.flickr-feed'); 304 305 306 307 flickrBox.each(function() { 308 309 var item = jQuery(this); 310 311 var feedType = item.attr('data-type'); 312 313 314 315 item.jflickrfeed({ 316 317 feedapi: feedType === 'group' ? 'groups_pool.gne' : feedType, 318 319 limit: Number(item.attr('data-count')) || 8, 320 321 qstrings: { 322 323 id: item.attr('data-id') 324 325 }, 326 327 itemTemplate: '<a href="{{image_b}}" title="{{title}}" rel="lightbox">' + '<img src="{{image_s}}" alt="{{title}}" />' + '</a>' 328 329 }); 330 331 }); 332 333} 334 335 336 337// animate pie charts init 338 339function initPieCharts() { 340 341 if(typeof jQuery.fn.easyPieChart != 'undefined'){ 342 343 jQuery(".pie-chart:in-viewport").each(function() { 344 345 var item = jQuery(this); 346 347 var dimension = item.attr("data-barSize"); 348 349 350 351 item.css({ 352 353 'height': dimension, 354 355 'width': dimension, 356 357 'line-height': dimension + 'px' 358 359 }); 360 361 362 363 item.easyPieChart({ 364 365 animate: 2000, 366 367 lineCap: "square", 368 369 lineWidth: item.attr("data-lineWidth"), 370 371 size: dimension, 372 373 barColor: item.attr("data-barColor"), 374 375 trackColor: item.attr("data-trackColor"), 376 377 scaleColor: "transparent", 378 379 onStep: function(from, to, percent) { 380 381 jQuery(this.el).find('.pie-chart-percent span').text(Math.round(from)); 382 383 } 384 385 }); 386 387 }); 388 389 } 390 391} 392 393 394 395// progressbars init 396 397function initAnimatedProgressbars() { 398 399 jQuery(".progress-bar .progress-bar-outer:in-viewport").each(function() { 400 401 var item = jQuery(this); 402 403 var percent = item.attr('data-width'); 404 405 var animationSpeed = 2500; 406 407 var flag = false;
408 409 410 411 if(!flag) { 412 413 item.animate({ 414 415 width: percent + "%" 416 417 }, animationSpeed); 418 419 420 421 flag = true; 422 423 } 424 425 }); 426 427} 428 429 430 431// count down init 432 433function initCountDown() { 434 435 if (jQuery('#countdown').length) { 436 437 var year = jQuery('#countdown').data('year'); 438 439 var month = jQuery('#countdown').data('month') - 1; 440 441 var day = jQuery('#countdown').data('day'); 442 443 var newDate = new Date(year, month, day); 444 445 jQuery('#countdown').countdown({until: newDate}); 446 447 } 448 449} 450 451 452 453// counter init 454 455function initNumCounter() { 456 457 var counters = jQuery('.counter'); 458 459 var pageBody = jQuery('body'); 460 461 462 463 counters.each(function() { 464 465 var item = jQuery(this); 466 467 var isComma = item.find('span').attr('data-comma'); 468 469 470 471 item.appear(function() { 472 473 if(isComma) { 474 475 item.find('span').countTo({ 476 477 formatter: function (value, options) { 478 479 value = value.toFixed(options.decimals); 480 481 value = value.replace(/\B(?=(\d{3})+(?!\d))/g, ','); 482 483 return value; 484 485 } 486 487 }); 488 489 } else { 490 491 item.find('span').countTo(); 492 493 } 494 495 }); 496 497 }); 498 499} 500 501 502 503// go to top init 504 505function initGoToTop() { 506 507 var linkTop = jQuery('#gotoTop'); 508 509 var animationSpeed = 600; 510 511 512 513 linkTop.click(function(e) { 514 515 e.preventDefault(); 516 517 518 519 jQuery('body,html').stop(true).animate({ 520 521 scrollTop: 0 522 523 }, animationSpeed); 524 525 }); 526 527} 528 529 530 531// go to top scroll init 532 533function initGoToTopScroll() { 534 535 var linkTop = jQuery('#gotoTop'), 536 537 win = jQuery(window); 538 539 540 541 if(win.scrollTop() > 0) { 542 543 linkTop.fadeIn(); 544 545 } else { 546 547 linkTop.fadeOut(); 548 549 } 550 551} 552 553 554 555// PreLoader init 556 557function initPreLoader() { 558 559 jQuery('#pre-loader').delay(1200).fadeOut(); 560 561} 562 563 564 565// AudioPlayer init 566 567function initAudioPlayer() { 568 569 jQuery('audio').mediaelementplayer(); 570 571} 572 573 574 575// VimeoPlayer init 576 577function initVimeoPlayer() { 578 579 var vimeoHolder = jQuery('.vimeo-area'); 580 581 582 583 vimeoHolder.each(function(index, item) { 584 585 var container = jQuery(item); 586 587 var vimeoBox = container.find('.vimeo'); 588 589 var iframe = jQuery('#player1')[0]; 590 591 var player = $f(iframe); 592 593 var button = container.find('.btn-play'); 594 595 var activeClass = 'playing'; 596 597 598 599 window.setTimeout(function() { 600 601 vimeoBox.css({ 602 603 visibility: 'visible' 604 605 }); 606 607 }, 2000); 608 609 610 611 player.addEvent('ready', function() { 612 613 player.api('setVolume', 0); 614 615 button.on('click', function(e) { 616 617 e.preventDefault(); 618 619 620 621 if(button.hasClass(activeClass)) { 622 623 player.api('pause'); 624 625 button.removeClass(activeClass); 626 627 } else { 628 629 player.api('play'); 630 631 button.addClass(activeClass); 632 633 } 634 635 }); 636 637 }); 638 639 }); 640 641} 642 643 644 645// initVideoPlayer init 646 647function initVideoPlayer() { 648 649 jQuery('.video-area').each(function() { 650 651 var container = jQuery(this); 652 653 var player = container.find('video').mediaelementplayer().get(0); 654 655 var button = container.find('.btn-play'); 656 657 var activeClass = 'playing'; 658 659 660 661 662 663 if(container.hasClass('mute')) { 664 665 player.setVolume(0); 666 667 } 668 669 button.on('click', function(e) { 670 671 e.preventDefault(); 672 673 674 675 if(button.hasClass(activeClass)) { 676 677 player.pause(); 678 679 button.removeClass(activeClass); 680 681 } else { 682 683 player.play(); 684 685 button.addClass(activeClass); 686 687 } 688 689 }); 690 691 }); 692 693} 694 695 696 697// GoogleMap init 698 699function initGoogleMap() { 700 701 jQuery('.map').googleMapAPI({ 702 703 marker: path_theme+'/images/icons/marker.png', 704 705 mapInfoContent: '.map-info', 706 707 streetViewControl: false, 708 709 mapTypeControl: false, 710 711 scrollwheel: false, 712 713 panControl: false, 714 715 zoomControl: false 716 717 }); 718 719} 720 721 722 723// Custom variables for isotop 724 725function initIsotopControl() { 726 727 var isotopeHolder = jQuery('#work'), 728 729 win = jQuery(window); 730 731 732 733 isotopeHolder.isotope({transitionDuration: '0.75s'}); 734 735 736 737 setTimeout(function() { 738 739 isotopeHolder.isotope('layout'); 740 741 }, 100); 742 743 744 745 jQuery('#work-filter a').click(function(e){ 746 747 e.preventDefault(); 748 749 750 751 jQuery('#work-filter li').removeClass('active'); 752 753 jQuery(this).parent('li').addClass('active'); 754 755 var selector = jQuery(this).attr('data-filter'); 756 757 isotopeHolder.isotope({ filter: selector }); 758 759 }); 760 761 762 763 jQuery('#work-shuffle').click(function() { 764 765 isotopeHolder.isotope('updateSortData').isotope({ 766 767 sortBy: 'random' 768 769 }); 770 771 }); 772 773 774 775 win.resize(function() { 776 777 isotopeHolder.isotope('layout'); 778 779 }); 780 781} 782 783 784 785// style changer 786 787function initStyleChanger() { 788 789 var element = jQuery('#style-changer'); 790 791 792 793 if(element) { 794 795 $.ajax({ 796 797 url: element.attr('data-src'), 798 799 type: 'get', 800 801 dataType: 'text', 802 803 success: function(data) { 804 805 var newContent = jQuery('<div>', { 806 807 html: data 808 809 }); 810 811 812 813 newContent.appendTo(element); 814 815 jQuery('body').mobileNav({ 816 817 hideOnClickOutside: false, 818 819 menuActiveClass: 'changer-active', 820 821 menuOpener: '.changer-opener' 822 823 }); 824 825 jQuery('body').mobileNav({ 826 827 hideOnClickOutside: false, 828 829 menuActiveClass: 'boxed-v', 830 831 menuOpener: '.boxed-link, .btn2', 832 833 onInit: function() { 834 835 initIsotopControl(); 836
837 initBackgroundResize(); 838 839 }, 840 841 onHide: function() { 842 843 initIsotopControl(); 844 845 initBackgroundResize(); 846 847 } 848 849 }); 850 851 852 853 var sheet, 854 855 darkSheet, 856 857 sheetName, 858 859 darkSheetName = 'dark', 860 861 sheetAdded = false, 862 863 darkStylesAdded = false; 864 865 866 867 jQuery('.list-color li').each(function() { 868 869 var item = jQuery(this), 870 871 link = item.find('a').eq(0); 872 873 var path_theme = jQuery('#style-changer').data('path-theme'); 874 875 link.on('click', function(e) { 876 877 e.preventDefault(); 878 879 sheetName = item.attr('class'); 880 881 882 883 if(!sheetAdded) { 884 885 sheet = jQuery('<link>').attr('rel','stylesheet') 886 887 .attr('type','text/css') 888 889 .attr('href', path_theme+'/css/color/' + sheetName + '.css') 890 891 .appendTo('head'); 892 893 894 895 sheetAdded = true; 896 897 } else { 898 899 sheet.attr('href', path_theme+'/css/color/' + sheetName + '.css'); 900 901 } 902 903 }); 904 905 }); 906 907 jQuery('.list-bg-color li').each(function() { 908 909 var body = jQuery('body'), 910 911 item = jQuery(this), 912 913 link = item.find('a').eq(0); 914 915 916 917 link.on('click', function(e) { 918 919 e.preventDefault(); 920 921 922 923 body.removeClass('dark'); 924 925 if(link.hasClass('dark')) { 926 927 if(!body.hasClass('dark')) { 928 929 body.addClass('dark'); 930 931 } 932 933 } 934 935 }); 936 937 }); 938 939 } 940 941 }); 942 943 } 944 945} 946 947 948 949// initialize smooth anchor links 950 951function initAnchors() { 952 953 new SmoothScroll({ 954 955 anchorLinks: 'a[href^="#"].smoothanchor', 956 957 extraOffset: 66, 958 959 activeClasses: 'parent' 960 961 }); 962 963} 964 965 966 967// content tabs init 968 969function initTabs() { 970 971 jQuery('ul.beans-tabset').contentTabs({ 972 973 addToParent: true, 974 975 tabLinks: 'a' 976 977 }); 978 979 jQuery('ul.tabset').contentTabs({ 980 981 addToParent: true, 982 983 tabLinks: 'a' 984 985 }); 986 987 jQuery('ul.tabset-onepage').contentTabs({ 988 989 addToParent: true, 990 991 tabLinks: 'a' 992 993 }); 994 995} 996 997 998 999// Isotope init 1000 1001function initIsotope() { 1002 1003 jQuery('#masonry-container').isotope({ 1004 1005 itemSelector: '.item', 1006 1007 transitionDuration: '0.6s', 1008 1009 masonry: { 1010 1011 columnWidth: 2, 1012 1013 gutter: 0, 1014 1015 isResizable: false 1016 1017 } 1018 1019 }); 1020 1021} 1022 1023 1024 1025// init youtube background player 1026 1027function initYoutubePlayer() { 1028 1029 jQuery(".youtube_bg_video").each(function() { 1030 1031 var player = jQuery(this), 1032 1033 btnPlay = player.closest('.video-section').find('.play-icon'), 1034 1035 videoPlaying = false; 1036 1037 player.YTPlayer(); 1038 1039 1040 1041 btnPlay.on('click', function(e) { 1042 1043 e.preventDefault(); 1044 1045 if(videoPlaying) { 1046 1047 player.pauseYTP(); 1048 1049 btnPlay.removeClass('video-playing').addClass('video-pause'); 1050 1051 videoPlaying = false; 1052 1053 } else { 1054 1055 player.playYTP(); 1056 1057 btnPlay.removeClass('video-pause').addClass('video-playing'); 1058 1059 videoPlaying = true; 1060 1061 } 1062 1063 }); 1064 1065 }); 1066 1067} 1068 1069 1070 1071// handle flexible video size 1072 1073function initFitVids() { 1074 1075 jQuery('.vimeo').fitVids(); 1076 1077 jQuery('.video-area').fitVids(); 1078 1079} 1080 1081 1082 1083// align blocks height 1084 1085function initSameHeight() { 1086 1087 setSameHeight({ 1088 1089 holder: '.same-block', 1090 1091 elements: '.same-column', 1092 1093 flexible: true, 1094 1095 multiLine: true, 1096 1097 biggestHeight: true 1098 1099 }); 1100 1101} 1102 1103 1104 1105// ajax load init 1106 1107function initAjaxLoad(){ 1108 1109 jQuery('.ajax-area').ajaxPopup({ 1110 1111 button: '.btn-load', 1112 1113 ajaxHold: '#ajax-holder', 1114 1115 appendToBody: false, 1116 1117 attr: 'href', 1118 1119 animSpeed: 500, 1120 1121 onChange: function(){ 1122 1123 initCycleCarousel(); 1124
1125 initBackgroundResize(); 1126 1127 } 1128 1129 }); 1130 1131} 1132 1133 1134 1135// scroll galleries init 1136 1137function initCarousel() { 1138 1139 jQuery('.beans-stepslider').scrollGallery({ 1140 1141 mask: '.beans-mask', 1142 1143 slider: '.beans-slideset', 1144 1145 slides: '.beans-slide', 1146 1147 btnPrev: 'a.btn-prev', 1148 1149 btnNext: 'a.btn-next', 1150 1151 generatePagination: '.beans-pagination', 1152 1153 stretchSlideToMask: true, 1154 1155 maskAutoSize: true, 1156 1157 autoRotation: false, 1158 1159 switchTime: 6000, 1160 1161 animSpeed: 1000, 1162 1163 step: 1 1164 1165 }); 1166 1167} 1168 1169 1170 1171// cycle scroll galleries init 1172 1173function initCycleCarousel() { 1174 1175 jQuery('.beans-slider').scrollAbsoluteGallery({ 1176 1177 mask: '.beans-mask', 1178 1179 slider: '.beans-slideset', 1180 1181 slides: '.beans-slide', 1182 1183 btnPrev: 'a.btn-prev', 1184 1185 btnNext: 'a.btn-next', 1186 1187 generatePagination: '.beans-pagination', 1188 1189 stretchSlideToMask: true, 1190 1191 pauseOnHover: false, 1192 1193 maskAutoSize: true, 1194 1195 autoRotation: false, 1196 1197 switchTime: 3000, 1198 1199 animSpeed: 1000 1200 1201 }); 1202 1203 jQuery('.beans-stepslider2').scrollAbsoluteGallery({ 1204 1205 mask: '.beans-mask', 1206 1207 slider: '.beans-slideset', 1208 1209 slides: '.beans-slide', 1210 1211 btnPrev: 'a.btn-prev', 1212 1213 btnNext: 'a.btn-next', 1214 1215 pagerLinks: '.beans-pagination ul li', 1216 1217 stretchSlideToMask: true, 1218 1219 pauseOnHover: false, 1220 1221 maskAutoSize: true, 1222 1223 autoRotation: false, 1224 1225 switchTime: 3000, 1226 1227 animSpeed: 1000 1228 1229 }); 1230 1231} 1232 1233 1234 1235// fade gallery init 1236 1237function initSlideShow() { 1238 1239 jQuery('.beans-fadeslider').fadeGallery({ 1240 1241 slides: '.slide', 1242 1243 btnPrev: 'a.btn-prev', 1244 1245 btnNext: 'a.btn-next', 1246 1247 generatePagination: '.beans-pagination', 1248 1249 event: 'click', 1250 1251 useSwipe: true, 1252 1253 autoRotation: true, 1254 1255 autoHeight: true, 1256 1257 switchTime: 3000, 1258 1259 animSpeed: 1000 1260 1261 }); 1262 1263} 1264 1265 1266 1267// mobile menu init 1268 1269function initMobileNav() { 1270 1271 jQuery('body').mobileNav({ 1272 1273 hideOnClickOutside: true, 1274 1275 menuActiveClass: 'sidenav-active', 1276 1277 menuOpener: '.menu-opener , .btn-close', 1278 1279 menuDrop: '.menu-nav' 1280 1281 }); 1282 1283 jQuery('body').mobileNav({ 1284 1285 hideOnClickOutside: false, 1286 1287 menuActiveClass: 'search-active', 1288 1289 menuOpener: '.search-opener , .close-btn' 1290 1291 }); 1292 1293 jQuery('body').mobileNav({ 1294 1295 hideOnClickOutside: false, 1296 1297 menuActiveClass: 'mainnav-active', 1298 1299 menuOpener: '.nav-opener', 1300 1301 menuDrop: '.sidemenu-photo' 1302 1303 }); 1304 1305 jQuery('body').mobileNav({ 1306 1307 hideOnClickOutside: true, 1308 1309 menuActiveClass: 'mainnav-active', 1310 1311 menuOpener: '.main-navopener2', 1312 1313 menuDrop: '.main-menu' 1314 1315 }); 1316 1317 jQuery('body').mobileNav({ 1318 1319 hideOnClickOutside: true, 1320 1321 menuActiveClass: 'nav-active', 1322 1323 menuOpener: '.portfolio-nav-opener' 1324 1325 }); 1326 1327} 1328 1329//Mega menu 1330 1331function MegaMenu() { 1332 1333 jQuery('.nav-top > li.expanded').each(function(index, el) { 1334 1335 var menu = ''; 1336 1337 if($(this).hasClass('has-mega-drop')) { 1338 1339 menu += '<a href="'+$(this).find('>a').attr("href")+'" class="'+$(this).find('>a').attr("class")+'">'; 1340 1341 menu += $(this).find('>a').text()+'</a><div class="mega-drop"><div class="drop-holder">'; 1342 1343 $(this).find('> .list-unstyled >li').each(function(index, el) { 1344 1345 if($(this).hasClass('title')) { 1346 1347 menu += '<div class="coll"><strong class="title">' + $(this).find('>a').text() + '</strong>'; 1348 1349 menu += '<ul class="list-unstyled">'; 1350 1351 $(this).find('>.list-unstyled >li').each(function(index, el) { 1352 1353 if($(this).hasClass('title')) { 1354 1355 menu += '<strong class="title">' + $(this).find('>a').text() + '</strong>'; 1356 1357 if($(this).find('.list-unstyled').html()) { 1358 1359 menu += '<ul class="list-unstyled">' +$(this).find('>.list-unstyled').html() + '</ul>'; 1360 1361 } else menu += ''; 1362 1363 1364 1365 } else { 1366 1367 menu += '<li>' +$(this).html()+ '</li>'; 1368 1369 } 1370 1371 1372 1373 }); 1374 1375 menu += '</div>'; 1376 1377 1378 1379 } else { 1380 1381 menu += '<strong class="title">' + $(this).find('>a').text() + '</strong>'; 1382 1383 if($(this).find('.list-unstyled').html()) { 1384 1385 menu += '<ul class="list-unstyled">' + $(this).find('.list-unstyled').html() + '</ul></div>'; 1386 1387 } else menu += '</div>'; 1388 1389 } 1390 1391 }); 1392 1393 menu += '</div></div>'; 1394 1395 $(this).html(menu); 1396 1397 } else { 1398 1399 menu += '<a href="'+$(this).find('>a').attr("href")+'">'+ $(this).find('>a').text() + '</a>'; 1400 1401 menu += '<div class="drop"><ul class="list-unstyled">'; 1402 1403 $(this).find(">.list-unstyled >li").each(function(index, el) { 1404 1405 if($(this).hasClass('expanded')) { 1406 1407 menu += '<li class="has-drop"><a href="' + $(this).find('>a').attr('href')+'">'+ $(this).find('>a').text()+ '</a>'; 1408 1409 if($(this).find('.list-unstyled').html()) { 1410 1411 menu += '<div class="drop"><ul class="list-unstyled">'; 1412 1413 $(this).find('>.list-unstyled >li').each(function(index, el) { 1414 1415 if($(this).hasClass('expanded')) { 1416 1417 menu += '<li class="has-drop"><a href="' + $(this).find('>a').attr('href')+'">'+ $(this).find('>a').text()+ '</a>'; 1418 1419 if($(this).find('.list-unstyled').html()) { 1420 1421 menu += '<div class="drop"><ul class="list-unstyled">' + $(this).find('.list-unstyled').html()+ '</ul></div>'; 1422 1423 } else { 1424 1425 menu += '<div class="drop"></div>'; 1426 1427 } 1428 1429 menu += '</li>'; 1430 1431 } else { 1432 1433 menu += '<li><a href="' + $(this).find('>a').attr('href')+'">'+ $(this).find('>a').text()+ '</a></li>'; 1434 1435 } 1436 1437 }); 1438 1439 menu += '</ul></div>'; 1440 1441 } else { 1442 1443 1444 1445 } 1446 1447 menu += '</li>'; 1448 1449 } else { 1450 1451 menu += '<li><a href="' + $(this).find('>a').attr('href')+'">'+ $(this).find('>a').text()+ '</a></li>'; 1452 1453 } 1454 1455 }); 1456 1457 menu += '</ul></div>'; 1458 1459 $(this).html(menu); 1460 1461 } 1462 1463 }); 1464 1465} 1466 1467// dropdown classes 1468 1469function initHasDropClasses() { 1470 1471 var dropClassName = 'has-drop', 1472 1473 megaDropClassName = 'has-mega-drop'; 1474 1475 1476 1477 jQuery('#nav li').each(function(index, item) { 1478 1479 var container = jQuery(item), 1480 1481 link = container.find('a'), 1482 1483 drop = container.find('.drop'), 1484 1485 megaDrop = container.find('.mega-drop'); 1486 1487 1488 1489 if(drop.length) { 1490 1491 container.addClass(dropClassName); 1492 1493 } 1494 1495 1496 1497 if(megaDrop.length) { 1498 1499 container.addClass(megaDropClassName); 1500 1501 } 1502 1503 }); 1504 1505} 1506 1507 1508 1509// initialize Parallax background 1510 1511function initParallaxBg() { 1512 1513 jQuery('.parallax-holder').parallaxBG({ 1514 1515 parent: '.parallax-frame', 1516 1517 image: 'img', 1518 1519 parallaxOffset: 100, 1520 1521 fallbackFunc: initBgStretch 1522 1523 }); 1524 1525} 1526 1527 1528 1529// stretch background to fill blocks 1530
1531function initBackgroundResize() { 1532 1533 jQuery('.stretch').each(function() { 1534 1535 ImageStretcher.add({ 1536 1537 container: this, 1538 1539 image: 'img' 1540 1541 }); 1542 1543 }); 1544 1545} 1546 1547 1548 1549// running line init 1550 1551function initMarquee() { 1552 1553 jQuery('.line-box').marquee({ 1554 1555 line: '.line', 1556 1557 animSpeed: 50 1558 1559 }); 1560 1561} 1562 1563 1564 1565// initialize custom form elements 1566 1567function initCustomForms() { 1568 1569 jcf.replaceAll(); 1570 1571} 1572 1573 1574 1575// fancybox modal popup init 1576 1577function initLightbox() { 1578 1579 jQuery('a.lightbox, a[rel*="lightbox"]').fancybox({ 1580 1581 padding: 0, 1582 1583 loop: false, 1584 1585 helpers: { 1586 1587 overlay: { 1588 1589 css: {background: 'rgba(0, 0, 0, 0.35)'} 1590 1591 } 1592 1593 }, 1594 1595 afterLoad: function(current, previous) { 1596 1597 // handle custom close button in inline modal 1598 1599 if(current.href.indexOf('#') === 0) { 1600 1601 jQuery(current.href).find('a.close').off('click.fb').on('click.fb', function(e){ 1602 1603 e.preventDefault(); 1604 1605 jQuery.fancybox.close(); 1606 1607 }); 1608 1609 } 1610 1611 } 1612 1613 }); 1614 1615} 1616 1617 1618 1619// accordion menu init 1620 1621function initAccordion() { 1622 1623 jQuery('.blog-accordion').slideAccordion({ 1624 1625 opener: 'a.opener', 1626 1627 slider: '.blog-slide', 1628 1629 animSpeed: 300 1630 1631 }); 1632 1633 jQuery('.beans-accordion').slideAccordion({ 1634 1635 opener: 'a.opener', 1636 1637 slider: '.beans-slide', 1638 1639 animSpeed: 300 1640 1641 }); 1642 1643} 1644 1645 1646 1647// form validation init 1648 1649function initFormValidation() { 1650 1651 //if submit button is clicked 1652 1653 $('#submit,#submit2').click(function () { 1654 1655 1656 1657 //Get the data from all the fields 1658 1659 var name = $('input[name=name]'); 1660 1661 var email = $('input[name=email]'); 1662 1663 var website = $('input[name=website]'); 1664 1665 var comment = $('textarea[name=comment]'); 1666 1667 var returnError = false; 1668 1669 1670 1671 //Simple validation to make sure user entered something 1672 1673 //Add your own error checking here with JS, but also do some error checking with PHP. 1674 1675 //If error found, add hightlight class to the text field 1676 1677 if (name.val()=='') { 1678 1679 name.addClass('error'); 1680 1681 returnError = true; 1682 1683 } else name.removeClass('error'); 1684 1685 1686 1687 if (email.val()=='') { 1688 1689 email.addClass('error'); 1690 1691 returnError = true; 1692 1693 } else email.removeClass('error'); 1694 1695 1696 1697 if (comment.val()=='') { 1698 1699 comment.addClass('error'); 1700 1701 returnError = true; 1702 1703 } else comment.removeClass('error'); 1704 1705 1706 1707 // Highlight all error fields, then quit. 1708 1709 if(returnError == true) { 1710 1711 return false; 1712 1713 } 1714 1715 1716 1717 //organize the data 1718 1719 var data = 'name=' + name.val() + '&email=' + email.val() + '&website=' + website.val() + '&comment=' + encodeURIComponent(comment.val()); 1720 1721 1722 1723 //disabled all the text fields 1724 1725 $('.text').attr('disabled','true'); 1726 1727 1728 1729 //show the loading sign 1730 1731 $('.loading').show(); 1732 1733 1734 1735 //start the ajax 1736 1737 $.ajax({ 1738 1739 //this is the php file that processes the data and sends email 1740 1741 url: "inc/process.php", 1742 1743 1744 1745 //GET method is used 1746 1747 type: "GET", 1748 1749 1750 1751 //pass the data 1752 1753 data: data, 1754 1755 1756 1757 //Do not cache the page 1758 1759 cache: false, 1760 1761 1762 1763 //success 1764 1765 success: function (html) { 1766 1767 //if process.php returned 1/true (send mail success) 1768 1769 if (html==1) { 1770 1771 //hide the form 1772 1773 $('.email-form').fadeOut('slow'); 1774 1775 1776 1777 //show the success message 1778 1779 $('.done-massage').fadeIn('slow'); 1780 1781 1782 1783 //if process.php returned 0/false (send mail failed) 1784 1785 } else alert('Sorry, unexpected error. Please try again later.'); 1786 1787 } 1788 1789 }); 1790 1791 1792 1793 //cancel the submit button default behaviours 1794 1795 return false; 1796 1797 }); 1798 1799 //if submit button is clicked 1800 1801 $('#form-submit').click(function () { 1802 1803 1804 1805 //Get the data from all the fields 1806 1807 var name = $('input[name=name]'); 1808 1809 var email = $('input[name=email]'); 1810 1811 var purchase = $('input[name=purchase]'); 1812 1813 var profile = $('input[name=profile]'); 1814 1815 var comment = $('textarea[name=comment]'); 1816 1817 var returnError = false; 1818 1819 1820 1821 //Simple validation to make sure user entered something 1822 1823 //Add your own error checking here with JS, but also do some error checking with PHP. 1824 1825 //If error found, add hightlight class to the text field 1826 1827 if (name.val()=='') { 1828 1829 name.addClass('error'); 1830 1831 returnError = true; 1832 1833 } else name.removeClass('error'); 1834 1835 1836 1837 if (email.val()=='') { 1838 1839 email.addClass('error'); 1840 1841 returnError = true; 1842 1843 } else email.removeClass('error'); 1844 1845 1846 1847 if (purchase.val()=='') { 1848 1849 purchase.addClass('error'); 1850 1851 returnError = true; 1852 1853 } else purchase.removeClass('error'); 1854 1855 1856 1857 if (profile.val()=='') { 1858 1859 profile.addClass('error'); 1860 1861 returnError = true; 1862 1863 } else profile.removeClass('error'); 1864 1865 1866 1867 if (comment.val()=='') { 1868 1869 comment.addClass('error'); 1870 1871 returnError = true; 1872 1873 } else comment.removeClass('error'); 1874 1875 1876 1877 // Highlight all error fields, then quit. 1878 1879 if(returnError == true) { 1880 1881 return false;
1882 1883 } 1884 1885 1886 1887 //organize the data 1888 1889 var data = 'name=' + name.val() + '&email=' + email.val() + '&purchase=' + purchase.val() + '&profile=' + profile.val() + '&website=' + website.val() + '&comment=' + encodeURIComponent(comment.val()); 1890 1891 1892 1893 //disabled all the text fields 1894 1895 $('.form-control').attr('disabled','true'); 1896 1897 1898 1899 //show the loading sign 1900 1901 $('.loading').show(); 1902 1903 1904 1905 //start the ajax 1906 1907 $.ajax({ 1908 1909 //this is the php file that processes the data and sends email 1910 1911 url: "inc/process2.php", 1912 1913 1914 1915 //GET method is used 1916 1917 type: "GET", 1918 1919 1920 1921 //pass the data 1922 1923 data: data, 1924 1925 1926 1927 //Do not cache the page 1928 1929 cache: false, 1930 1931 1932 1933 //success 1934 1935 success: function (html) { 1936 1937 //if process.php returned 1/true (send mail success) 1938 1939 if (html==1) { 1940 1941 //hide the form 1942 1943 $('.email-form').fadeOut('slow'); 1944 1945 1946 1947 //show the success message 1948 1949 $('.done-massage').fadeIn('slow'); 1950 1951 1952 1953 //if process.php returned 0/false (send mail failed) 1954 1955 } else alert('Sorry, unexpected error. Please try again later.'); 1956 1957 } 1958 1959 }); 1960 1961 1962 1963 //cancel the submit button default behaviours 1964 1965 return false; 1966 1967 }); 1968 1969} 1970 1971 1972 1973 1974 1975/* 1976 1977 * jQuery Carousel plugin 1978 1979 */ 1980 1981;(function($){function ScrollGallery(options) {this.options = $.extend({mask: 'div.mask',slider: '>*',slides: '>*',activeClass:'active',disabledClass:'disabled',btnPrev: 'a.btn-prev',btnNext: 'a.btn-next',generatePagination: false,pagerList: '<ul>',pagerListItem: '<li><a href="#"></a></li>',pagerListItemText: 'a',pagerLinks: '.pagination li',currentNumber: 'span.current-num',totalNumber: 'span.total-num',btnPlay: '.btn-play',btnPause: '.btn-pause',btnPlayPause: '.btn-play-pause',galleryReadyClass: 'gallery-js-ready',autorotationActiveClass: 'autorotation-active',autorotationDisabledClass: 'autorotation-disabled',stretchSlideToMask: false,circularRotation: true,disableWhileAnimating: false,autoRotation: false,pauseOnHover: false,maskAutoSize: false,switchTime: 4000,animSpeed: 600,event:'click',swipeThreshold: 15,handleTouch: true,vertical: false,useTranslate3D: false,step: false}, options);this.init();}ScrollGallery.prototype = {init: function() {if(this.options.holder) {this.findElements();this.attachEvents();this.refreshPosition();this.refreshState(true);this.resumeRotation();this.makeCallback('onInit', this);}},findElements: function() {this.fullSizeFunction = this.options.vertical ? 'outerHeight' : 'outerWidth';this.innerSizeFunction = this.options.vertical ? 'height' : 'width';this.slideSizeFunction = 'outerHeight';this.maskSizeProperty = 'height';this.animProperty = this.options.vertical ? 'marginTop' : 'marginLeft';this.gallery = $(this.options.holder).addClass(this.options.galleryReadyClass);this.mask = this.gallery.find(this.options.mask);this.slider = this.mask.find(this.options.slider);this.slides = this.slider.find(this.options.slides);this.btnPrev = this.gallery.find(this.options.btnPrev);this.btnNext = this.gallery.find(this.options.btnNext);this.currentStep = 0; this.stepsCount = 0;if(this.options.step === false) {var activeSlide = this.slides.filter('.'+this.options.activeClass);if(activeSlide.length) {this.currentStep = this.slides.index(activeSlide);}}this.calculateOffsets();if(typeof this.options.generatePagination === 'string') {this.pagerLinks = $();this.buildPagination();} else {this.pagerLinks = this.gallery.find(this.options.pagerLinks);this.attachPaginationEvents();}this.btnPlay = this.gallery.find(this.options.btnPlay);this.btnPause = this.gallery.find(this.options.btnPause);this.btnPlayPause = this.gallery.find(this.options.btnPlayPause);this.curNum = this.gallery.find(this.options.currentNumber);this.allNum = this.gallery.find(this.options.totalNumber);},attachEvents: function() {var self = this;this.bindHandlers(['onWindowResize']);$(window).bind('load resize orientationchange', this.onWindowResize);if(this.btnPrev.length) {this.prevSlideHandler = function(e) {e.preventDefault();self.prevSlide();};this.btnPrev.bind(this.options.event, this.prevSlideHandler);}if(this.btnNext.length) {this.nextSlideHandler = function(e) {e.preventDefault();self.nextSlide();};this.btnNext.bind(this.options.event, this.nextSlideHandler);}if(this.options.pauseOnHover && !isTouchDevice) {this.hoverHandler = function() {if(self.options.autoRotation) {self.galleryHover = true;self.pauseRotation();}};this.leaveHandler = function() {if(self.options.autoRotation) {self.galleryHover = false;self.resumeRotation();}};this.gallery.bind({mouseenter: this.hoverHandler, mouseleave: this.leaveHandler});}if(this.btnPlay.length) {this.btnPlayHandler = function(e) {e.preventDefault();self.startRotation();};this.btnPlay.bind(this.options.event, this.btnPlayHandler);}if(this.btnPause.length) {this.btnPauseHandler = function(e) {e.preventDefault();self.stopRotation();};this.btnPause.bind(this.options.event, this.btnPauseHandler);}if(this.btnPlayPause.length) {this.btnPlayPauseHandler = function(e) {e.preventDefault();if(!self.gallery.hasClass(self.options.autorotationActiveClass)) {self.startRotation();} else {self.stopRotation();}};this.btnPlayPause.bind(this.options.event, this.btnPlayPauseHandler);}if(isTouchDevice && this.options.useTranslate3D) {this.slider.css({'-webkit-transform': 'translate3d(0px, 0px, 0px)'});}if(isTouchDevice && this.options.handleTouch && window.Hammer && this.mask.length) {this.swipeHandler = new Hammer.Manager(this.mask[0]);this.swipeHandler.add(new Hammer.Pan({direction: self.options.vertical ? Hammer.DIRECTION_VERTICAL : Hammer.DIRECTION_HORIZONTAL,threshold: self.options.swipeThreshold}));this.swipeHandler.on('panstart', function() {if(self.galleryAnimating) {self.swipeHandler.stop();} else {self.pauseRotation();self.originalOffset = parseFloat(self.slider.css(self.animProperty));}}).on('panmove', function(e) {var tmpOffset = self.originalOffset + e[self.options.vertical ? 'deltaY' : 'deltaX'];tmpOffset = Math.max(Math.min(0, tmpOffset), self.maxOffset);self.slider.css(self.animProperty, tmpOffset);}).on('panend', function(e) {self.resumeRotation();if(e.distance > self.options.swipeThreshold) {if(e.offsetDirection === Hammer.DIRECTION_RIGHT || e.offsetDirection === Hammer.DIRECTION_DOWN) {self.nextSlide();} else {self.prevSlide();}} else {self.switchSlide();}});}},onWindowResize: function() {if(!this.galleryAnimating) {this.calculateOffsets();this.refreshPosition();this.buildPagination();this.refreshState();this.resizeQueue = false;} else {this.resizeQueue = true;}},refreshPosition: function() {this.currentStep = Math.min(this.currentStep, this.stepsCount - 1);this.tmpProps = {};
1981this.tmpProps[this.animProperty] = this.getStepOffset();this.slider.stop().css(this.tmpProps);},calculateOffsets: function() {var self = this, tmpOffset, tmpStep;if(this.options.stretchSlideToMask) {var tmpObj = {};tmpObj[this.innerSizeFunction] = this.mask[this.innerSizeFunction]();this.slides.css(tmpObj);}this.maskSize = this.mask[this.innerSizeFunction]();this.sumSize = this.getSumSize();this.maxOffset = this.maskSize - this.sumSize;if(this.options.vertical && this.options.maskAutoSize) {this.options.step = 1;this.stepsCount = this.slides.length;this.stepOffsets = [0];tmpOffset = 0;for(var i = 0; i < this.slides.length; i++) {tmpOffset -= $(this.slides[i])[this.fullSizeFunction](true);this.stepOffsets.push(tmpOffset);}this.maxOffset = tmpOffset;return;}if(typeof this.options.step === 'number' && this.options.step > 0) {this.slideDimensions = [];this.slides.each($.proxy(function(ind, obj){self.slideDimensions.push( $(obj)[self.fullSizeFunction](true) );},this));this.stepOffsets = [0];this.stepsCount = 1;tmpOffset = tmpStep = 0;while(tmpOffset > this.maxOffset) {tmpOffset -= this.getSlideSize(tmpStep, tmpStep + this.options.step);tmpStep += this.options.step;this.stepOffsets.push(Math.max(tmpOffset, this.maxOffset));this.stepsCount++;}}else {this.stepSize = this.maskSize;this.stepsCount = 1;tmpOffset = 0;while(tmpOffset > this.maxOffset) {tmpOffset -= this.stepSize;this.stepsCount++;}}},getSumSize: function() {var sum = 0;this.slides.each($.proxy(function(ind, obj){sum += $(obj)[this.fullSizeFunction](true);},this));this.slider.css(this.innerSizeFunction, sum);return sum;},getStepOffset: function(step) {step = step || this.currentStep;if(typeof this.options.step === 'number') {return this.stepOffsets[this.currentStep];} else {return Math.min(0, Math.max(-this.currentStep * this.stepSize, this.maxOffset));}},getSlideSize: function(i1, i2) {var sum = 0;for(var i = i1; i < Math.min(i2, this.slideDimensions.length); i++) {sum += this.slideDimensions[i];}return sum;},buildPagination: function() {if(typeof this.options.generatePagination === 'string') {if(!this.pagerHolder) {this.pagerHolder = this.gallery.find(this.options.generatePagination);}if(this.pagerHolder.length && this.oldStepsCount != this.stepsCount) {this.oldStepsCount = this.stepsCount;this.pagerHolder.empty();this.pagerList = $(this.options.pagerList).appendTo(this.pagerHolder);for(var i = 0; i < this.stepsCount; i++) {$(this.options.pagerListItem).appendTo(this.pagerList).find(this.options.pagerListItemText).text(i+1);}this.pagerLinks = this.pagerList.children();this.attachPaginationEvents();}}},attachPaginationEvents: function() {var self = this;this.pagerLinksHandler = function(e) {e.preventDefault();self.numSlide(self.pagerLinks.index(e.currentTarget));};this.pagerLinks.bind(this.options.event, this.pagerLinksHandler);},prevSlide: function() {if(!(this.options.disableWhileAnimating && this.galleryAnimating)) {if(this.currentStep > 0) {this.currentStep--;this.switchSlide();} else if(this.options.circularRotation) {this.currentStep = this.stepsCount - 1;this.switchSlide();}}},nextSlide: function(fromAutoRotation) {if(!(this.options.disableWhileAnimating && this.galleryAnimating)) {if(this.currentStep < this.stepsCount - 1) {this.currentStep++;this.switchSlide();} else if(this.options.circularRotation || fromAutoRotation === true) {this.currentStep = 0;this.switchSlide();}}},numSlide: function(c) {if(this.currentStep != c) {this.currentStep = c;this.switchSlide();}},switchSlide: function() {var self = this;this.galleryAnimating = true;this.tmpProps = {};this.tmpProps[this.animProperty] = this.getStepOffset();this.slider.stop().animate(this.tmpProps, {duration: this.options.animSpeed, complete: function(){self.galleryAnimating = false;if(self.resizeQueue) {self.onWindowResize();}self.makeCallback('onChange', self);self.autoRotate();}});this.refreshState();this.makeCallback('onBeforeChange', this);},refreshState: function(initial) {if(this.options.step === 1 || this.stepsCount === this.slides.length) {this.slides.removeClass(this.options.activeClass).eq(this.currentStep).addClass(this.options.activeClass);}this.pagerLinks.removeClass(this.options.activeClass).eq(this.currentStep).addClass(this.options.activeClass);this.curNum.html(this.currentStep+1);this.allNum.html(this.stepsCount);if(this.options.maskAutoSize && typeof this.options.step === 'number') {this.tmpProps = {};this.tmpProps[this.maskSizeProperty] = this.slides.eq(Math.min(this.currentStep,this.slides.length-1))[this.slideSizeFunction](true);this.mask.stop()[initial ? 'css' : 'animate'](this.tmpProps);}if(!this.options.circularRotation) {this.btnPrev.add(this.btnNext).removeClass(this.options.disabledClass);if(this.currentStep === 0) this.btnPrev.addClass(this.options.disabledClass);if(this.currentStep === this.stepsCount - 1) this.btnNext.addClass(this.options.disabledClass);}
1981this.gallery.toggleClass('not-enough-slides', this.sumSize <= this.maskSize);},startRotation: function() {this.options.autoRotation = true;this.galleryHover = false;this.autoRotationStopped = false;this.resumeRotation();},stopRotation: function() {this.galleryHover = true;this.autoRotationStopped = true;this.pauseRotation();},pauseRotation: function() {this.gallery.addClass(this.options.autorotationDisabledClass);this.gallery.removeClass(this.options.autorotationActiveClass);clearTimeout(this.timer);},resumeRotation: function() {if(!this.autoRotationStopped) {this.gallery.addClass(this.options.autorotationActiveClass);this.gallery.removeClass(this.options.autorotationDisabledClass);this.autoRotate();}},autoRotate: function() {var self = this;clearTimeout(this.timer);if(this.options.autoRotation && !this.galleryHover && !this.autoRotationStopped) {this.timer = setTimeout(function(){self.nextSlide(true);}, this.options.switchTime);} else {this.pauseRotation();}},bindHandlers: function(handlersList) {var self = this;$.each(handlersList, function(index, handler) {var origHandler = self[handler];self[handler] = function() {return origHandler.apply(self, arguments);};});},makeCallback: function(name) {if(typeof this.options[name] === 'function') {var args = Array.prototype.slice.call(arguments);args.shift();this.options[name].apply(this, args);}}};var isTouchDevice = /Windows Phone/.test(navigator.userAgent) || ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;$.fn.scrollGallery = function(opt){return this.each(function(){$(this).data('ScrollGallery', new ScrollGallery($.extend(opt,{holder:this})));});};}(jQuery)); 1982 1983 1984 1985/* 1986 1987 * jQuery Cycle Carousel plugin 1988 1989 */ 1990 1991;(function($){function ScrollAbsoluteGallery(options) {this.options = $.extend({activeClass: 'active',mask: 'div.slides-mask',slider: '>ul',slides: '>li',btnPrev: '.btn-prev',btnNext: '.btn-next',pagerLinks: 'ul.pager > li',generatePagination: false,pagerList: '<ul>',pagerListItem: '<li><a href="#"></a></li>',pagerListItemText: 'a',galleryReadyClass: 'gallery-js-ready',currentNumber: 'span.current-num',totalNumber: 'span.total-num',maskAutoSize: false,autoRotation: false,pauseOnHover: false,stretchSlideToMask: false,switchTime: 3000,animSpeed: 500,handleTouch: true,swipeThreshold: 15,vertical: false}, options);this.init();}ScrollAbsoluteGallery.prototype = {init: function() {if(this.options.holder) {this.findElements();this.attachEvents();this.makeCallback('onInit', this);}},findElements: function() {this.holder = $(this.options.holder).addClass(this.options.galleryReadyClass);this.mask = this.holder.find(this.options.mask);this.slider = this.mask.find(this.options.slider);this.slides = this.slider.find(this.options.slides);this.btnPrev = this.holder.find(this.options.btnPrev);this.btnNext = this.holder.find(this.options.btnNext);this.currentNumber = this.holder.find(this.options.currentNumber);this.totalNumber = this.holder.find(this.options.totalNumber);this.updateAttributes();if(typeof this.options.generatePagination === 'string') {this.pagerLinks = this.buildPagination();} else {this.pagerLinks = this.holder.find(this.options.pagerLinks);}this.sizeProperty = this.options.vertical ? 'height' : 'width';this.positionProperty = this.options.vertical ? 'top' : 'left';this.animProperty = this.options.vertical ? 'marginTop' : 'marginLeft';this.slideSize = this.slides[this.sizeProperty]();this.currentIndex = 0;this.prevIndex = 0;this.options.maskAutoSize = this.options.vertical ? false : this.options.maskAutoSize;if(this.options.vertical) {this.mask.css({height: this.slides.innerHeight()});}if(this.options.maskAutoSize){this.mask.css({height: this.slider.height()});}this.slider.css({position: 'relative',height: this.options.vertical ? this.slideSize * this.slides.length : '100%'});this.slides.css({position: 'absolute'}).css(this.positionProperty, -9999).eq(this.currentIndex).css(this.positionProperty, 0);this.refreshState();},updateAttributes: function() {if(this.holder.attr('data-rotate') === 'true') {this.options.autoRotation = true;}if(this.holder.attr('data-direction') === 'vertical') {this.options.vertical = true;}if(this.holder.attr('data-pause-hover') === 'true') {this.options.pauseOnHover = true;}if(this.holder.attr('data-speed')) {this.options.animSpeed = parseFloat(this.holder.attr('data-speed'));}},buildPagination: function() {var pagerLinks = $();if(!this.pagerHolder) {this.pagerHolder = this.holder.find(this.options.generatePagination);}if(this.pagerHolder.length) {this.pagerHolder.empty();this.pagerList = $(this.options.pagerList).appendTo(this.pagerHolder);for(var i = 0; i < this.slides.length; i++) {$(this.options.pagerListItem).appendTo(this.pagerList).find(this.options.pagerListItemText).text(i+1);}
1991pagerLinks = this.pagerList.children();}return pagerLinks;},updateAttributes: function() {if(this.holder.attr('data-rotate') === 'true') {this.options.autoRotation = true;}if(this.holder.attr('data-direction') === 'vertical') {this.options.vertical = true;}if(this.holder.attr('data-pause-hover') === 'true') {this.options.pauseOnHover = true;}if(this.holder.attr('data-speed')) {this.options.animSpeed = parseFloat(this.holder.attr('data-speed'));}},attachEvents: function() {var self = this;if(this.btnPrev.length) {this.btnPrevHandler = function(e) {e.preventDefault();self.prevSlide();};this.btnPrev.click(this.btnPrevHandler);}if(this.btnNext.length) {this.btnNextHandler = function(e) {e.preventDefault();self.nextSlide();};this.btnNext.click(this.btnNextHandler);}if(this.pagerLinks.length) {this.pagerLinksHandler = function(e) {e.preventDefault();self.numSlide(self.pagerLinks.index(e.currentTarget));};this.pagerLinks.click(this.pagerLinksHandler);}if(this.options.pauseOnHover) {this.hoverHandler = function() {clearTimeout(self.timer);};this.leaveHandler = function() {self.autoRotate();};this.holder.bind({mouseenter: this.hoverHandler, mouseleave: this.leaveHandler});}this.resizeHandler = function() {if(!self.animating) {if(self.options.stretchSlideToMask) {self.resizeSlides();}self.resizeHolder();self.setSlidesPosition(self.currentIndex);}};$(window).bind('load resize orientationchange', this.resizeHandler);if(self.options.stretchSlideToMask) {self.resizeSlides();}if(this.options.handleTouch && window.Hammer && this.mask.length && this.slides.length > 1 && isTouchDevice) {this.swipeHandler = new Hammer.Manager(this.mask[0]);this.swipeHandler.add(new Hammer.Pan({direction: self.options.vertical ? Hammer.DIRECTION_VERTICAL : Hammer.DIRECTION_HORIZONTAL,threshold: self.options.swipeThreshold}));this.swipeHandler.on('panstart', function() {if(self.animating) {self.swipeHandler.stop();} else {clearTimeout(self.timer);}}).on('panmove', function(e) {self.swipeOffset = -self.slideSize + e[self.options.vertical ? 'deltaY' : 'deltaX'];self.slider.css(self.animProperty, self.swipeOffset);clearTimeout(self.timer);}).on('panend', function(e) {if(e.distance > self.options.swipeThreshold) {if(e.offsetDirection === Hammer.DIRECTION_RIGHT || e.offsetDirection === Hammer.DIRECTION_DOWN) {self.nextSlide();} else {self.prevSlide();}} else {var tmpObj = {};tmpObj[self.animProperty] = -self.slideSize;self.slider.animate(tmpObj, {duration: self.options.animSpeed});self.autoRotate();}self.swipeOffset = 0;});}this.autoRotate();this.resizeHolder();this.setSlidesPosition(this.currentIndex);},resizeSlides: function() {this.slideSize = this.mask[this.options.vertical ? 'height' : 'width']();this.slides.css(this.sizeProperty, this.slideSize);},resizeHolder: function() {if(this.options.maskAutoSize) {this.mask.css({height: this.slides.eq(this.currentIndex).outerHeight(true)});}},prevSlide: function() {if(!this.animating && this.slides.length > 1) {this.direction = -1;this.prevIndex = this.currentIndex;if(this.currentIndex > 0) this.currentIndex--;else this.currentIndex = this.slides.length - 1;this.switchSlide();}},nextSlide: function(fromAutoRotation) {if(!this.animating && this.slides.length > 1) {this.direction = 1;this.prevIndex = this.currentIndex;if(this.currentIndex < this.slides.length - 1) this.currentIndex++;else this.currentIndex = 0;this.switchSlide();}},numSlide: function(c) {if(!this.animating && this.currentIndex !== c && this.slides.length > 1) {this.direction = c > this.currentIndex ? 1 : -1;this.prevIndex = this.currentIndex;this.currentIndex = c;this.switchSlide();}},preparePosition: function() {this.setSlidesPosition(this.prevIndex, this.direction < 0 ? this.currentIndex : null, this.direction > 0 ? this.currentIndex : null, this.direction);},setSlidesPosition: function(index, slideLeft, slideRight, direction) {if(this.slides.length > 1) {var prevIndex = (typeof slideLeft === 'number' ? slideLeft : index > 0 ? index - 1 : this.slides.length - 1);var nextIndex = (typeof slideRight === 'number' ? slideRight : index < this.slides.length - 1 ? index + 1 : 0);this.slider.css(this.animProperty, this.swipeOffset ? this.swipeOffset : -this.slideSize);this.slides.css(this.positionProperty, -9999).eq(index).css(this.positionProperty, this.slideSize);if(prevIndex === nextIndex && typeof direction === 'number') {var calcOffset = direction > 0 ? this.slideSize*2 : 0;this.slides.eq(nextIndex).css(this.positionProperty, calcOffset);} else {this.slides.eq(prevIndex).css(this.positionProperty, 0);this.slides.eq(nextIndex).css(this.positionProperty, this.slideSize*2);}}},switchSlide: function() {var self = this;var oldSlide = this.slides.eq(this.prevIndex);var newSlide = this.slides.eq(this.currentIndex);self.hideContent();this.animating = true;if(this.options.maskAutoSize) {this.mask.animate({height: newSlide.outerHeight(true)}, {duration: this.options.animSpeed});}var animProps = {};animProps[this.animProperty] = this.direction > 0 ? -this.slideSize*2 : 0;this.preparePosition();this.slider.animate(animProps,{duration:this.options.animSpeed, complete:function() {self.showContent();self.setSlidesPosition(self.currentIndex);self.animating = false;self.autoRotate();self.makeCallback('onChange', self);}});this.refreshState();this.makeCallback('onBeforeChange', this);},hideContent: function() {$(this.slides.eq(this.currentIndex)).find('.heading2, anim-heading').css({position: 'relative'}).animate({bottom: -50,opacity: 0}, 500);$(this.slides.eq(this.currentIndex)).find('.btn-box').css({position: 'relative'}).animate({bottom: -50,opacity: 0}, 500);$(this.slides.eq(this.currentIndex)).find('.title2').css({position: 'relative'}).animate({bottom: -50,opacity: 0}, 500);},showContent: function() {$(this.slides.eq(this.currentIndex)).find('.heading2, anim-heading').animate({bottom: 0,opacity: 1}, 700);$(this.slides.eq(this.currentIndex)).find('.btn-box').animate({bottom: 0,opacity: 1}, 700);$(this.slides.eq(this.currentIndex)).find('.title2').animate({bottom: 0,opacity: 1}, 700);},refreshState: function(initial) {this.slides.removeClass(this.options.activeClass).eq(this.currentIndex).addClass(this.options.activeClass);this.pagerLinks.removeClass(this.options.activeClass).eq(this.currentIndex).addClass(this.options.activeClass);this.currentNumber.html(this.currentIndex + 1);this.totalNumber.html(this.slides.length);
1991this.holder.toggleClass('not-enough-slides', this.slides.length === 1);},autoRotate: function() {var self = this;clearTimeout(this.timer);if(this.options.autoRotation) {this.timer = setTimeout(function() {self.nextSlide();}, this.options.switchTime);}},makeCallback: function(name) {if(typeof this.options[name] === 'function') {var args = Array.prototype.slice.call(arguments);args.shift();this.options[name].apply(this, args);}}};var isTouchDevice = /Windows Phone/.test(navigator.userAgent) || ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;$.fn.scrollAbsoluteGallery = function(opt){return this.each(function(){$(this).data('ScrollAbsoluteGallery', new ScrollAbsoluteGallery($.extend(opt,{holder:this})));});};}(jQuery)); 1992 1993 1994 1995/* 1996 1997 * Simple Mobile Navigation 1998 1999 */ 2000 2001;(function($) { 2002 2003 function MobileNav(options) { 2004 2005 this.options = $.extend({ 2006 2007 container: null, 2008 2009 hideOnClickOutside: false, 2010 2011 menuActiveClass: 'nav-active', 2012 2013 menuOpener: '.nav-opener', 2014 2015 menuDrop: '.nav-drop', 2016 2017 toggleEvent: 'click', 2018 2019 outsideClickEvent: 'click touchstart pointerdown MSPointerDown' 2020 2021 }, options); 2022 2023 this.initStructure(); 2024 2025 this.attachEvents(); 2026 2027 } 2028 2029 MobileNav.prototype = { 2030 2031 initStructure: function() { 2032 2033 this.page = $('html'); 2034 2035 this.container = $(this.options.container); 2036 2037 this.opener = this.container.find(this.options.menuOpener); 2038 2039 this.drop = this.container.find(this.options.menuDrop); 2040 2041 }, 2042 2043 attachEvents: function() { 2044 2045 var self = this; 2046 2047 2048 2049 if(activateResizeHandler) { 2050 2051 activateResizeHandler(); 2052 2053 activateResizeHandler = null; 2054 2055 } 2056 2057 2058 2059 this.outsideClickHandler = function(e) { 2060 2061 if(self.isOpened()) { 2062 2063 var target = $(e.target); 2064 2065 if(!target.closest(self.opener).length && !target.closest(self.drop).length) { 2066 2067 self.hide(); 2068 2069 } 2070 2071 } 2072 2073 }; 2074 2075 2076 2077 this.openerClickHandler = function(e) { 2078 2079 e.preventDefault(); 2080 2081 self.toggle(); 2082 2083 }; 2084 2085 2086 2087 this.opener.on(this.options.toggleEvent, this.openerClickHandler); 2088 2089 }, 2090 2091 isOpened: function() { 2092 2093 return this.container.hasClass(this.options.menuActiveClass); 2094 2095 }, 2096 2097 show: function() { 2098 2099 this.container.addClass(this.options.menuActiveClass); 2100 2101 if(this.options.hideOnClickOutside) { 2102 2103 this.page.on(this.options.outsideClickEvent, this.outsideClickHandler); 2104 2105 } 2106 2107 this.makeCallback('onInit', this); 2108 2109 }, 2110 2111 hide: function() { 2112 2113 this.container.removeClass(this.options.menuActiveClass); 2114 2115 if(this.options.hideOnClickOutside) { 2116 2117 this.page.off(this.options.outsideClickEvent, this.outsideClickHandler); 2118 2119 } 2120 2121 this.makeCallback('onHide', this); 2122 2123 }, 2124 2125 toggle: function() { 2126 2127 if(this.isOpened()) { 2128 2129 this.hide(); 2130 2131 } else { 2132 2133 this.show(); 2134 2135 } 2136 2137 }, 2138 2139 makeCallback: function(name) { 2140 2141 if(typeof this.options[name] === 'function') { 2142 2143 var args = Array.prototype.slice.call(arguments); 2144 2145 args.shift(); 2146 2147 this.options[name].apply(this, args); 2148 2149 } 2150 2151 }, 2152 2153 destroy: function() { 2154 2155 this.container.removeClass(this.options.menuActiveClass); 2156 2157 this.opener.off(this.options.toggleEvent, this.clickHandler); 2158 2159 this.page.off(this.options.outsideClickEvent, this.outsideClickHandler); 2160 2161 } 2162 2163 }; 2164 2165 2166 2167 var activateResizeHandler = function() { 2168 2169 var win = $(window), 2170 2171 doc = $('html'), 2172 2173 resizeClass = 'resize-active', 2174 2175 flag, timer; 2176 2177 var removeClassHandler = function() { 2178 2179 flag = false; 2180 2181 doc.removeClass(resizeClass); 2182 2183 }; 2184 2185 var resizeHandler = function() { 2186 2187 if(!flag) { 2188 2189 flag = true; 2190 2191 doc.addClass(resizeClass); 2192 2193 } 2194 2195 clearTimeout(timer); 2196 2197 timer = setTimeout(removeClassHandler, 500); 2198 2199 }; 2200 2201 win.on('resize orientationchange', resizeHandler); 2202 2203 }; 2204 2205 2206 2207 $.fn.mobileNav = function(options) { 2208 2209 return this.each(function() { 2210 2211 var params = $.extend({}, options, {container: this}), 2212 2213 instance = new MobileNav(params); 2214 2215 $.data(this, 'MobileNav', instance); 2216 2217 }); 2218 2219 }; 2220 2221}(jQuery)); 2222 2223 2224 2225/*! http://mths.be/placeholder v2.0.7 by @mathias */ 2226 2227;(function(window, document, $) { 2228 2229 2230 2231 // Opera Mini v7 doesn’t support placeholder although its DOM seems to indicate so 2232 2233 var isOperaMini = Object.prototype.toString.call(window.operamini) == '[object OperaMini]'; 2234 2235 var isInputSupported = 'placeholder' in document.createElement('input') && !isOperaMini; 2236 2237 var isTextareaSupported = 'placeholder' in document.createElement('textarea') && !isOperaMini; 2238 2239 var prototype = $.fn; 2240 2241 var valHooks = $.valHooks; 2242 2243 var propHooks = $.propHooks; 2244 2245 var hooks; 2246 2247 var placeholder; 2248 2249 2250 2251 if (isInputSupported && isTextareaSupported) { 2252 2253 2254 2255 placeholder = prototype.placeholder = function() { 2256 2257 return this; 2258 2259 }; 2260 2261 2262 2263 placeholder.input = placeholder.textarea = true; 2264 2265 2266 2267 } else { 2268 2269 2270 2271 placeholder = prototype.placeholder = function() { 2272 2273 var $this = this; 2274 2275 $this 2276 2277 .filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]') 2278 2279 .not('.placeholder') 2280 2281 .bind({ 2282
2283 'focus.placeholder': clearPlaceholder, 2284 2285 'blur.placeholder': setPlaceholder 2286 2287 }) 2288 2289 .data('placeholder-enabled', true) 2290 2291 .trigger('blur.placeholder'); 2292 2293 return $this; 2294 2295 }; 2296 2297 2298 2299 placeholder.input = isInputSupported; 2300 2301 placeholder.textarea = isTextareaSupported; 2302 2303 2304 2305 hooks = { 2306 2307 'get': function(element) { 2308 2309 var $element = $(element); 2310 2311 2312 2313 var $passwordInput = $element.data('placeholder-password'); 2314 2315 if ($passwordInput) { 2316 2317 return $passwordInput[0].value; 2318 2319 } 2320 2321 2322 2323 return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value; 2324 2325 }, 2326 2327 'set': function(element, value) { 2328 2329 var $element = $(element); 2330 2331 2332 2333 var $passwordInput = $element.data('placeholder-password'); 2334 2335 if ($passwordInput) { 2336 2337 return $passwordInput[0].value = value; 2338 2339 } 2340 2341 2342 2343 if (!$element.data('placeholder-enabled')) { 2344 2345 return element.value = value; 2346 2347 } 2348 2349 if (value == '') { 2350 2351 element.value = value; 2352 2353 // Issue #56: Setting the placeholder causes problems if the element continues to have focus. 2354 2355 if (element != safeActiveElement()) { 2356 2357 // We can't use `triggerHandler` here because of dummy text/password inputs :( 2358 2359 setPlaceholder.call(element); 2360 2361 } 2362 2363 } else if ($element.hasClass('placeholder')) { 2364 2365 clearPlaceholder.call(element, true, value) || (element.value = value); 2366 2367 } else { 2368 2369 element.value = value; 2370 2371 } 2372 2373 // `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363 2374 2375 return $element; 2376 2377 } 2378 2379 }; 2380 2381 2382 2383 if (!isInputSupported) { 2384 2385 valHooks.input = hooks; 2386 2387 propHooks.value = hooks; 2388 2389 } 2390 2391 if (!isTextareaSupported) { 2392 2393 valHooks.textarea = hooks; 2394 2395 propHooks.value = hooks; 2396 2397 } 2398 2399 2400 2401 $(function() { 2402 2403 // Look for forms 2404 2405 $(document).delegate('form', 'submit.placeholder', function() { 2406 2407 // Clear the placeholder values so they don't get submitted 2408 2409 var $inputs = $('.placeholder', this).each(clearPlaceholder); 2410 2411 setTimeout(function() { 2412 2413 $inputs.each(setPlaceholder); 2414 2415 }, 10); 2416 2417 }); 2418 2419 }); 2420 2421 2422 2423 // Clear placeholder values upon page reload 2424 2425 $(window).bind('beforeunload.placeholder', function() { 2426 2427 $('.placeholder').each(function() { 2428 2429 this.value = ''; 2430 2431 }); 2432 2433 }); 2434 2435 2436 2437 } 2438 2439 2440 2441 function args(elem) { 2442 2443 // Return an object of element attributes 2444 2445 var newAttrs = {}; 2446 2447 var rinlinejQuery = /^jQuery\d+$/; 2448 2449 $.each(elem.attributes, function(i, attr) { 2450 2451 if (attr.specified && !rinlinejQuery.test(attr.name)) { 2452 2453 newAttrs[attr.name] = attr.value; 2454 2455 } 2456 2457 }); 2458 2459 return newAttrs; 2460 2461 } 2462 2463 2464 2465 function clearPlaceholder(event, value) { 2466 2467 var input = this; 2468 2469 var $input = $(input); 2470 2471 if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) { 2472 2473 if ($input.data('placeholder-password')) { 2474 2475 $input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id')); 2476 2477 // If `clearPlaceholder` was called from `$.valHooks.input.set` 2478 2479 if (event === true) { 2480 2481 return $input[0].value = value; 2482 2483 } 2484 2485 $input.focus(); 2486 2487 } else { 2488 2489 input.value = ''; 2490 2491 $input.removeClass('placeholder'); 2492 2493 input == safeActiveElement() && input.select(); 2494 2495 } 2496 2497 } 2498 2499 } 2500 2501 2502 2503 function setPlaceholder() { 2504 2505 var $replacement; 2506 2507 var input = this; 2508 2509 var $input = $(input); 2510 2511 var id = this.id; 2512 2513 if (input.value == '') { 2514 2515 if (input.type == 'password') { 2516 2517 if (!$input.data('placeholder-textinput')) { 2518 2519 try { 2520 2521 $replacement = $input.clone().attr({ 'type': 'text' }); 2522 2523 } catch(e) { 2524 2525 $replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' })); 2526 2527 } 2528 2529 $replacement 2530 2531 .removeAttr('name') 2532 2533 .data({ 2534 2535 'placeholder-password': $input, 2536 2537 'placeholder-id': id 2538 2539 }) 2540 2541 .bind('focus.placeholder', clearPlaceholder); 2542 2543 $input 2544 2545 .data({ 2546 2547 'placeholder-textinput': $replacement, 2548 2549 'placeholder-id': id 2550 2551 }) 2552 2553 .before($replacement); 2554 2555 } 2556 2557 $input = $input.removeAttr('id').hide().prev().attr('id', id).show(); 2558 2559 // Note: `$input[0] != input` now! 2560 2561 } 2562 2563 $input.addClass('placeholder'); 2564 2565 $input[0].value = $input.attr('placeholder'); 2566 2567 } else { 2568 2569 $input.removeClass('placeholder'); 2570 2571 } 2572 2573 } 2574 2575 2576 2577 function safeActiveElement() { 2578 2579 // Avoid IE9 `document.activeElement` of death 2580 2581 // https://github.com/mathiasbynens/jquery-placeholder/pull/99 2582 2583 try { 2584 2585 return document.activeElement; 2586 2587 } catch (err) {} 2588 2589 } 2590 2591 2592 2593}(this, document, jQuery)); 2594 2595 2596 2597/* 2598 2599 * Window Height CSS rules 2600 2601 */ 2602 2603;(function() { 2604 2605 var styleSheet; 2606 2607 2608 2609 var getWindowHeight = function() { 2610 2611 return window.innerHeight || document.documentElement.clientHeight; 2612 2613 }; 2614 2615 2616 2617 var createStyleTag = function() { 2618 2619 // create style tag 2620 2621 var styleTag = jQuery('<style>').appendTo('head'); 2622 2623 styleSheet = styleTag.prop('sheet') || styleTag.prop('styleSheet'); 2624 2625 2626 2627 // crossbrowser style handling 2628 2629 var addCSSRule = function(selector, rules, index) { 2630 2631 if(styleSheet.insertRule) { 2632 2633 styleSheet.insertRule(selector + '{' + rules + '}', index); 2634 2635 } else { 2636 2637 styleSheet.addRule(selector, rules, index); 2638 2639 } 2640 2641 }; 2642 2643 2644 2645 // create style rules 2646
2647 addCSSRule('.win-min-height', 'min-height:0'); 2648 2649 addCSSRule('.win-height', 'height:auto'); 2650 2651 addCSSRule('.win-max-height', 'max-height:100%'); 2652 2653 resizeHandler(); 2654 2655 }; 2656 2657 2658 2659 var resizeHandler = function() { 2660 2661 // handle changes in style rules 2662 2663 var currentWindowHeight = getWindowHeight(), 2664 2665 styleRules = styleSheet.cssRules || styleSheet.rules; 2666 2667 2668 2669 jQuery.each(styleRules, function(index, currentRule) { 2670 2671 var currentProperty = currentRule.selectorText.toLowerCase().replace('.win-', '').replace('-h','H'); 2672 2673 currentRule.style[currentProperty] = currentWindowHeight + 'px'; 2674 2675 }); 2676 2677 }; 2678 2679 2680 2681 createStyleTag(); 2682 2683 jQuery(window).on('resize orientationchange', resizeHandler); 2684 2685}()); 2686 2687 2688 2689 2690 2691;(function($){ 2692 2693 function ParallaxBG(opt) { 2694 2695 this.options = $.extend({ 2696 2697 parent: '.bg-frame', 2698 2699 image: 'img', 2700 2701 parallaxOffset: 100, 2702 2703 fallbackFunc: function() {} 2704 2705 }, opt); 2706 2707 this.init(); 2708 2709 } 2710 2711 ParallaxBG.prototype = { 2712 2713 init: function() { 2714 2715 if(this.options.holder) { 2716 2717 if(typeof this.options.fallbackFunc == 'function' && (oldIe || isTouchDevice)) { 2718 2719 this.options.fallbackFunc(); 2720 2721 return; 2722 2723 } 2724
2725 this.getStructure(); 2726 2727 this.attachEvents(); 2728 2729 } 2730 2731 }, 2732 2733 getStructure: function() { 2734 2735 this.holder = $(this.options.holder); 2736 2737 this.parent = this.holder.find(this.options.parent); 2738 2739 this.holderHeight = this.holder.height(); 2740 2741 this.holderOffset = this.holder.offset().top; 2742 2743 2744 2745 // generate bg 2746 2747 this.image = this.parent.find(this.options.image).eq(0).css({visibility: 'hidden'}); 2748 2749 this.imageRatio = this.image.attr('width')/this.image.attr('height') || this.image.width()/this.image.height(); 2750 2751 2752 2753 this.parent.css({ 2754 2755 backgroundImage: 'url('+this.image.attr('src')+')', 2756 2757 backgroundRepeat: 'no-repeat', 2758 2759 backgroundAttachment: 'fixed' 2760 2761 }); 2762 2763 2764 2765 this.win = $(window); 2766 2767 this.winHeight = this.win.height(); 2768 2769 this.winWidth = this.win.width(); 2770 2771 this.winScroll = this.win.scrollTop(); 2772 2773 this.bgHeight = this.winHeight + this.options.parallaxOffset; 2774 2775 }, 2776 2777 attachEvents: function() { 2778 2779 var self = this; 2780 2781 this.bindHandlers(['scrollLayout']); 2782 2783 this.bindHandlers(['resizeLayout']); 2784 2785 this.win.bind('scroll', this.scrollLayout).bind('resize load', this.resizeLayout); 2786 2787 2788 2789 // fix load problem 2790 2791 setTimeout(function() { 2792 2793 self.resizeLayout(); 2794 2795 self.win.trigger('scroll'); 2796 2797 }, 500); 2798 2799 }, 2800 2801 resizeLayout: function() { 2802 2803 // get dimensions 2804 2805 this.winHeight = this.win.height(); 2806 2807 this.winWidth = this.win.width(); 2808 2809 this.holderHeight = this.holder.height(); 2810 2811 this.holderOffset = this.holder.offset().top; 2812 2813 2814 2815 this.blockHeight = this.winHeight + this.options.parallaxOffset; 2816 2817 this.currentTop = Math.max(0, this.blockHeight - this.holderHeight); 2818 2819 2820 2821 // get parallax ratio and image ratio state 2822 2823 this.parallaxRatio = this.win.width()/(this.winHeight + this.options.parallaxOffset); 2824 2825 this.ratioState = this.imageRatio <= this.parallaxRatio; 2826 2827 2828 2829 if(this.ratioState) { 2830 2831 this.bgWidth = this.winWidth; 2832 2833 this.bgHeight = this.bgWidth/this.imageRatio; 2834 2835 } else { 2836 2837 this.bgWidth = 'auto'; 2838 2839 this.bgHeight = this.winHeight + this.options.parallaxOffset; 2840 2841 } 2842 2843 2844 2845 this.parent.css({ 2846 2847 paddingBottom: this.currentTop, 2848 2849 backgroundSize: this.bgWidth != 'auto' ? this.bgWidth +'px '+this.bgHeight+'px' : this.bgWidth +' '+this.bgHeight+'px' 2850 2851 }); 2852 2853 this.scrollLayout(); 2854 2855 }, 2856 2857 scrollLayout: function() { 2858 2859 this.winScroll = this.win.scrollTop(); 2860 2861 this.offsetPercentage = Math.max(0, Math.min((this.winScroll + this.winHeight - this.holderOffset)/(this.winHeight + this.holderHeight), 1)).toFixed(4); 2862 2863 2864 2865 if(!!this.ratioState) { 2866 2867 var curPos = '50% ' + ((-parseFloat(this.offsetPercentage)*this.options.parallaxOffset) - (this.bgHeight - this.winHeight)/2)+'px'; 2868 2869 } else { 2870 2871 var curPos = '50% ' + (-parseFloat(this.offsetPercentage)*this.options.parallaxOffset)+'px'; 2872 2873 } 2874 2875 2876 2877 this.parent.css({backgroundPosition: curPos}); 2878 2879 }, 2880 2881 bindHandlers: function(handlersList) { 2882 2883 var self = this; 2884 2885 $.each(handlersList, function(index, handler) { 2886 2887 var origHandler = self[handler]; 2888 2889 self[handler] = function() { 2890 2891 return origHandler.apply(self, arguments); 2892 2893 }; 2894 2895 }); 2896 2897 } 2898 2899 }; 2900 2901 2902 2903 // detect device type 2904 2905 var isTouchDevice = /MSIE 10.*Touch/.test(navigator.userAgent) || ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch; 2906 2907 var oldIe = window.attachEvent && !window.addEventListener; 2908 2909 2910 2911 // jquery parallax plugin 2912 2913 $.fn.parallaxBG = function(opt){ 2914 2915 return this.each(function(){ 2916 2917 new ParallaxBG($.extend(opt,{holder:this})); 2918 2919 }); 2920 2921 }; 2922 2923}(jQuery)); 2924 2925 2926 2927// background stretching 2928 2929function initBgStretch() { 2930 2931 jQuery('.bg-frame').each(function() { 2932 2933 var holder = jQuery(this); 2934 2935 var image = holder.find('img'); 2936 2937 jQuery(window).bind('load resize', function() { 2938 2939 var settings = getProportions(getDimensions(image, holder)); 2940 2941 resizeAll(image, settings); 2942 2943 }); 2944 2945 }); 2946 2947 2948 2949 function getProportions(dimensions) { 2950 2951 var ratio = dimensions.ratio || (dimensions.elementWidth / dimensions.elementHeight); 2952 2953 var slideWidth = dimensions.maskWidth, slideHeight = slideWidth / ratio; 2954 2955 if(slideHeight < dimensions.maskHeight) { 2956 2957 slideHeight = dimensions.maskHeight; 2958 2959 slideWidth = slideHeight * ratio; 2960 2961 } 2962 2963 return { 2964 2965 width: slideWidth, 2966 2967 height: slideHeight, 2968 2969 top: (dimensions.maskHeight - slideHeight) / 2, 2970
2971 left: (dimensions.maskWidth - slideWidth) / 2 2972 2973 } 2974 2975 } 2976 2977 2978 2979 function getDimensions(img, block) { 2980 2981 img.css({ 2982 2983 height: '', 2984 2985 left: '', 2986 2987 top: '', 2988 2989 width: '' 2990 2991 }); 2992 2993 return { 2994 2995 ratio: img.width()/img.height(), 2996 2997 maskWidth: block.width(), 2998 2999 maskHeight: block.outerHeight(true) 3000 3001 }; 3002 3003 } 3004 3005 3006 3007 function resizeAll(img, obj) { 3008 3009 img.css({ 3010 3011 height: obj.height, 3012 3013 left: obj.left, 3014 3015 top: obj.top, 3016 3017 width: obj.width 3018 3019 }); 3020 3021 } 3022 3023} 3024 3025 3026 3027 3028 3029/* 3030 3031 * Image Stretch module 3032 3033 */ 3034 3035var ImageStretcher = { 3036 3037 getDimensions: function(data) { 3038 3039 // calculate element coords to fit in mask 3040 3041 var ratio = data.imageRatio || (data.imageWidth / data.imageHeight), 3042 3043 slideWidth = data.maskWidth, 3044 3045 slideHeight = slideWidth / ratio; 3046 3047 3048 3049 if(slideHeight < data.maskHeight) { 3050 3051 slideHeight = data.maskHeight; 3052 3053 slideWidth = slideHeight * ratio; 3054 3055 } 3056 3057 return { 3058 3059 width: slideWidth, 3060 3061 height: slideHeight, 3062 3063 top: (data.maskHeight - slideHeight) / 2, 3064 3065 left: (data.maskWidth - slideWidth) / 2 3066 3067 }; 3068 3069 }, 3070 3071 getRatio: function(image) { 3072 3073 if(image.prop('naturalWidth')) { 3074 3075 return image.prop('naturalWidth') / image.prop('naturalHeight'); 3076 3077 } else { 3078 3079 var img = new Image(); 3080 3081 img.src = image.prop('src'); 3082 3083 return img.width / img.height; 3084 3085 } 3086 3087 }, 3088 3089 imageLoaded: function(image, callback) { 3090 3091 var self = this; 3092 3093 var loadHandler = function() { 3094 3095 callback.call(self); 3096 3097 }; 3098 3099 if(image.prop('complete')) { 3100 3101 loadHandler(); 3102 3103 } else { 3104 3105 image.one('load', loadHandler); 3106 3107 } 3108 3109 }, 3110 3111 resizeHandler: function() { 3112 3113 var self = this; 3114 3115 jQuery.each(this.imgList, function(index, item) { 3116 3117 if(item.image.prop('complete')) { 3118 3119 self.resizeImage(item.image, item.container); 3120 3121 } 3122 3123 }); 3124 3125 }, 3126 3127 resizeImage: function(image, container) { 3128 3129 this.imageLoaded(image, function() { 3130 3131 var styles = this.getDimensions({ 3132 3133 imageRatio: this.getRatio(image), 3134 3135 maskWidth: container.width(), 3136 3137 maskHeight: container.height() 3138 3139 }); 3140 3141 image.css({ 3142 3143 width: styles.width, 3144 3145 height: styles.height, 3146 3147 marginTop: styles.top, 3148 3149 marginLeft: styles.left 3150 3151 }); 3152 3153 }); 3154 3155 }, 3156 3157 add: function(options) { 3158 3159 var container = jQuery(options.container ? options.container : window), 3160 3161 image = typeof options.image === 'string' ? container.find(options.image) : jQuery(options.image); 3162 3163 3164 3165 // resize image 3166 3167 this.resizeImage(image, container); 3168 3169 3170 3171 // add resize handler once if needed 3172 3173 if(!this.win) { 3174 3175 this.resizeHandler = jQuery.proxy(this.resizeHandler, this); 3176 3177 this.imgList = []; 3178 3179 this.win = jQuery(window); 3180 3181 this.win.on('resize orientationchange', this.resizeHandler); 3182 3183 } 3184 3185 3186 3187 // store item in collection 3188 3189 this.imgList.push({ 3190 3191 container: container, 3192 3193 image: image 3194 3195 }); 3196 3197 } 3198 3199}; 3200 3201 3202 3203/* 3204 3205 * jQuery SlideShow plugin 3206 3207 */ 3208 3209;(function($){function FadeGallery(options) {this.options = $.extend({slides: 'ul.slideset > li',activeClass:'active',disabledClass:'disabled',btnPrev: 'a.btn-prev',btnNext: 'a.btn-next',generatePagination: false,pagerList: '<ul>',pagerListItem: '<li><a href="#"></a></li>',pagerListItemText: 'a',pagerLinks: '.pagination li',currentNumber: 'span.current-num',totalNumber: 'span.total-num',btnPlay: '.btn-play',btnPause: '.btn-pause',btnPlayPause: '.btn-play-pause',galleryReadyClass: 'gallery-js-ready',autorotationActiveClass: 'autorotation-active',autorotationDisabledClass: 'autorotation-disabled',autorotationStopAfterClick: false,circularRotation: true,switchSimultaneously: true,disableWhileAnimating: false,disableFadeIE: false,autoRotation: false,pauseOnHover: false,autoHeight: false,useSwipe: false,swipeThreshold: 15,switchTime: 4000,animSpeed: 600,event:'click'}, options);this.init();}FadeGallery.prototype = {init: function() {if(this.options.holder) {this.findElements();this.attachEvents();this.refreshState(true);this.autoRotate();this.makeCallback('onInit', this);}},findElements: function() {this.gallery = $(this.options.holder).addClass(this.options.galleryReadyClass);this.slides = this.gallery.find(this.options.slides);this.slidesHolder = this.slides.eq(0).parent();this.stepsCount = this.slides.length;this.btnPrev = this.gallery.find(this.options.btnPrev);this.btnNext = this.gallery.find(this.options.btnNext);this.currentIndex = 0;
3209if(this.options.disableFadeIE && !$.support.opacity) {this.options.animSpeed = 0;}if(typeof this.options.generatePagination === 'string') {this.pagerHolder = this.gallery.find(this.options.generatePagination).empty();this.pagerList = $(this.options.pagerList).appendTo(this.pagerHolder);for(var i = 0; i < this.stepsCount; i++) {$(this.options.pagerListItem).appendTo(this.pagerList).find(this.options.pagerListItemText).text(i+1);}this.pagerLinks = this.pagerList.children();} else {this.pagerLinks = this.gallery.find(this.options.pagerLinks);}var activeSlide = this.slides.filter('.'+this.options.activeClass);if(activeSlide.length) {this.currentIndex = this.slides.index(activeSlide);}this.prevIndex = this.currentIndex;this.btnPlay = this.gallery.find(this.options.btnPlay);this.btnPause = this.gallery.find(this.options.btnPause);this.btnPlayPause = this.gallery.find(this.options.btnPlayPause);this.curNum = this.gallery.find(this.options.currentNumber);this.allNum = this.gallery.find(this.options.totalNumber);this.slides.css({display:'block',opacity:0}
3209).eq(this.currentIndex).css({opacity:''});},updateAttributes: function() {if(this.holder.attr('data-rotate') === 'true') {this.options.autoRotation = true;}if(this.holder.attr('data-direction') === 'vertical') {this.options.vertical = true;}if(this.holder.attr('data-pause-hover') === 'true') {this.options.pauseOnHover = true;}if(this.holder.attr('data-speed')) {this.options.animSpeed = parseFloat(this.holder.attr('data-speed'));}},attachEvents: function() {var self = this;this.resizeHandler = function() {self.onWindowResize();};$(window).bind('load resize orientationchange', this.resizeHandler);if(this.btnPrev.length) {this.btnPrevHandler = function(e){e.preventDefault();self.prevSlide();if(self.options.autorotationStopAfterClick) {self.stopRotation();}};this.btnPrev.bind(this.options.event, this.btnPrevHandler);}if(this.btnNext.length) {this.btnNextHandler = function(e) {e.preventDefault();self.nextSlide();if(self.options.autorotationStopAfterClick) {self.stopRotation();}};this.btnNext.bind(this.options.event, this.btnNextHandler);}if(this.pagerLinks.length) {this.pagerLinksHandler = function(e) {e.preventDefault();self.numSlide(self.pagerLinks.index(e.currentTarget));if(self.options.autorotationStopAfterClick) {self.stopRotation();}};this.pagerLinks.bind(self.options.event, this.pagerLinksHandler);}if(this.btnPlay.length) {this.btnPlayHandler = function(e) {e.preventDefault();self.startRotation();};this.btnPlay.bind(this.options.event, this.btnPlayHandler);}if(this.btnPause.length) {this.btnPauseHandler = function(e) {e.preventDefault();self.stopRotation();};this.btnPause.bind(this.options.event, this.btnPauseHandler);}if(this.btnPlayPause.length) {this.btnPlayPauseHandler = function(e){e.preventDefault();if(!self.gallery.hasClass(self.options.autorotationActiveClass)) {self.startRotation();} else {self.stopRotation();}};this.btnPlayPause.bind(this.options.event, this.btnPlayPauseHandler);}if(this.options.useSwipe && window.Hammer && isTouchDevice) {this.swipeHandler = new Hammer.Manager(this.gallery[0]);this.swipeHandler.add(new Hammer.Swipe({direction: Hammer.DIRECTION_HORIZONTAL,threshold: self.options.swipeThreshold}));this.swipeHandler.on('swipeleft', function() {self.nextSlide();}).on('swiperight', function() {self.prevSlide();});}if(this.options.pauseOnHover) {this.hoverHandler = function() {if(self.options.autoRotation) {self.galleryHover = true;self.pauseRotation();}};this.leaveHandler = function() {if(self.options.autoRotation) {self.galleryHover = false;self.resumeRotation();}};this.gallery.bind({mouseenter: this.hoverHandler, mouseleave: this.leaveHandler});}},onWindowResize: function(){if(this.options.autoHeight) {this.slidesHolder.css({height: this.slides.eq(this.currentIndex).outerHeight(true) });}},prevSlide: function() {if(!(this.options.disableWhileAnimating && this.galleryAnimating)) {this.prevIndex = this.currentIndex;if(this.currentIndex > 0) {this.currentIndex--;this.switchSlide();} else if(this.options.circularRotation) {this.currentIndex = this.stepsCount - 1;this.switchSlide();}}},nextSlide: function(fromAutoRotation) {if(!(this.options.disableWhileAnimating && this.galleryAnimating)) {this.prevIndex = this.currentIndex;if(this.currentIndex < this.stepsCount - 1) {this.currentIndex++;this.switchSlide();} else if(this.options.circularRotation || fromAutoRotation === true) {this.currentIndex = 0;this.switchSlide();}}},numSlide: function(c) {if(this.currentIndex != c) {this.prevIndex = this.currentIndex;this.currentIndex = c;this.switchSlide();}},switchSlide: function() {var self = this;var oldSlide = this.slides.eq(this.prevIndex);var newSlide = this.slides.eq(this.currentIndex);self.hideContent();this.animating = true;if(this.slides.length > 1) {this.galleryAnimating = true;if(!this.options.animSpeed) {this.slides.eq(this.prevIndex).css({opacity:0});} else {this.slides.eq(this.prevIndex).stop().animate({opacity:0}
3209,{duration: this.options.animSpeed});}this.switchNext = function() {if(!self.options.animSpeed) {self.slides.eq(self.currentIndex).css({opacity:''});} else {self.slides.eq(self.currentIndex).stop().animate({opacity:1},{duration: self.options.animSpeed});}clearTimeout(this.nextTimer);this.nextTimer = setTimeout(function() {self.showContent();self.slides.eq(self.currentIndex).css({opacity:''});self.galleryAnimating = false;self.autoRotate();self.makeCallback('onChange', self);}, self.options.animSpeed);};if(this.options.switchSimultaneously) {self.switchNext();} else {clearTimeout(this.switchTimer);this.switchTimer = setTimeout(function(){self.switchNext();}, this.options.animSpeed);}this.refreshState();this.makeCallback('onBeforeChange', this);}},hideContent: function() {$(this.slides.eq(this.currentIndex)).find('.heading').css({position: 'relative'}).animate({bottom: -50,opacity: 0}, 500);$(this.slides.eq(this.currentIndex)).find('.btn-box').css({position: 'relative'}).animate({bottom: -50,opacity: 0}, 500);$(this.slides.eq(this.currentIndex)).find('.txt').css({position: 'relative'}).animate({bottom: -50,opacity: 0}, 500);},showContent: function() {$(this.slides.eq(this.currentIndex)).find('.heading').animate({bottom: 0,opacity: 1}, 700);$(this.slides.eq(this.currentIndex)).find('.btn-box').animate({bottom: 0,opacity: 1}, 700);$(this.slides.eq(this.currentIndex)).find('.txt').animate({bottom: 0,opacity: 1}, 700);},refreshState: function(initial) {this.slides.removeClass(this.options.activeClass).eq(this.currentIndex).addClass(this.options.activeClass);this.pagerLinks.removeClass(this.options.activeClass).eq(this.currentIndex).addClass(this.options.activeClass);this.curNum.html(this.currentIndex+1);this.allNum.html(this.stepsCount);if(this.options.autoHeight) {if(initial) {this.slidesHolder.css({height: this.slides.eq(this.currentIndex).outerHeight(true) });} else {this.slidesHolder.stop().animate({height: this.slides.eq(this.currentIndex).outerHeight(true)}, {duration: this.options.animSpeed});}}if(!this.options.circularRotation) {this.btnPrev.add(this.btnNext).removeClass(this.options.disabledClass);if(this.currentIndex === 0) this.btnPrev.addClass(this.options.disabledClass);if(this.currentIndex === this.stepsCount - 1) this.btnNext.addClass(this.options.disabledClass);}this.gallery.toggleClass('not-enough-slides', this.stepsCount === 1);},startRotation: function() {this.options.autoRotation = true;this.galleryHover = false;this.autoRotationStopped = false;this.resumeRotation();},stopRotation: function() {this.galleryHover = true;this.autoRotationStopped = true;this.pauseRotation();},pauseRotation: function() {this.gallery.addClass(this.options.autorotationDisabledClass);this.gallery.removeClass(this.options.autorotationActiveClass);clearTimeout(this.timer);},resumeRotation: function() {if(!this.autoRotationStopped) {this.gallery.addClass(this.options.autorotationActiveClass);this.gallery.removeClass(this.options.autorotationDisabledClass);this.autoRotate();}},autoRotate: function() {var self = this;clearTimeout(this.timer);if(this.options.autoRotation && !this.galleryHover && !this.autoRotationStopped) {this.gallery.addClass(this.options.autorotationActiveClass);this.timer = setTimeout(function(){self.nextSlide(true);}, this.options.switchTime);} else {this.pauseRotation();}},makeCallback: function(name) {if(typeof this.options[name] === 'function') {var args = Array.prototype.slice.call(arguments);args.shift();this.options[name].apply(this, args);}}};var isTouchDevice = /Windows Phone/.test(navigator.userAgent) || ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;$.fn.fadeGallery = function(opt){return this.each(function(){$(this).data('FadeGallery', new FadeGallery($.extend(opt,{holder:this})));});};}(jQuery)); 3210 3211 3212 3213/*! 3214 3215 * JavaScript Custom Forms 3216 3217 * 3218 3219 * Copyright 2014-2015 PSD2HTML - http://psd2html.com/jcf 3220 3221 * Released under the MIT license (LICENSE.txt) 3222 3223 * 3224 3225 * Version: 1.1.3 3226 3227 */ 3228 3229;(function(root, factory) { 3230 3231 'use strict'; 3232 3233 if (typeof define === 'function' && define.amd) { 3234 3235 define(['jquery'], factory); 3236 3237 } else if (typeof exports === 'object') { 3238 3239 module.exports = factory(require('jquery')); 3240 3241 } else { 3242
3243 root.jcf = factory(jQuery); 3244 3245 } 3246 3247} 3248 3249(this, function($) { 3250 3251 'use strict'; 3252 3253 3254 3255 // define version 3256 3257 var version = '1.1.3'; 3258 3259 3260 3261 // private variables 3262 3263 var customInstances = []; 3264 3265 3266 3267 // default global options 3268 3269 var commonOptions = { 3270 3271 optionsKey: 'jcf', 3272 3273 dataKey: 'jcf-instance', 3274 3275 rtlClass: 'jcf-rtl', 3276 3277 focusClass: 'jcf-focus', 3278 3279 pressedClass: 'jcf-pressed', 3280 3281 disabledClass: 'jcf-disabled', 3282 3283 hiddenClass: 'jcf-hidden', 3284 3285 resetAppearanceClass: 'jcf-reset-appearance', 3286 3287 unselectableClass: 'jcf-unselectable' 3288 3289 }; 3290 3291 3292 3293 // detect device type 3294 3295 var isTouchDevice = ('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch, 3296 3297 isWinPhoneDevice = /Windows Phone/.test(navigator.userAgent); 3298 3299 commonOptions.isMobileDevice = !!(isTouchDevice || isWinPhoneDevice); 3300 3301 3302 3303 // create global stylesheet if custom forms are used 3304 3305 var createStyleSheet = function() { 3306 3307 var styleTag = $('<style>').appendTo('head'), 3308 3309 styleSheet = styleTag.prop('sheet') || styleTag.prop('styleSheet'); 3310 3311 3312 3313 // crossbrowser style handling 3314 3315 var addCSSRule = function(selector, rules, index) { 3316 3317 if (styleSheet.insertRule) { 3318 3319 styleSheet.insertRule(selector + '{' + rules + '}', index); 3320 3321 } else { 3322 3323 styleSheet.addRule(selector, rules, index); 3324 3325 } 3326 3327 }; 3328 3329 3330 3331 // add special rules 3332 3333 addCSSRule('.' + commonOptions.hiddenClass, 'position:absolute !important;left:-9999px !important;height:1px !important;width:1px !important;margin:0 !important;border-width:0 !important;-webkit-appearance:none;-moz-appearance:none;appearance:none'); 3334 3335 addCSSRule('.' + commonOptions.rtlClass + ' .' + commonOptions.hiddenClass, 'right:-9999px !important; left: auto !important'); 3336 3337 addCSSRule('.' + commonOptions.unselectableClass, '-webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-tap-highlight-color: rgba(0,0,0,0);'); 3338 3339 addCSSRule('.' + commonOptions.resetAppearanceClass, 'background: none; border: none; -webkit-appearance: none; appearance: none; opacity: 0; filter: alpha(opacity=0);'); 3340 3341 3342 3343 // detect rtl pages 3344 3345 var html = $('html'), body = $('body'); 3346 3347 if (html.css('direction') === 'rtl' || body.css('direction') === 'rtl') { 3348 3349 html.addClass(commonOptions.rtlClass); 3350 3351 } 3352 3353 3354 3355 // handle form reset event 3356 3357 html.on('reset', function() { 3358 3359 setTimeout(function() { 3360 3361 api.refreshAll(); 3362 3363 }, 0); 3364 3365 }); 3366 3367 3368 3369 // mark stylesheet as created 3370 3371 commonOptions.styleSheetCreated = true; 3372 3373 }; 3374 3375 3376 3377 // simplified pointer events handler 3378 3379 (function() { 3380 3381 var pointerEventsSupported = navigator.pointerEnabled || navigator.msPointerEnabled, 3382 3383 touchEventsSupported = ('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch, 3384 3385 eventList, eventMap = {}, eventPrefix = 'jcf-'; 3386 3387 3388 3389 // detect events to attach 3390 3391 if (pointerEventsSupported) { 3392 3393 eventList = { 3394 3395 pointerover: navigator.pointerEnabled ? 'pointerover' : 'MSPointerOver', 3396 3397 pointerdown: navigator.pointerEnabled ? 'pointerdown' : 'MSPointerDown', 3398 3399 pointermove: navigator.pointerEnabled ? 'pointermove' : 'MSPointerMove', 3400 3401 pointerup: navigator.pointerEnabled ? 'pointerup' : 'MSPointerUp' 3402 3403 }; 3404 3405 } else { 3406 3407 eventList = { 3408 3409 pointerover: 'mouseover', 3410 3411 pointerdown: 'mousedown' + (touchEventsSupported ? ' touchstart' : ''), 3412 3413 pointermove: 'mousemove' + (touchEventsSupported ? ' touchmove' : ''), 3414 3415 pointerup: 'mouseup' + (touchEventsSupported ? ' touchend' : '') 3416 3417 }; 3418 3419 } 3420 3421 3422 3423 // create event map 3424 3425 $.each(eventList, function(targetEventName, fakeEventList) { 3426 3427 $.each(fakeEventList.split(' '), function(index, fakeEventName) { 3428 3429 eventMap[fakeEventName] = targetEventName; 3430 3431 }); 3432 3433 }); 3434 3435 3436 3437 // jQuery event hooks 3438 3439 $.each(eventList, function(eventName, eventHandlers) { 3440 3441 eventHandlers = eventHandlers.split(' '); 3442 3443 $.event.special[eventPrefix + eventName] = { 3444 3445 setup: function() { 3446 3447 var self = this; 3448 3449 $.each(eventHandlers, function(index, fallbackEvent) { 3450 3451 if (self.addEventListener) self.addEventListener(fallbackEvent, fixEvent, false); 3452 3453 else self['on' + fallbackEvent] = fixEvent; 3454 3455 }); 3456 3457 }, 3458 3459 teardown: function() { 3460 3461 var self = this; 3462 3463 $.each(eventHandlers, function(index, fallbackEvent) { 3464 3465 if (self.addEventListener) self.removeEventListener(fallbackEvent, fixEvent, false); 3466 3467 else self['on' + fallbackEvent] = null; 3468 3469 }); 3470 3471 } 3472 3473 }; 3474 3475 }); 3476 3477 3478 3479 // check that mouse event are not simulated by mobile browsers 3480 3481 var lastTouch = null; 3482 3483 var mouseEventSimulated = function(e) { 3484 3485 var dx = Math.abs(e.pageX - lastTouch.x), 3486 3487 dy = Math.abs(e.pageY - lastTouch.y), 3488 3489 rangeDistance = 25; 3490 3491 3492 3493 if (dx <= rangeDistance && dy <= rangeDistance) { 3494 3495 return true; 3496 3497 } 3498 3499 }; 3500 3501 3502 3503 // normalize event 3504 3505 var fixEvent = function(e) { 3506 3507 var origEvent = e || window.event, 3508 3509 touchEventData = null, 3510 3511 targetEventName = eventMap[origEvent.type]; 3512 3513 3514 3515 e = $.event.fix(origEvent); 3516 3517 e.type = eventPrefix + targetEventName; 3518 3519 3520 3521 if (origEvent.pointerType) { 3522 3523 switch (origEvent.pointerType) { 3524 3525 case 2: e.pointerType = 'touch'; break; 3526 3527 case 3: e.pointerType = 'pen'; break; 3528 3529 case 4: e.pointerType = 'mouse'; break; 3530 3531 default: e.pointerType = origEvent.pointerType; 3532 3533 } 3534 3535 } else { 3536 3537 e.pointerType = origEvent.type.substr(0, 5); // "mouse" or "touch" word length 3538 3539 } 3540 3541 3542 3543 if (!e.pageX && !e.pageY) { 3544 3545 touchEventData = origEvent.changedTouches ? origEvent.changedTouches[0] : origEvent; 3546 3547 e.pageX = touchEventData.pageX; 3548 3549 e.pageY = touchEventData.pageY; 3550 3551 } 3552 3553 3554 3555 if (origEvent.type === 'touchend') { 3556 3557 lastTouch = { x: e.pageX, y: e.pageY }; 3558 3559 } 3560 3561 if (e.pointerType === 'mouse' && lastTouch && mouseEventSimulated(e)) { 3562 3563 return; 3564 3565 } else { 3566 3567 return ($.event.dispatch || $.event.handle).call(this, e); 3568 3569 } 3570 3571 }; 3572 3573 }()); 3574 3575 3576 3577 // custom mousewheel/trackpad handler 3578 3579 (function() { 3580 3581 var wheelEvents = ('onwheel' in document || document.documentMode >= 9 ? 'wheel' : 'mousewheel DOMMouseScroll').split(' '), 3582 3583 shimEventName = 'jcf-mousewheel'; 3584 3585 3586 3587 $.event.special[shimEventName] = { 3588 3589 setup: function() { 3590 3591 var self = this; 3592 3593 $.each(wheelEvents, function(index, fallbackEvent) { 3594 3595 if (self.addEventListener) self.addEventListener(fallbackEvent, fixEvent, false); 3596 3597 else self['on' + fallbackEvent] = fixEvent; 3598 3599 }); 3600 3601 }, 3602 3603 teardown: function() { 3604 3605 var self = this; 3606 3607 $.each(wheelEvents, function(index, fallbackEvent) { 3608 3609 if (self.addEventListener) self.removeEventListener(fallbackEvent, fixEvent, false); 3610 3611 else self['on' + fallbackEvent] = null; 3612 3613 }); 3614 3615 } 3616 3617 }; 3618 3619 3620 3621 var fixEvent = function(e) { 3622 3623 var origEvent = e || window.event; 3624 3625 e = $.event.fix(origEvent); 3626 3627 e.type = shimEventName; 3628 3629 3630 3631 // old wheel events handler 3632 3633 if ('detail' in origEvent) { e.deltaY = -origEvent.detail; } 3634 3635 if ('wheelDelta' in origEvent) { e.deltaY = -origEvent.wheelDelta; } 3636 3637 if ('wheelDeltaY' in origEvent) { e.deltaY = -origEvent.wheelDeltaY; } 3638 3639 if ('wheelDeltaX' in origEvent) { e.deltaX = -origEvent.wheelDeltaX; } 3640 3641 3642 3643 // modern wheel event handler 3644 3645 if ('deltaY' in origEvent) { 3646 3647 e.deltaY = origEvent.deltaY; 3648 3649 } 3650 3651 if ('deltaX' in origEvent) { 3652 3653 e.deltaX = origEvent.deltaX; 3654 3655 } 3656 3657 3658 3659 // handle deltaMode for mouse wheel 3660 3661 e.delta = e.deltaY || e.deltaX; 3662 3663 if (origEvent.deltaMode === 1) { 3664 3665 var lineHeight = 16; 3666 3667 e.delta *= lineHeight; 3668 3669 e.deltaY *= lineHeight; 3670 3671 e.deltaX *= lineHeight; 3672 3673 } 3674 3675 3676 3677 return ($.event.dispatch || $.event.handle).call(this, e); 3678 3679 }; 3680 3681 }()); 3682 3683 3684 3685 // extra module methods 3686 3687 var moduleMixin = { 3688 3689 // provide function for firing native events 3690 3691 fireNativeEvent: function(elements, eventName) { 3692 3693 $(elements).each(function() { 3694 3695 var element = this, eventObject; 3696 3697 if (element.dispatchEvent) { 3698 3699 eventObject = document.createEvent('HTMLEvents'); 3700 3701 eventObject.initEvent(eventName, true, true); 3702 3703 element.dispatchEvent(eventObject); 3704 3705 } else if (document.createEventObject) { 3706 3707 eventObject = document.createEventObject(); 3708 3709 eventObject.target = element; 3710 3711 element.fireEvent('on' + eventName, eventObject); 3712 3713 } 3714 3715 }); 3716 3717 }, 3718 3719 // bind event handlers for module instance (functions beggining with "on") 3720 3721 bindHandlers: function() { 3722 3723 var self = this; 3724 3725 $.each(self, function(propName, propValue) { 3726 3727 if (propName.indexOf('on') === 0 && $.isFunction(propValue)) { 3728 3729 // dont use $.proxy here because it doesn't create unique handler 3730 3731 self[propName] = function() { 3732 3733 return propValue.apply(self, arguments); 3734 3735 }; 3736 3737 } 3738 3739 }); 3740 3741 } 3742 3743 }; 3744 3745 3746 3747 // public API 3748 3749 var api = { 3750 3751 version: version, 3752 3753 modules: {}, 3754 3755 getOptions: function() { 3756 3757 return $.extend({}, commonOptions); 3758 3759 }, 3760 3761 setOptions: function(moduleName, moduleOptions) { 3762
3763 if (arguments.length > 1) { 3764 3765 // set module options 3766 3767 if (this.modules[moduleName]) { 3768 3769 $.extend(this.modules[moduleName].prototype.options, moduleOptions); 3770 3771 } 3772 3773 } else { 3774 3775 // set common options 3776 3777 $.extend(commonOptions, moduleName); 3778 3779 } 3780 3781 }, 3782 3783 addModule: function(proto) { 3784 3785 // add module to list 3786 3787 var Module = function(options) { 3788 3789 // save instance to collection 3790 3791 if (!options.element.data(commonOptions.dataKey)) { 3792 3793 options.element.data(commonOptions.dataKey, this); 3794 3795 } 3796 3797 customInstances.push(this); 3798 3799 3800 3801 // save options 3802 3803 this.options = $.extend({}, commonOptions, this.options, getInlineOptions(options.element), options); 3804 3805 3806 3807 // bind event handlers to instance 3808 3809 this.bindHandlers(); 3810 3811 3812 3813 // call constructor 3814 3815 this.init.apply(this, arguments); 3816 3817 }; 3818 3819 3820 3821 // parse options from HTML attribute 3822 3823 var getInlineOptions = function(element) { 3824 3825 var dataOptions = element.data(commonOptions.optionsKey), 3826 3827 attrOptions = element.attr(commonOptions.optionsKey); 3828 3829 3830 3831 if (dataOptions) { 3832 3833 return dataOptions; 3834 3835 } else if (attrOptions) { 3836 3837 try { 3838 3839 return $.parseJSON(attrOptions); 3840 3841 } catch (e) { 3842 3843 // ignore invalid attributes 3844 3845 } 3846 3847 } 3848 3849 }; 3850 3851 3852 3853 // set proto as prototype for new module 3854 3855 Module.prototype = proto; 3856 3857 3858 3859 // add mixin methods to module proto 3860 3861 $.extend(proto, moduleMixin); 3862 3863 if (proto.plugins) { 3864 3865 $.each(proto.plugins, function(pluginName, plugin) { 3866 3867 $.extend(plugin.prototype, moduleMixin); 3868 3869 }); 3870 3871 } 3872 3873 3874 3875 // override destroy method 3876 3877 var originalDestroy = Module.prototype.destroy; 3878 3879 Module.prototype.destroy = function() { 3880 3881 this.options.element.removeData(this.options.dataKey); 3882 3883 3884 3885 for (var i = customInstances.length - 1; i >= 0; i--) { 3886 3887 if (customInstances[i] === this) { 3888 3889 customInstances.splice(i, 1); 3890 3891 break; 3892 3893 } 3894 3895 } 3896 3897 3898 3899 if (originalDestroy) { 3900 3901 originalDestroy.apply(this, arguments); 3902 3903 } 3904 3905 }; 3906 3907 3908 3909 // save module to list 3910 3911 this.modules[proto.name] = Module; 3912 3913 }, 3914 3915 getInstance: function(element) { 3916 3917 return $(element).data(commonOptions.dataKey); 3918 3919 }, 3920 3921 replace: function(elements, moduleName, customOptions) { 3922 3923 var self = this, 3924 3925 instance; 3926 3927 3928 3929 if (!commonOptions.styleSheetCreated) { 3930 3931 createStyleSheet(); 3932 3933 } 3934 3935 3936 3937 $(elements).each(function() { 3938 3939 var moduleOptions, 3940 3941 element = $(this); 3942 3943 3944 3945 instance = element.data(commonOptions.dataKey); 3946 3947 if (instance) { 3948 3949 instance.refresh(); 3950 3951 } else { 3952 3953 if (!moduleName) { 3954 3955 $.each(self.modules, function(currentModuleName, module) { 3956 3957 if (module.prototype.matchElement.call(module.prototype, element)) { 3958 3959 moduleName = currentModuleName; 3960 3961 return false; 3962 3963 } 3964 3965 }); 3966 3967 } 3968 3969 if (moduleName) { 3970 3971 moduleOptions = $.extend({ element: element }, customOptions); 3972 3973 instance = new self.modules[moduleName](moduleOptions); 3974 3975 } 3976 3977 } 3978 3979 }); 3980 3981 return instance; 3982 3983 }, 3984 3985 refresh: function(elements) { 3986 3987 $(elements).each(function() { 3988 3989 var instance = $(this).data(commonOptions.dataKey); 3990 3991 if (instance) { 3992 3993 instance.refresh(); 3994 3995 } 3996 3997 }); 3998 3999 }, 4000 4001 destroy: function(elements) { 4002 4003 $(elements).each(function() { 4004 4005 var instance = $(this).data(commonOptions.dataKey); 4006 4007 if (instance) { 4008 4009 instance.destroy(); 4010 4011 } 4012 4013 }); 4014 4015 }, 4016 4017 replaceAll: function(context) { 4018 4019 var self = this; 4020 4021 $.each(this.modules, function(moduleName, module) { 4022 4023 $(module.prototype.selector, context).each(function() { 4024 4025 if (this.className.indexOf('jcf-ignore') < 0) { 4026 4027 self.replace(this, moduleName); 4028 4029 } 4030 4031 }); 4032 4033 }); 4034 4035 }, 4036 4037 refreshAll: function(context) { 4038 4039 if (context) { 4040 4041 $.each(this.modules, function(moduleName, module) { 4042 4043 $(module.prototype.selector, context).each(function() { 4044 4045 var instance = $(this).data(commonOptions.dataKey); 4046 4047 if (instance) { 4048 4049 instance.refresh(); 4050 4051 } 4052 4053 }); 4054 4055 }); 4056 4057 } else { 4058 4059 for (var i = customInstances.length - 1; i >= 0; i--) { 4060 4061 customInstances[i].refresh(); 4062 4063 } 4064 4065 } 4066 4067 }, 4068 4069 destroyAll: function(context) { 4070 4071 if (context) { 4072 4073 $.each(this.modules, function(moduleName, module) { 4074 4075 $(module.prototype.selector, context).each(function(index, element) { 4076 4077 var instance = $(element).data(commonOptions.dataKey); 4078 4079 if (instance) { 4080 4081 instance.destroy(); 4082 4083 } 4084 4085 }); 4086 4087 }); 4088 4089 } else { 4090 4091 while (customInstances.length) { 4092 4093 customInstances[0].destroy(); 4094 4095 } 4096 4097 } 4098 4099 } 4100 4101 }; 4102 4103 4104 4105 // always export API to the global window object 4106 4107 window.jcf = api; 4108 4109 4110 4111 return api; 4112 4113})); 4114 4115 4116 4117/*! 4118 4119 * JavaScript Custom Forms : Scrollbar Module 4120 4121 * 4122 4123 * Copyright 2014-2015 PSD2HTML - http://psd2html.com/jcf 4124 4125 * Released under the MIT license (LICENSE.txt) 4126 4127 * 4128 4129 * Version: 1.1.3 4130 4131 */ 4132 4133;(function($, window) { 4134 4135 'use strict'; 4136 4137 4138 4139 jcf.addModule({ 4140 4141 name: 'Scrollable', 4142 4143 selector: '.jcf-scrollable', 4144 4145 plugins: { 4146 4147 ScrollBar: ScrollBar 4148 4149 }, 4150 4151 options: { 4152 4153 mouseWheelStep: 150, 4154 4155 handleResize: true, 4156 4157 alwaysShowScrollbars: false, 4158 4159 alwaysPreventMouseWheel: false, 4160 4161 scrollAreaStructure: '<div class="jcf-scrollable-wrapper"></div>' 4162 4163 }, 4164 4165 matchElement: function(element) { 4166 4167 return element.is('.jcf-scrollable'); 4168 4169 }, 4170 4171 init: function() { 4172 4173 this.initStructure(); 4174 4175 this.attachEvents(); 4176 4177 this.rebuildScrollbars(); 4178 4179 }, 4180 4181 initStructure: function() { 4182 4183 // prepare structure 4184 4185 this.doc = $(document); 4186 4187 this.win = $(window); 4188 4189 this.realElement = $(this.options.element); 4190 4191 this.scrollWrapper = $(this.options.scrollAreaStructure).insertAfter(this.realElement); 4192 4193 4194 4195 // set initial styles 4196 4197 this.scrollWrapper.css('position', 'relative'); 4198 4199 this.realElement.css('overflow', 'hidden'); 4200 4201 this.vBarEdge = 0; 4202 4203 }, 4204 4205 attachEvents: function() { 4206 4207 // create scrollbars 4208 4209 var self = this; 4210 4211 this.vBar = new ScrollBar({ 4212 4213 holder: this.scrollWrapper, 4214 4215 vertical: true, 4216 4217 onScroll: function(scrollTop) { 4218 4219 self.realElement.scrollTop(scrollTop); 4220 4221 } 4222 4223 }); 4224 4225 this.hBar = new ScrollBar({ 4226 4227 holder: this.scrollWrapper, 4228 4229 vertical: false, 4230 4231 onScroll: function(scrollLeft) { 4232 4233 self.realElement.scrollLeft(scrollLeft); 4234 4235 } 4236 4237 }); 4238 4239 4240 4241 // add event handlers 4242 4243 this.realElement.on('scroll', this.onScroll); 4244 4245 if (this.options.handleResize) { 4246 4247 this.win.on('resize orientationchange load', this.onResize); 4248 4249 } 4250 4251 4252 4253 // add pointer/wheel event handlers 4254 4255 this.realElement.on('jcf-mousewheel', this.onMouseWheel); 4256
4257 this.realElement.on('jcf-pointerdown', this.onTouchBody); 4258 4259 }, 4260 4261 onScroll: function() { 4262 4263 this.redrawScrollbars(); 4264 4265 }, 4266 4267 onResize: function() { 4268 4269 // do not rebuild scrollbars if form field is in focus 4270 4271 if (!$(document.activeElement).is(':input')) { 4272 4273 this.rebuildScrollbars(); 4274 4275 } 4276 4277 }, 4278 4279 onTouchBody: function(e) { 4280 4281 if (e.pointerType === 'touch') { 4282 4283 this.touchData = { 4284 4285 scrollTop: this.realElement.scrollTop(), 4286 4287 scrollLeft: this.realElement.scrollLeft(), 4288 4289 left: e.pageX, 4290 4291 top: e.pageY 4292 4293 }; 4294 4295 this.doc.on({ 4296 4297 'jcf-pointermove': this.onMoveBody, 4298 4299 'jcf-pointerup': this.onReleaseBody 4300 4301 }); 4302 4303 } 4304 4305 }, 4306 4307 onMoveBody: function(e) { 4308 4309 var targetScrollTop, 4310 4311 targetScrollLeft, 4312 4313 verticalScrollAllowed = this.verticalScrollActive, 4314 4315 horizontalScrollAllowed = this.horizontalScrollActive; 4316 4317 4318 4319 if (e.pointerType === 'touch') { 4320 4321 targetScrollTop = this.touchData.scrollTop - e.pageY + this.touchData.top; 4322 4323 targetScrollLeft = this.touchData.scrollLeft - e.pageX + this.touchData.left; 4324 4325 4326 4327 // check that scrolling is ended and release outer scrolling 4328 4329 if (this.verticalScrollActive && (targetScrollTop < 0 || targetScrollTop > this.vBar.maxValue)) { 4330 4331 verticalScrollAllowed = false; 4332 4333 } 4334 4335 if (this.horizontalScrollActive && (targetScrollLeft < 0 || targetScrollLeft > this.hBar.maxValue)) { 4336 4337 horizontalScrollAllowed = false; 4338 4339 } 4340 4341 4342 4343 this.realElement.scrollTop(targetScrollTop); 4344 4345 this.realElement.scrollLeft(targetScrollLeft); 4346 4347 4348 4349 if (verticalScrollAllowed || horizontalScrollAllowed) { 4350 4351 e.preventDefault(); 4352 4353 } else { 4354 4355 this.onReleaseBody(e); 4356 4357 } 4358 4359 } 4360 4361 }, 4362 4363 onReleaseBody: function(e) { 4364 4365 if (e.pointerType === 'touch') { 4366 4367 delete this.touchData; 4368 4369 this.doc.off({ 4370 4371 'jcf-pointermove': this.onMoveBody, 4372 4373 'jcf-pointerup': this.onReleaseBody 4374 4375 }); 4376 4377 } 4378 4379 }, 4380 4381 onMouseWheel: function(e) { 4382 4383 var currentScrollTop = this.realElement.scrollTop(), 4384 4385 currentScrollLeft = this.realElement.scrollLeft(), 4386 4387 maxScrollTop = this.realElement.prop('scrollHeight') - this.embeddedDimensions.innerHeight, 4388 4389 maxScrollLeft = this.realElement.prop('scrollWidth') - this.embeddedDimensions.innerWidth, 4390 4391 extraLeft, extraTop, preventFlag; 4392 4393 4394 4395 // check edge cases 4396 4397 if (!this.options.alwaysPreventMouseWheel) { 4398 4399 if (this.verticalScrollActive && e.deltaY) { 4400 4401 if (!(currentScrollTop <= 0 && e.deltaY < 0) && !(currentScrollTop >= maxScrollTop && e.deltaY > 0)) { 4402 4403 preventFlag = true; 4404 4405 } 4406 4407 } 4408 4409 if (this.horizontalScrollActive && e.deltaX) { 4410 4411 if (!(currentScrollLeft <= 0 && e.deltaX < 0) && !(currentScrollLeft >= maxScrollLeft && e.deltaX > 0)) { 4412 4413 preventFlag = true; 4414 4415 } 4416 4417 } 4418 4419 if (!this.verticalScrollActive && !this.horizontalScrollActive) { 4420 4421 return; 4422 4423 } 4424 4425 } 4426 4427 4428 4429 // prevent default action and scroll item 4430 4431 if (preventFlag || this.options.alwaysPreventMouseWheel) { 4432 4433 e.preventDefault(); 4434 4435 } else { 4436 4437 return; 4438 4439 } 4440 4441 4442 4443 extraLeft = e.deltaX / 100 * this.options.mouseWheelStep; 4444 4445 extraTop = e.deltaY / 100 * this.options.mouseWheelStep; 4446 4447 4448 4449 this.realElement.scrollTop(currentScrollTop + extraTop); 4450 4451 this.realElement.scrollLeft(currentScrollLeft + extraLeft); 4452 4453 }, 4454 4455 setScrollBarEdge: function(edgeSize) { 4456 4457 this.vBarEdge = edgeSize || 0; 4458 4459 this.redrawScrollbars(); 4460 4461 }, 4462 4463 saveElementDimensions: function() { 4464 4465 this.savedDimensions = { 4466 4467 top: this.realElement.width(), 4468 4469 left: this.realElement.height() 4470 4471 }; 4472 4473 return this; 4474 4475 }, 4476 4477 restoreElementDimensions: function() { 4478 4479 if (this.savedDimensions) { 4480 4481 this.realElement.css({ 4482 4483 width: this.savedDimensions.width, 4484 4485 height: this.savedDimensions.height 4486 4487 }); 4488 4489 } 4490 4491 return this; 4492 4493 }, 4494 4495 saveScrollOffsets: function() { 4496 4497 this.savedOffsets = { 4498 4499 top: this.realElement.scrollTop(), 4500 4501 left: this.realElement.scrollLeft() 4502 4503 }; 4504 4505 return this; 4506 4507 }, 4508 4509 restoreScrollOffsets: function() { 4510 4511 if (this.savedOffsets) { 4512 4513 this.realElement.scrollTop(this.savedOffsets.top); 4514 4515 this.realElement.scrollLeft(this.savedOffsets.left); 4516 4517 } 4518 4519 return this; 4520 4521 }, 4522 4523 getContainerDimensions: function() { 4524 4525 // save current styles 4526 4527 var desiredDimensions, 4528 4529 currentStyles, 4530 4531 currentHeight, 4532 4533 currentWidth; 4534 4535 4536 4537 if (this.isModifiedStyles) { 4538 4539 desiredDimensions = { 4540 4541 width: this.realElement.innerWidth() + this.vBar.getThickness(), 4542
4543 height: this.realElement.innerHeight() + this.hBar.getThickness() 4544 4545 }; 4546 4547 } else { 4548 4549 // unwrap real element and measure it according to CSS 4550 4551 this.saveElementDimensions().saveScrollOffsets(); 4552 4553 this.realElement.insertAfter(this.scrollWrapper); 4554 4555 this.scrollWrapper.detach(); 4556 4557 4558 4559 // measure element 4560 4561 currentStyles = this.realElement.prop('style'); 4562 4563 currentWidth = parseFloat(currentStyles.width); 4564 4565 currentHeight = parseFloat(currentStyles.height); 4566 4567 4568 4569 // reset styles if needed 4570 4571 if (this.embeddedDimensions && currentWidth && currentHeight) { 4572 4573 this.isModifiedStyles |= (currentWidth !== this.embeddedDimensions.width || currentHeight !== this.embeddedDimensions.height); 4574 4575 this.realElement.css({ 4576 4577 overflow: '', 4578 4579 width: '', 4580 4581 height: '' 4582 4583 }); 4584 4585 } 4586 4587 4588 4589 // calculate desired dimensions for real element 4590 4591 desiredDimensions = { 4592 4593 width: this.realElement.outerWidth(), 4594 4595 height: this.realElement.outerHeight() 4596 4597 }; 4598 4599 4600 4601 // restore structure and original scroll offsets 4602 4603 this.scrollWrapper.insertAfter(this.realElement); 4604 4605 this.realElement.css('overflow', 'hidden').prependTo(this.scrollWrapper); 4606 4607 this.restoreElementDimensions().restoreScrollOffsets(); 4608 4609 } 4610 4611 4612 4613 return desiredDimensions; 4614 4615 }, 4616 4617 getEmbeddedDimensions: function(dimensions) { 4618 4619 // handle scrollbars cropping 4620 4621 var fakeBarWidth = this.vBar.getThickness(), 4622 4623 fakeBarHeight = this.hBar.getThickness(), 4624 4625 paddingWidth = this.realElement.outerWidth() - this.realElement.width(), 4626 4627 paddingHeight = this.realElement.outerHeight() - this.realElement.height(), 4628 4629 resultDimensions; 4630 4631 4632 4633 if (this.options.alwaysShowScrollbars) { 4634 4635 // simply return dimensions without custom scrollbars 4636 4637 this.verticalScrollActive = true; 4638 4639 this.horizontalScrollActive = true; 4640 4641 resultDimensions = { 4642 4643 innerWidth: dimensions.width - fakeBarWidth, 4644 4645 innerHeight: dimensions.height - fakeBarHeight 4646 4647 }; 4648 4649 } else { 4650 4651 // detect when to display each scrollbar 4652 4653 this.saveElementDimensions(); 4654 4655 this.verticalScrollActive = false; 4656 4657 this.horizontalScrollActive = false; 4658 4659 4660 4661 // fill container with full size 4662 4663 this.realElement.css({ 4664 4665 width: dimensions.width - paddingWidth, 4666 4667 height: dimensions.height - paddingHeight 4668 4669 }); 4670 4671 4672 4673 this.horizontalScrollActive = this.realElement.prop('scrollWidth') > this.containerDimensions.width; 4674 4675 this.verticalScrollActive = this.realElement.prop('scrollHeight') > this.containerDimensions.height; 4676 4677 4678 4679 this.restoreElementDimensions(); 4680 4681 resultDimensions = { 4682 4683 innerWidth: dimensions.width - (this.verticalScrollActive ? fakeBarWidth : 0), 4684 4685 innerHeight: dimensions.height - (this.horizontalScrollActive ? fakeBarHeight : 0) 4686 4687 }; 4688 4689 } 4690 4691 $.extend(resultDimensions, { 4692 4693 width: resultDimensions.innerWidth - paddingWidth, 4694 4695 height: resultDimensions.innerHeight - paddingHeight 4696 4697 }); 4698 4699 return resultDimensions; 4700 4701 }, 4702 4703 rebuildScrollbars: function() { 4704 4705 // resize wrapper according to real element styles 4706 4707 this.containerDimensions = this.getContainerDimensions(); 4708 4709 this.embeddedDimensions = this.getEmbeddedDimensions(this.containerDimensions); 4710 4711 4712 4713 // resize wrapper to desired dimensions 4714 4715 this.scrollWrapper.css({ 4716 4717 width: this.containerDimensions.width, 4718 4719 height: this.containerDimensions.height 4720 4721 }); 4722 4723 4724 4725 // resize element inside wrapper excluding scrollbar size 4726 4727 this.realElement.css({ 4728 4729 overflow: 'hidden', 4730 4731 width: this.embeddedDimensions.width, 4732 4733 height: this.embeddedDimensions.height 4734 4735 }); 4736 4737 4738 4739 // redraw scrollbar offset 4740 4741 this.redrawScrollbars(); 4742 4743 }, 4744 4745 redrawScrollbars: function() { 4746 4747 var viewSize, maxScrollValue; 4748 4749 4750 4751 // redraw vertical scrollbar 4752 4753 if (this.verticalScrollActive) { 4754 4755 viewSize = this.vBarEdge ? this.containerDimensions.height - this.vBarEdge : this.embeddedDimensions.innerHeight; 4756 4757 maxScrollValue = Math.max(this.realElement.prop('offsetHeight'), this.realElement.prop('scrollHeight')) - this.vBarEdge; 4758 4759 4760 4761 this.vBar.show().setMaxValue(maxScrollValue - viewSize).setRatio(viewSize / maxScrollValue).setSize(viewSize); 4762 4763 this.vBar.setValue(this.realElement.scrollTop()); 4764 4765 } else { 4766 4767 this.vBar.hide(); 4768 4769 } 4770 4771 4772 4773 // redraw horizontal scrollbar 4774 4775 if (this.horizontalScrollActive) { 4776 4777 viewSize = this.embeddedDimensions.innerWidth; 4778 4779 maxScrollValue = this.realElement.prop('scrollWidth'); 4780 4781 4782 4783 if (maxScrollValue === viewSize) { 4784 4785 this.horizontalScrollActive = false;
4786 4787 } 4788 4789 this.hBar.show().setMaxValue(maxScrollValue - viewSize).setRatio(viewSize / maxScrollValue).setSize(viewSize); 4790 4791 this.hBar.setValue(this.realElement.scrollLeft()); 4792 4793 } else { 4794 4795 this.hBar.hide(); 4796 4797 } 4798 4799 4800 4801 // set "touch-action" style rule 4802 4803 var touchAction = ''; 4804 4805 if (this.verticalScrollActive && this.horizontalScrollActive) { 4806 4807 touchAction = 'none'; 4808 4809 } else if (this.verticalScrollActive) { 4810 4811 touchAction = 'pan-x'; 4812 4813 } else if (this.horizontalScrollActive) { 4814 4815 touchAction = 'pan-y'; 4816 4817 } 4818 4819 this.realElement.css('touchAction', touchAction); 4820 4821 }, 4822 4823 refresh: function() { 4824 4825 this.rebuildScrollbars(); 4826 4827 }, 4828 4829 destroy: function() { 4830 4831 // remove event listeners 4832 4833 this.win.off('resize orientationchange load', this.onResize); 4834 4835 this.realElement.off({ 4836 4837 'jcf-mousewheel': this.onMouseWheel, 4838 4839 'jcf-pointerdown': this.onTouchBody 4840 4841 }); 4842 4843 this.doc.off({ 4844 4845 'jcf-pointermove': this.onMoveBody, 4846 4847 'jcf-pointerup': this.onReleaseBody 4848 4849 }); 4850 4851 4852 4853 // restore structure 4854 4855 this.saveScrollOffsets(); 4856 4857 this.vBar.destroy(); 4858 4859 this.hBar.destroy(); 4860 4861 this.realElement.insertAfter(this.scrollWrapper).css({ 4862 4863 touchAction: '', 4864 4865 overflow: '', 4866 4867 width: '', 4868 4869 height: '' 4870 4871 }); 4872 4873 this.scrollWrapper.remove(); 4874 4875 this.restoreScrollOffsets(); 4876 4877 } 4878 4879 }); 4880 4881 4882 4883 // custom scrollbar 4884 4885 function ScrollBar(options) { 4886 4887 this.options = $.extend({ 4888 4889 holder: null, 4890 4891 vertical: true, 4892 4893 inactiveClass: 'jcf-inactive', 4894 4895 verticalClass: 'jcf-scrollbar-vertical', 4896 4897 horizontalClass: 'jcf-scrollbar-horizontal', 4898 4899 scrollbarStructure: '<div class="jcf-scrollbar"><div class="jcf-scrollbar-dec"></div><div class="jcf-scrollbar-slider"><div class="jcf-scrollbar-handle"></div></div><div class="jcf-scrollbar-inc"></div></div>', 4900 4901 btnDecSelector: '.jcf-scrollbar-dec', 4902 4903 btnIncSelector: '.jcf-scrollbar-inc', 4904 4905 sliderSelector: '.jcf-scrollbar-slider', 4906 4907 handleSelector: '.jcf-scrollbar-handle', 4908 4909 scrollInterval: 300, 4910 4911 scrollStep: 400 // px/sec 4912 4913 }, options); 4914 4915 this.init(); 4916 4917 } 4918 4919 $.extend(ScrollBar.prototype, { 4920 4921 init: function() { 4922 4923 this.initStructure(); 4924 4925 this.attachEvents(); 4926 4927 }, 4928 4929 initStructure: function() { 4930 4931 // define proporties 4932 4933 this.doc = $(document); 4934 4935 this.isVertical = !!this.options.vertical; 4936 4937 this.sizeProperty = this.isVertical ? 'height' : 'width'; 4938 4939 this.fullSizeProperty = this.isVertical ? 'outerHeight' : 'outerWidth'; 4940 4941 this.invertedSizeProperty = this.isVertical ? 'width' : 'height'; 4942 4943 this.thicknessMeasureMethod = 'outer' + this.invertedSizeProperty.charAt(0).toUpperCase() + this.invertedSizeProperty.substr(1); 4944 4945 this.offsetProperty = this.isVertical ? 'top' : 'left'; 4946 4947 this.offsetEventProperty = this.isVertical ? 'pageY' : 'pageX'; 4948 4949 4950 4951 // initialize variables 4952 4953 this.value = this.options.value || 0; 4954 4955 this.maxValue = this.options.maxValue || 0; 4956 4957 this.currentSliderSize = 0; 4958 4959 this.handleSize = 0; 4960 4961 4962 4963 // find elements 4964 4965 this.holder = $(this.options.holder); 4966 4967 this.scrollbar = $(this.options.scrollbarStructure).appendTo(this.holder); 4968 4969 this.btnDec = this.scrollbar.find(this.options.btnDecSelector); 4970 4971 this.btnInc = this.scrollbar.find(this.options.btnIncSelector); 4972 4973 this.slider = this.scrollbar.find(this.options.sliderSelector); 4974 4975 this.handle = this.slider.find(this.options.handleSelector); 4976 4977 4978 4979 // set initial styles 4980 4981 this.scrollbar.addClass(this.isVertical ? this.options.verticalClass : this.options.horizontalClass).css({ 4982 4983 touchAction: this.isVertical ? 'pan-x' : 'pan-y', 4984 4985 position: 'absolute' 4986 4987 }); 4988 4989 this.slider.css({ 4990 4991 position: 'relative' 4992 4993 }); 4994 4995 this.handle.css({ 4996 4997 touchAction: 'none', 4998 4999 position: 'absolute' 5000 5001 }); 5002 5003 }, 5004 5005 attachEvents: function() { 5006 5007 this.bindHandlers(); 5008 5009 this.handle.on('jcf-pointerdown', this.onHandlePress); 5010 5011 this.slider.add(this.btnDec).add(this.btnInc).on('jcf-pointerdown', this.onButtonPress); 5012 5013 }, 5014 5015 onHandlePress: function(e) { 5016 5017 if (e.pointerType === 'mouse' && e.button > 1) { 5018 5019 return; 5020 5021 } else { 5022 5023 e.preventDefault(); 5024 5025 this.handleDragActive = true; 5026 5027 this.sliderOffset = this.slider.offset()[this.offsetProperty]; 5028 5029 this.innerHandleOffset = e[this.offsetEventProperty] - this.handle.offset()[this.offsetProperty]; 5030 5031 5032 5033 this.doc.on('jcf-pointermove', this.onHandleDrag); 5034 5035 this.doc.on('jcf-pointerup', this.onHandleRelease); 5036 5037 } 5038 5039 }, 5040 5041 onHandleDrag: function(e) { 5042 5043 e.preventDefault(); 5044 5045 this.calcOffset = e[this.offsetEventProperty] - this.sliderOffset - this.innerHandleOffset; 5046 5047 this.setValue(this.calcOffset / (this.currentSliderSize - this.handleSize) * this.maxValue); 5048 5049 this.triggerScrollEvent(this.value); 5050 5051 }, 5052 5053 onHandleRelease: function() { 5054 5055 this.handleDragActive = false;
5056 5057 this.doc.off('jcf-pointermove', this.onHandleDrag); 5058 5059 this.doc.off('jcf-pointerup', this.onHandleRelease); 5060 5061 }, 5062 5063 onButtonPress: function(e) { 5064 5065 var direction, clickOffset; 5066 5067 if (e.pointerType === 'mouse' && e.button > 1) { 5068 5069 return; 5070 5071 } else { 5072 5073 e.preventDefault(); 5074 5075 if (!this.handleDragActive) { 5076 5077 if (this.slider.is(e.currentTarget)) { 5078 5079 // slider pressed 5080 5081 direction = this.handle.offset()[this.offsetProperty] > e[this.offsetEventProperty] ? -1 : 1; 5082 5083 clickOffset = e[this.offsetEventProperty] - this.slider.offset()[this.offsetProperty]; 5084 5085 this.startPageScrolling(direction, clickOffset); 5086 5087 } else { 5088 5089 // scrollbar buttons pressed 5090 5091 direction = this.btnDec.is(e.currentTarget) ? -1 : 1; 5092 5093 this.startSmoothScrolling(direction); 5094 5095 } 5096 5097 this.doc.on('jcf-pointerup', this.onButtonRelease); 5098 5099 } 5100 5101 } 5102 5103 }, 5104 5105 onButtonRelease: function() { 5106 5107 this.stopPageScrolling(); 5108 5109 this.stopSmoothScrolling(); 5110 5111 this.doc.off('jcf-pointerup', this.onButtonRelease); 5112 5113 }, 5114 5115 startPageScrolling: function(direction, clickOffset) { 5116 5117 var self = this, 5118 5119 stepValue = direction * self.currentSize; 5120 5121 5122 5123 // limit checker 5124 5125 var isFinishedScrolling = function() { 5126 5127 var handleTop = (self.value / self.maxValue) * (self.currentSliderSize - self.handleSize); 5128 5129 5130 5131 if (direction > 0) { 5132 5133 return handleTop + self.handleSize >= clickOffset; 5134 5135 } else { 5136 5137 return handleTop <= clickOffset; 5138 5139 } 5140 5141 }; 5142 5143 5144 5145 // scroll by page when track is pressed 5146 5147 var doPageScroll = function() { 5148 5149 self.value += stepValue; 5150 5151 self.setValue(self.value); 5152 5153 self.triggerScrollEvent(self.value); 5154 5155 5156 5157 if (isFinishedScrolling()) { 5158 5159 clearInterval(self.pageScrollTimer); 5160 5161 } 5162 5163 }; 5164 5165 5166 5167 // start scrolling 5168 5169 this.pageScrollTimer = setInterval(doPageScroll, this.options.scrollInterval); 5170 5171 doPageScroll(); 5172 5173 }, 5174 5175 stopPageScrolling: function() { 5176 5177 clearInterval(this.pageScrollTimer); 5178 5179 }, 5180 5181 startSmoothScrolling: function(direction) { 5182 5183 var self = this, dt; 5184 5185 this.stopSmoothScrolling(); 5186 5187 5188 5189 // simple animation functions 5190 5191 var raf = window.requestAnimationFrame || function(func) { 5192 5193 setTimeout(func, 16); 5194 5195 }; 5196 5197 var getTimestamp = function() { 5198 5199 return Date.now ? Date.now() : new Date().getTime(); 5200 5201 }; 5202 5203 5204 5205 // set animation limit 5206 5207 var isFinishedScrolling = function() { 5208 5209 if (direction > 0) { 5210 5211 return self.value >= self.maxValue; 5212 5213 } else { 5214 5215 return self.value <= 0; 5216 5217 } 5218 5219 }; 5220 5221 5222 5223 // animation step 5224 5225 var doScrollAnimation = function() { 5226 5227 var stepValue = (getTimestamp() - dt) / 1000 * self.options.scrollStep; 5228 5229 5230 5231 if (self.smoothScrollActive) { 5232 5233 self.value += stepValue * direction; 5234 5235 self.setValue(self.value); 5236 5237 self.triggerScrollEvent(self.value); 5238 5239 5240 5241 if (!isFinishedScrolling()) { 5242 5243 dt = getTimestamp(); 5244 5245 raf(doScrollAnimation); 5246 5247 } 5248 5249 } 5250 5251 }; 5252 5253 5254 5255 // start animation 5256 5257 self.smoothScrollActive = true; 5258 5259 dt = getTimestamp(); 5260 5261 raf(doScrollAnimation); 5262 5263 }, 5264 5265 stopSmoothScrolling: function() { 5266 5267 this.smoothScrollActive = false; 5268 5269 }, 5270 5271 triggerScrollEvent: function(scrollValue) { 5272 5273 if (this.options.onScroll) { 5274 5275 this.options.onScroll(scrollValue); 5276 5277 } 5278 5279 }, 5280 5281 getThickness: function() { 5282 5283 return this.scrollbar[this.thicknessMeasureMethod](); 5284 5285 }, 5286 5287 setSize: function(size) { 5288 5289 // resize scrollbar 5290 5291 var btnDecSize = this.btnDec[this.fullSizeProperty](), 5292 5293 btnIncSize = this.btnInc[this.fullSizeProperty](); 5294 5295 5296 5297 // resize slider 5298 5299 this.currentSize = size; 5300 5301 this.currentSliderSize = size - btnDecSize - btnIncSize; 5302 5303 this.scrollbar.css(this.sizeProperty, size); 5304 5305 this.slider.css(this.sizeProperty, this.currentSliderSize); 5306 5307 this.currentSliderSize = this.slider[this.sizeProperty](); 5308 5309 5310 5311 // resize handle 5312 5313 this.handleSize = Math.round(this.currentSliderSize * this.ratio); 5314 5315 this.handle.css(this.sizeProperty, this.handleSize); 5316 5317 this.handleSize = this.handle[this.fullSizeProperty](); 5318 5319 5320 5321 return this; 5322 5323 }, 5324 5325 setRatio: function(ratio) { 5326 5327 this.ratio = ratio; 5328 5329 return this; 5330 5331 }, 5332 5333 setMaxValue: function(maxValue) { 5334 5335 this.maxValue = maxValue; 5336 5337 this.setValue(Math.min(this.value, this.maxValue)); 5338 5339 return this; 5340 5341 }, 5342 5343 setValue: function(value) { 5344 5345 this.value = value; 5346 5347 if (this.value < 0) { 5348 5349 this.value = 0; 5350 5351 } else if (this.value > this.maxValue) { 5352 5353 this.value = this.maxValue; 5354 5355 } 5356 5357 this.refresh(); 5358 5359 }, 5360 5361 setPosition: function(styles) { 5362 5363 this.scrollbar.css(styles); 5364 5365 return this; 5366 5367 }, 5368 5369 hide: function() { 5370 5371 this.scrollbar.detach(); 5372 5373 return this; 5374 5375 }, 5376 5377 show: function() { 5378 5379 this.scrollbar.appendTo(this.holder); 5380 5381 return this; 5382 5383 }, 5384 5385 refresh: function() { 5386 5387 // recalculate handle position 5388 5389 if (this.value === 0 || this.maxValue === 0) { 5390 5391 this.calcOffset = 0; 5392 5393 } else { 5394 5395 this.calcOffset = (this.value / this.maxValue) * (this.currentSliderSize - this.handleSize); 5396 5397 } 5398 5399 this.handle.css(this.offsetProperty, this.calcOffset); 5400 5401 5402 5403 // toggle inactive classes 5404 5405 this.btnDec.toggleClass(this.options.inactiveClass, this.value === 0); 5406 5407 this.btnInc.toggleClass(this.options.inactiveClass, this.value === this.maxValue); 5408 5409 this.scrollbar.toggleClass(this.options.inactiveClass, this.maxValue === 0); 5410 5411 }, 5412 5413 destroy: function() { 5414 5415 // remove event handlers and scrollbar block itself 5416 5417 this.btnDec.add(this.btnInc).off('jcf-pointerdown', this.onButtonPress); 5418 5419 this.handle.off('jcf-pointerdown', this.onHandlePress); 5420 5421 this.doc.off('jcf-pointermove', this.onHandleDrag); 5422 5423 this.doc.off('jcf-pointerup', this.onHandleRelease); 5424 5425 this.doc.off('jcf-pointerup', this.onButtonRelease); 5426 5427 this.stopSmoothScrolling(); 5428 5429 this.stopPageScrolling(); 5430 5431 this.scrollbar.remove(); 5432 5433 } 5434 5435 }); 5436 5437 5438 5439}(jQuery, this)); 5440 5441 5442 5443/*! 5444 5445 * JavaScript Custom Forms : Number Module 5446 5447 * 5448 5449 * Copyright 2014-2015 PSD2HTML - http://psd2html.com/jcf 5450 5451 * Released under the MIT license (LICENSE.txt) 5452 5453 * 5454 5455 * Version: 1.1.3 5456 5457 */ 5458 5459;(function($) { 5460 5461 'use strict'; 5462 5463 5464 5465 jcf.addModule({ 5466 5467 name: 'Number', 5468 5469 selector: 'input[type="number"]', 5470 5471 options: { 5472 5473 realElementClass: 'jcf-real-element', 5474 5475 fakeStructure: '<span class="jcf-number"><span class="jcf-btn-inc"></span><span class="jcf-btn-dec"></span></span>', 5476 5477 btnIncSelector: '.jcf-btn-inc', 5478 5479 btnDecSelector: '.jcf-btn-dec', 5480 5481 pressInterval: 150 5482 5483 }, 5484 5485 matchElement: function(element) { 5486 5487 return element.is(this.selector); 5488 5489 }, 5490 5491 init: function() { 5492 5493 this.initStructure(); 5494 5495 this.attachEvents(); 5496 5497 this.refresh(); 5498 5499 }, 5500 5501 initStructure: function() { 5502 5503 this.page = $('html'); 5504 5505 this.realElement = $(this.options.element).addClass(this.options.realElementClass); 5506 5507 this.fakeElement = $(this.options.fakeStructure).insertBefore(this.realElement).prepend(this.realElement); 5508 5509 this.btnDec = this.fakeElement.find(this.options.btnDecSelector); 5510 5511 this.btnInc = this.fakeElement.find(this.options.btnIncSelector); 5512 5513 5514 5515 // set initial values 5516 5517 this.initialValue = parseFloat(this.realElement.val()) || 0; 5518 5519 this.minValue = parseFloat(this.realElement.attr('min')); 5520 5521 this.maxValue = parseFloat(this.realElement.attr('max')); 5522 5523 this.stepValue = parseFloat(this.realElement.attr('step')) || 1; 5524 5525 5526 5527 // check attribute values 5528 5529 this.minValue = isNaN(this.minValue) ? -Infinity : this.minValue; 5530 5531 this.maxValue = isNaN(this.maxValue) ? Infinity : this.maxValue; 5532 5533 5534 5535 // handle range 5536 5537 if (isFinite(this.maxValue)) { 5538 5539 this.maxValue -= (this.maxValue - this.minValue) % this.stepValue; 5540 5541 } 5542 5543 }, 5544 5545 attachEvents: function() { 5546 5547 this.realElement.on({ 5548 5549 focus: this.onFocus 5550 5551 }); 5552 5553 this.btnDec.add(this.btnInc).on('jcf-pointerdown', this.onBtnPress); 5554 5555 }, 5556 5557 onBtnPress: function(e) { 5558 5559 var self = this, 5560 5561 increment; 5562 5563 5564 5565 if (!this.realElement.is(':disabled')) { 5566 5567 increment = this.btnInc.is(e.currentTarget); 5568 5569 5570 5571 self.step(increment); 5572 5573 clearInterval(this.stepTimer); 5574 5575 this.stepTimer = setInterval(function() { 5576 5577 self.step(increment); 5578 5579 }, this.options.pressInterval); 5580 5581 5582 5583 this.page.on('jcf-pointerup', this.onBtnRelease); 5584 5585 } 5586 5587 }, 5588 5589 onBtnRelease: function() { 5590 5591 clearInterval(this.stepTimer); 5592 5593 this.page.off('jcf-pointerup', this.onBtnRelease); 5594 5595 }, 5596 5597 onFocus: function() { 5598 5599 this.fakeElement.addClass(this.options.focusClass); 5600 5601 this.realElement.on({ 5602 5603 blur: this.onBlur, 5604 5605 keydown: this.onKeyPress 5606 5607 }); 5608 5609 }, 5610 5611 onBlur: function() { 5612 5613 this.fakeElement.removeClass(this.options.focusClass); 5614 5615 this.realElement.off({ 5616 5617 blur: this.onBlur, 5618 5619 keydown: this.onKeyPress 5620 5621 }); 5622 5623 }, 5624 5625 onKeyPress: function(e) { 5626 5627 if (e.which === 38 || e.which === 40) { 5628 5629 e.preventDefault(); 5630 5631 this.step(e.which === 38); 5632 5633 } 5634 5635 }, 5636 5637 step: function(increment) { 5638 5639 var originalValue = parseFloat(this.realElement.val()), 5640 5641 newValue = originalValue || 0, 5642 5643 addValue = this.stepValue * (increment ? 1 : -1), 5644 5645 edgeNumber = isFinite(this.minValue) ? this.minValue : this.initialValue - Math.abs(newValue * this.stepValue), 5646 5647 diff = Math.abs(edgeNumber - newValue) % this.stepValue; 5648 5649 5650 5651 // handle step diff 5652 5653 if (diff) { 5654 5655 if (increment) { 5656 5657 newValue += addValue - diff; 5658 5659 } else { 5660 5661 newValue -= diff; 5662 5663 } 5664 5665 } else { 5666 5667 newValue += addValue; 5668 5669 } 5670 5671 5672 5673 // handle min/max limits 5674 5675 if (newValue < this.minValue) { 5676 5677 newValue = this.minValue; 5678 5679 } else if (newValue > this.maxValue) { 5680 5681 newValue = this.maxValue; 5682 5683 } 5684 5685 5686 5687 // update value in real input if its changed 5688 5689 if (newValue !== originalValue) { 5690 5691 this.realElement.val(newValue).trigger('change'); 5692 5693 this.refresh(); 5694 5695 } 5696 5697 }, 5698 5699 refresh: function() { 5700 5701 var isDisabled = this.realElement.is(':disabled'), 5702 5703 currentValue = parseFloat(this.realElement.val()); 5704 5705 5706 5707 // handle disabled state 5708 5709 this.fakeElement.toggleClass(this.options.disabledClass, isDisabled); 5710 5711 5712 5713 // refresh button classes 5714 5715 this.btnDec.toggleClass(this.options.disabledClass, currentValue === this.minValue); 5716 5717 this.btnInc.toggleClass(this.options.disabledClass, currentValue === this.maxValue); 5718 5719 }, 5720 5721 destroy: function() { 5722 5723 // restore original structure 5724 5725 this.realElement.removeClass(this.options.realElementClass).insertBefore(this.fakeElement); 5726 5727 this.fakeElement.remove(); 5728 5729 clearInterval(this.stepTimer); 5730 5731 5732 5733 // remove event handlers 5734 5735 this.page.off('jcf-pointerup', this.onBtnRelease); 5736 5737 this.realElement.off({ 5738 5739 keydown: this.onKeyPress, 5740 5741 focus: this.onFocus, 5742 5743 blur: this.onBlur 5744 5745 }); 5746 5747 } 5748 5749 }); 5750 5751 5752 5753}(jQuery)); 5754 5755 5756 5757/*! 5758 5759 * JavaScript Custom Forms : Range Module 5760 5761 * 5762 5763 * Copyright 2014-2015 PSD2HTML - http://psd2html.com/jcf 5764 5765 * Released under the MIT license (LICENSE.txt) 5766 5767 * 5768 5769 * Version: 1.1.3 5770 5771 */ 5772 5773;(function($) { 5774 5775 'use strict'; 5776 5777 5778 5779 jcf.addModule({ 5780 5781 name: 'Range', 5782 5783 selector: 'input[type="range"]', 5784 5785 options: { 5786 5787 realElementClass: 'jcf-real-element', 5788 5789 fakeStructure: '<span class="jcf-range"><span class="jcf-range-wrapper"><span class="jcf-range-track"><span class="jcf-range-handle"></span></span></span></span>', 5790 5791 dataListMark: '<span class="jcf-range-mark"></span>', 5792 5793 rangeDisplayWrapper: '<span class="jcf-range-display-wrapper"></span>', 5794 5795 rangeDisplay: '<span class="jcf-range-display"></span>', 5796 5797 handleSelector: '.jcf-range-handle', 5798 5799 trackSelector: '.jcf-range-track', 5800 5801 activeHandleClass: 'jcf-active-handle', 5802 5803 verticalClass: 'jcf-vertical', 5804 5805 orientation: 'horizontal', 5806 5807 range: false, // or "min", "max", "all" 5808 5809 dragHandleCenter: true, 5810 5811 snapToMarks: true, 5812 5813 snapRadius: 5 5814 5815 }, 5816 5817 matchElement: function(element) { 5818 5819 return element.is(this.selector); 5820 5821 }, 5822 5823 init: function() { 5824 5825 this.initStructure(); 5826 5827 this.attachEvents(); 5828 5829 this.refresh(); 5830 5831 }, 5832 5833 initStructure: function() { 5834 5835 this.page = $('html'); 5836 5837 this.realElement = $(this.options.element).addClass(this.options.hiddenClass); 5838 5839 this.fakeElement = $(this.options.fakeStructure).insertBefore(this.realElement).prepend(this.realElement); 5840 5841 this.track = this.fakeElement.find(this.options.trackSelector); 5842 5843 this.trackHolder = this.track.parent(); 5844 5845 this.handle = this.fakeElement.find(this.options.handleSelector); 5846 5847 this.createdHandleCount = 0; 5848 5849 this.activeDragHandleIndex = 0; 5850 5851 this.isMultiple = this.realElement.prop('multiple') || typeof this.realElement.attr('multiple') === 'string'; 5852 5853 this.values = this.isMultiple ? this.realElement.attr('value').split(',') : [this.realElement.val()]; 5854 5855 this.handleCount = this.isMultiple ? this.values.length : 1; 5856 5857 5858 5859 // create range display 5860 5861 this.rangeDisplayWrapper = $(this.options.rangeDisplayWrapper).insertBefore(this.track); 5862 5863 if (this.options.range === 'min' || this.options.range === 'all') { 5864 5865 this.rangeMin = $(this.options.rangeDisplay).addClass('jcf-range-min').prependTo(this.rangeDisplayWrapper); 5866 5867 } 5868 5869 if (this.options.range === 'max' || this.options.range === 'all') { 5870 5871 this.rangeMax = $(this.options.rangeDisplay).addClass('jcf-range-max').prependTo(this.rangeDisplayWrapper); 5872 5873 } 5874 5875 5876 5877 // clone handles if needed 5878 5879 while (this.createdHandleCount < this.handleCount) { 5880 5881 this.createdHandleCount++; 5882 5883 this.handle.clone().addClass('jcf-index-' + this.createdHandleCount).insertBefore(this.handle); 5884 5885 5886 5887 // create mid ranges 5888 5889 if (this.createdHandleCount > 1) { 5890 5891 if (!this.rangeMid) { 5892 5893 this.rangeMid = $(); 5894 5895 } 5896 5897 this.rangeMid = this.rangeMid.add($(this.options.rangeDisplay).addClass('jcf-range-mid').prependTo(this.rangeDisplayWrapper)); 5898 5899 } 5900 5901 } 5902 5903 5904 5905 // grab all handles 5906 5907 this.handle.detach(); 5908 5909 this.handle = null; 5910 5911 this.handles = this.fakeElement.find(this.options.handleSelector); 5912 5913 this.handles.eq(0).addClass(this.options.activeHandleClass); 5914 5915 5916 5917 // handle orientation 5918 5919 this.isVertical = (this.options.orientation === 'vertical'); 5920 5921 this.directionProperty = this.isVertical ? 'top' : 'left'; 5922 5923 this.offsetProperty = this.isVertical ? 'bottom' : 'left'; 5924 5925 this.eventProperty = this.isVertical ? 'pageY' : 'pageX'; 5926 5927 this.sizeProperty = this.isVertical ? 'height' : 'width'; 5928
5929 this.sizeMethod = this.isVertical ? 'innerHeight' : 'innerWidth'; 5930 5931 this.fakeElement.css('touchAction', this.isVertical ? 'pan-x' : 'pan-y'); 5932 5933 if (this.isVertical) { 5934 5935 this.fakeElement.addClass(this.options.verticalClass); 5936 5937 } 5938 5939 5940 5941 // set initial values 5942 5943 this.minValue = parseFloat(this.realElement.attr('min')); 5944 5945 this.maxValue = parseFloat(this.realElement.attr('max')); 5946 5947 this.stepValue = parseFloat(this.realElement.attr('step')) || 1; 5948 5949 5950 5951 // check attribute values 5952 5953 this.minValue = isNaN(this.minValue) ? 0 : this.minValue; 5954 5955 this.maxValue = isNaN(this.maxValue) ? 100 : this.maxValue; 5956 5957 5958 5959 // handle range 5960 5961 if (this.stepValue !== 1) { 5962 5963 this.maxValue -= (this.maxValue - this.minValue) % this.stepValue; 5964 5965 } 5966 5967 this.stepsCount = (this.maxValue - this.minValue) / this.stepValue; 5968 5969 this.createDataList(); 5970 5971 }, 5972 5973 attachEvents: function() { 5974 5975 this.realElement.on({ 5976 5977 focus: this.onFocus 5978 5979 }); 5980 5981 this.trackHolder.on('jcf-pointerdown', this.onTrackPress); 5982 5983 this.handles.on('jcf-pointerdown', this.onHandlePress); 5984 5985 }, 5986 5987 createDataList: function() { 5988 5989 var self = this, 5990 5991 dataValues = [], 5992 5993 dataListId = this.realElement.attr('list'); 5994 5995 5996 5997 if (dataListId) { 5998 5999 $('#' + dataListId).find('option').each(function() { 6000 6001 var itemValue = parseFloat(this.value || this.innerHTML), 6002 6003 mark, markOffset; 6004 6005 6006 6007 if (!isNaN(itemValue)) { 6008 6009 markOffset = self.valueToOffset(itemValue); 6010 6011 dataValues.push({ 6012 6013 value: itemValue, 6014 6015 offset: markOffset 6016 6017 }); 6018 6019 mark = $(self.options.dataListMark).text(itemValue).attr({ 6020 6021 'data-mark-value': itemValue 6022 6023 }).css(self.offsetProperty, markOffset + '%').appendTo(self.track); 6024 6025 } 6026 6027 }); 6028 6029 if (dataValues.length) { 6030 6031 self.dataValues = dataValues; 6032 6033 } 6034 6035 } 6036 6037 }, 6038 6039 getDragHandleRange: function(handleIndex) { 6040 6041 // calculate range for slider with multiple handles 6042 6043 var minStep = -Infinity, 6044 6045 maxStep = Infinity; 6046 6047 6048 6049 if (handleIndex > 0) { 6050 6051 minStep = this.valueToStepIndex(this.values[handleIndex - 1]); 6052 6053 } 6054 6055 if (handleIndex < this.handleCount - 1) { 6056 6057 maxStep = this.valueToStepIndex(this.values[handleIndex + 1]); 6058 6059 } 6060 6061 6062 6063 return { 6064 6065 minStepIndex: minStep, 6066 6067 maxStepIndex: maxStep 6068 6069 }; 6070 6071 }, 6072 6073 getNearestHandle: function(percent) { 6074 6075 // handle vertical sliders 6076 6077 if (this.isVertical) { 6078 6079 percent = 1 - percent; 6080 6081 } 6082 6083 6084 6085 // detect closest handle when track is pressed 6086 6087 var closestHandle = this.handles.eq(0), 6088 6089 closestDistance = Infinity, 6090 6091 self = this; 6092 6093 6094 6095 if (this.handleCount > 1) { 6096 6097 this.handles.each(function() { 6098 6099 var handleOffset = parseFloat(this.style[self.offsetProperty]) / 100, 6100 6101 handleDistance = Math.abs(handleOffset - percent); 6102 6103 6104 6105 if (handleDistance < closestDistance) { 6106 6107 closestDistance = handleDistance; 6108 6109 closestHandle = $(this); 6110 6111 } 6112 6113 }); 6114 6115 } 6116 6117 return closestHandle; 6118 6119 }, 6120 6121 onTrackPress: function(e) { 6122 6123 var trackSize, trackOffset, innerOffset; 6124 6125 6126 6127 e.preventDefault(); 6128 6129 if (!this.realElement.is(':disabled') && !this.activeDragHandle) { 6130 6131 trackSize = this.track[this.sizeMethod](); 6132 6133 trackOffset = this.track.offset()[this.directionProperty]; 6134 6135 this.activeDragHandle = this.getNearestHandle((e[this.eventProperty] - trackOffset) / this.trackHolder[this.sizeMethod]()); 6136 6137 this.activeDragHandleIndex = this.handles.index(this.activeDragHandle); 6138 6139 this.handles.removeClass(this.options.activeHandleClass).eq(this.activeDragHandleIndex).addClass(this.options.activeHandleClass); 6140 6141 innerOffset = this.activeDragHandle[this.sizeMethod]() / 2; 6142 6143 6144 6145 this.dragData = { 6146 6147 trackSize: trackSize, 6148 6149 innerOffset: innerOffset, 6150 6151 trackOffset: trackOffset, 6152 6153 min: trackOffset, 6154 6155 max: trackOffset + trackSize 6156 6157 }; 6158 6159 this.page.on({ 6160 6161 'jcf-pointermove': this.onHandleMove, 6162 6163 'jcf-pointerup': this.onHandleRelease 6164 6165 }); 6166 6167 6168 6169 if (e.pointerType === 'mouse') { 6170 6171 this.realElement.focus(); 6172 6173 } 6174 6175 6176 6177 this.onHandleMove(e); 6178 6179 } 6180 6181 }, 6182 6183 onHandlePress: function(e) { 6184 6185 var trackSize, trackOffset, innerOffset; 6186 6187 6188 6189 e.preventDefault(); 6190 6191 if (!this.realElement.is(':disabled') && !this.activeDragHandle) { 6192 6193 this.activeDragHandle = $(e.currentTarget); 6194 6195 this.activeDragHandleIndex = this.handles.index(this.activeDragHandle); 6196 6197 this.handles.removeClass(this.options.activeHandleClass).eq(this.activeDragHandleIndex).addClass(this.options.activeHandleClass); 6198 6199 trackSize = this.track[this.sizeMethod](); 6200 6201 trackOffset = this.track.offset()[this.directionProperty]; 6202 6203 innerOffset = this.options.dragHandleCenter ? this.activeDragHandle[this.sizeMethod]() / 2 : e[this.eventProperty] - this.handle.offset()[this.directionProperty]; 6204 6205 6206 6207 this.dragData = { 6208 6209 trackSize: trackSize, 6210 6211 innerOffset: innerOffset, 6212 6213 trackOffset: trackOffset, 6214 6215 min: trackOffset, 6216 6217 max: trackOffset + trackSize 6218 6219 }; 6220 6221 this.page.on({ 6222 6223 'jcf-pointermove': this.onHandleMove, 6224 6225 'jcf-pointerup': this.onHandleRelease 6226 6227 }); 6228 6229 6230 6231 if (e.pointerType === 'mouse') { 6232 6233 this.realElement.focus(); 6234 6235 } 6236 6237 } 6238 6239 }, 6240 6241 onHandleMove: function(e) { 6242 6243 var self = this, 6244 6245 newOffset, dragPercent, stepIndex, valuePercent, handleDragRange; 6246 6247 6248 6249 // calculate offset 6250 6251 if (this.isVertical) { 6252 6253 newOffset = this.dragData.max + (this.dragData.min - e[this.eventProperty]) - this.dragData.innerOffset; 6254 6255 } else { 6256 6257 newOffset = e[this.eventProperty] - this.dragData.innerOffset; 6258 6259 } 6260 6261 6262 6263 // fit in range 6264 6265 if (newOffset < this.dragData.min) { 6266 6267 newOffset = this.dragData.min; 6268 6269 } else if (newOffset > this.dragData.max) { 6270 6271 newOffset = this.dragData.max; 6272 6273 } 6274 6275 6276 6277 e.preventDefault(); 6278 6279 if (this.options.snapToMarks && this.dataValues) { 6280 6281 // snap handle to marks 6282 6283 var dragOffset = newOffset - this.dragData.trackOffset; 6284 6285 dragPercent = (newOffset - this.dragData.trackOffset) / this.dragData.trackSize * 100; 6286 6287 6288 6289 $.each(this.dataValues, function(index, item) { 6290 6291 var markOffset = item.offset / 100 * self.dragData.trackSize, 6292 6293 markMin = markOffset - self.options.snapRadius, 6294 6295 markMax = markOffset + self.options.snapRadius; 6296 6297 6298 6299 if (dragOffset >= markMin && dragOffset <= markMax) { 6300 6301 dragPercent = item.offset; 6302 6303 return false;
6304 6305 } 6306 6307 }); 6308 6309 } else { 6310 6311 // snap handle to steps 6312 6313 dragPercent = (newOffset - this.dragData.trackOffset) / this.dragData.trackSize * 100; 6314 6315 } 6316 6317 6318 6319 // move handle only in range 6320 6321 stepIndex = Math.round(dragPercent * this.stepsCount / 100); 6322 6323 if (this.handleCount > 1) { 6324 6325 handleDragRange = this.getDragHandleRange(this.activeDragHandleIndex); 6326 6327 if (stepIndex < handleDragRange.minStepIndex) { 6328 6329 stepIndex = Math.max(handleDragRange.minStepIndex, stepIndex); 6330 6331 } else if (stepIndex > handleDragRange.maxStepIndex) { 6332 6333 stepIndex = Math.min(handleDragRange.maxStepIndex, stepIndex); 6334 6335 } 6336 6337 } 6338 6339 valuePercent = stepIndex * (100 / this.stepsCount); 6340 6341 6342 6343 if (this.dragData.stepIndex !== stepIndex) { 6344 6345 this.dragData.stepIndex = stepIndex; 6346 6347 this.dragData.offset = valuePercent; 6348 6349 this.activeDragHandle.css(this.offsetProperty, this.dragData.offset + '%'); 6350 6351 6352 6353 // update value(s) and trigger "input" event 6354 6355 this.values[this.activeDragHandleIndex] = '' + this.stepIndexToValue(stepIndex); 6356 6357 this.updateValues(); 6358 6359 this.realElement.trigger('input'); 6360 6361 } 6362 6363 }, 6364 6365 onHandleRelease: function() { 6366 6367 var newValue; 6368 6369 if (typeof this.dragData.offset === 'number') { 6370 6371 newValue = this.stepIndexToValue(this.dragData.stepIndex); 6372 6373 this.realElement.val(newValue).trigger('change'); 6374 6375 } 6376 6377 6378 6379 this.page.off({ 6380 6381 'jcf-pointermove': this.onHandleMove, 6382 6383 'jcf-pointerup': this.onHandleRelease 6384 6385 }); 6386 6387 delete this.activeDragHandle; 6388 6389 delete this.dragData; 6390 6391 }, 6392 6393 onFocus: function() { 6394 6395 if (!this.fakeElement.hasClass(this.options.focusClass)) { 6396 6397 this.fakeElement.addClass(this.options.focusClass); 6398 6399 this.realElement.on({ 6400 6401 blur: this.onBlur, 6402 6403 keydown: this.onKeyPress 6404 6405 }); 6406 6407 } 6408 6409 }, 6410 6411 onBlur: function() { 6412 6413 this.fakeElement.removeClass(this.options.focusClass); 6414 6415 this.realElement.off({ 6416 6417 blur: this.onBlur, 6418 6419 keydown: this.onKeyPress 6420 6421 }); 6422 6423 }, 6424 6425 onKeyPress: function(e) { 6426 6427 var incValue = (e.which === 38 || e.which === 39), 6428 6429 decValue = (e.which === 37 || e.which === 40); 6430 6431 6432 6433 // handle TAB key in slider with multiple handles 6434 6435 if (e.which === 9 && this.handleCount > 1) { 6436 6437 if (e.shiftKey && this.activeDragHandleIndex > 0) { 6438 6439 this.activeDragHandleIndex--; 6440 6441 } else if (!e.shiftKey && this.activeDragHandleIndex < this.handleCount - 1) { 6442 6443 this.activeDragHandleIndex++; 6444 6445 } else { 6446 6447 return; 6448 6449 } 6450 6451 e.preventDefault(); 6452 6453 this.handles.removeClass(this.options.activeHandleClass).eq(this.activeDragHandleIndex).addClass(this.options.activeHandleClass); 6454 6455 } 6456 6457 6458 6459 // handle cursor keys 6460 6461 if (decValue || incValue) { 6462 6463 e.preventDefault(); 6464 6465 this.step(incValue ? this.stepValue : -this.stepValue); 6466 6467 } 6468 6469 }, 6470 6471 updateValues: function() { 6472 6473 var value = this.values.join(','); 6474 6475 if (this.values.length > 1) { 6476 6477 this.realElement.prop('valueLow', this.values[0]); 6478 6479 this.realElement.prop('valueHigh', this.values[this.values.length - 1]); 6480 6481 this.realElement.val(value); 6482 6483 6484 6485 // if browser does not accept multiple values set only one 6486 6487 if (this.realElement.val() !== value) { 6488 6489 this.realElement.val(this.values[this.values.length - 1]); 6490 6491 } 6492 6493 } else { 6494 6495 this.realElement.val(value); 6496 6497 } 6498 6499 6500 6501 this.updateRanges(); 6502 6503 }, 6504 6505 updateRanges: function() { 6506 6507 // update display ranges 6508 6509 var self = this, 6510 6511 handle; 6512 6513 6514 6515 if (this.rangeMin) { 6516 6517 handle = this.handles[0]; 6518 6519 this.rangeMin.css(this.offsetProperty, 0).css(this.sizeProperty, handle.style[this.offsetProperty]); 6520 6521 } 6522 6523 if (this.rangeMax) { 6524 6525 handle = this.handles[this.handles.length - 1]; 6526 6527 this.rangeMax.css(this.offsetProperty, handle.style[this.offsetProperty]).css(this.sizeProperty, 100 - parseFloat(handle.style[this.offsetProperty]) + '%'); 6528 6529 } 6530 6531 if (this.rangeMid) { 6532 6533 this.handles.each(function(index, curHandle) { 6534 6535 var prevHandle, midBox; 6536 6537 if (index > 0) { 6538 6539 prevHandle = self.handles[index - 1]; 6540 6541 midBox = self.rangeMid[index - 1]; 6542 6543 midBox.style[self.offsetProperty] = prevHandle.style[self.offsetProperty]; 6544 6545 midBox.style[self.sizeProperty] = parseFloat(curHandle.style[self.offsetProperty]) - parseFloat(prevHandle.style[self.offsetProperty]) + '%'; 6546 6547 } 6548 6549 }); 6550 6551 } 6552 6553 }, 6554
6555 step: function(changeValue) { 6556 6557 var originalValue = parseFloat(this.values[this.activeDragHandleIndex || 0]), 6558 6559 newValue = originalValue, 6560 6561 minValue = this.minValue, 6562 6563 maxValue = this.maxValue; 6564 6565 6566 6567 if (isNaN(originalValue)) { 6568 6569 newValue = 0; 6570 6571 } 6572 6573 6574 6575 newValue += changeValue; 6576 6577 6578 6579 if (this.handleCount > 1) { 6580 6581 if (this.activeDragHandleIndex > 0) { 6582 6583 minValue = parseFloat(this.values[this.activeDragHandleIndex - 1]); 6584 6585 } 6586 6587 if (this.activeDragHandleIndex < this.handleCount - 1) { 6588 6589 maxValue = parseFloat(this.values[this.activeDragHandleIndex + 1]); 6590 6591 } 6592 6593 } 6594 6595 6596 6597 if (newValue > maxValue) { 6598 6599 newValue = maxValue; 6600 6601 } else if (newValue < minValue) { 6602 6603 newValue = minValue; 6604 6605 } 6606 6607 6608 6609 if (newValue !== originalValue) { 6610 6611 this.values[this.activeDragHandleIndex || 0] = '' + newValue; 6612 6613 this.updateValues(); 6614 6615 this.realElement.trigger('input').trigger('change'); 6616 6617 this.setSliderValue(this.values); 6618 6619 } 6620 6621 }, 6622 6623 valueToStepIndex: function(value) { 6624 6625 return (value - this.minValue) / this.stepValue; 6626 6627 }, 6628 6629 stepIndexToValue: function(stepIndex) { 6630 6631 return this.minValue + this.stepValue * stepIndex; 6632 6633 }, 6634 6635 valueToOffset: function(value) { 6636 6637 var range = this.maxValue - this.minValue, 6638 6639 percent = (value - this.minValue) / range; 6640 6641 6642 6643 return percent * 100; 6644 6645 }, 6646 6647 getSliderValue: function() { 6648 6649 return $.map(this.values, function(value) { 6650 6651 return parseFloat(value) || 0; 6652 6653 }); 6654 6655 }, 6656 6657 setSliderValue: function(values) { 6658 6659 // set handle position accordion according to value 6660 6661 var self = this; 6662 6663 this.handles.each(function(index, handle) { 6664 6665 handle.style[self.offsetProperty] = self.valueToOffset(values[index]) + '%'; 6666 6667 }); 6668 6669 }, 6670 6671 refresh: function() { 6672 6673 // handle disabled state 6674 6675 var isDisabled = this.realElement.is(':disabled'); 6676 6677 this.fakeElement.toggleClass(this.options.disabledClass, isDisabled); 6678 6679 6680 6681 // refresh handle position according to current value 6682 6683 this.setSliderValue(this.getSliderValue()); 6684 6685 this.updateRanges(); 6686 6687 }, 6688 6689 destroy: function() { 6690 6691 this.realElement.removeClass(this.options.hiddenClass).insertBefore(this.fakeElement); 6692 6693 this.fakeElement.remove(); 6694 6695 6696 6697 this.realElement.off({ 6698 6699 keydown: this.onKeyPress, 6700 6701 focus: this.onFocus, 6702 6703 blur: this.onBlur 6704 6705 }); 6706 6707 } 6708 6709 }); 6710 6711 6712 6713}(jQuery)); 6714 6715 6716 6717 6718 6719/* 6720 6721 * jQuery SlideMenu plugin 6722 6723 */ 6724 6725;(function($){ 6726 6727 function AjaxPopup(options){ 6728 6729 this.options = $.extend({ 6730 6731 holder: null, 6732 6733 button: '.btn-more', 6734 6735 holderBox: 'body', 6736 6737 ajaxHold: '#ajax-holder', 6738 6739 appendToBody: false, 6740 6741 attr: 'href', 6742 6743 animSpeed: 500 6744 6745 }, options); 6746 6747 6748 6749 this.init(); 6750 6751 } 6752 6753 AjaxPopup.prototype = { 6754 6755 init: function(){ 6756 6757 this.findElements(); 6758 6759 this.makeCallback('onInit', this); 6760 6761 this.attachEvents(); 6762 6763 }, 6764 6765 findElements: function(){ 6766 6767 this.holder = jQuery(this.options.holder); 6768 6769 this.button = this.holder.find(this.options.button); 6770 6771 this.ajaxHold = this.holder.find(this.options.ajaxHold); 6772 6773 6774 6775 }, 6776 6777 attachEvents: function(){ 6778 6779 var self = this; 6780 6781 this.clickHandler = function(e){ 6782 6783 e.preventDefault(); 6784 6785 var attr = self.button.attr(self.options.attr); 6786 6787 if(attr != '#'){ 6788 6789 e.preventDefault(); 6790 6791 self.ajaxLoad(attr).done(function(data){ 6792 6793 var content = jQuery(data).filter('.blogs-block').css({opacity: 0}); 6794 6795 var btnAjax = jQuery(data).filter('.btn-load'); 6796 6797 6798 6799 if(self.options.appendToBody) content.appendTo(jQuery(self.options.holderBox)); 6800 6801 else content.appendTo(self.ajaxHold); 6802 6803 6804 6805 if(btnAjax.length) self.button.attr('href', btnAjax.attr('href')); 6806 6807 else self.button.hide(); 6808 6809 6810 6811 content.stop().animate({opacity: 1}, self.options.animSpeed); 6812 6813 self.makeCallback('onChange', self); 6814 6815 }); 6816 6817 } 6818 6819 }; 6820 6821 this.button.on('click', this.clickHandler); 6822 6823 }, 6824 6825 ajaxLoad: function(url){ 6826 6827 var d = jQuery.Deferred(); 6828 6829 jQuery.ajax({ 6830 6831 url: url, 6832 6833 type: 'get', 6834 6835 cache: false, 6836 6837 dataType: "html", 6838 6839 success: function(data){ 6840 6841 d.resolve(data); 6842 6843 }, 6844 6845 error: function(jqXHR, textStatus, errorThrown){ 6846 6847 d.reject(jqXHR, textStatus, errorThrown); 6848 6849 } 6850 6851 }); 6852 6853 return d; 6854 6855 }, 6856 6857 makeCallback: function(name) { 6858 6859 if(typeof this.options[name] === 'function') { 6860 6861 var args = Array.prototype.slice.call(arguments); 6862 6863 args.shift(); 6864 6865 this.options[name].apply(this, args); 6866 6867 } 6868 6869 } 6870 6871 }; 6872 6873 6874 6875 $.fn.ajaxPopup = function(options){ 6876 6877 return this.each(function(){ 6878 6879 $(this).data('AjaxPopup', new AjaxPopup($.extend(options, {holder:this}))); 6880 6881 }); 6882 6883 }; 6884 6885})(jQuery); 6886 6887 6888 6889/* 6890 6891 * jQuery Accordion plugin 6892 6893 */ 6894 6895;(function($){ 6896 6897 $.fn.slideAccordion = function(opt){ 6898 6899 // default options 6900 6901 var options = $.extend({ 6902 6903 addClassBeforeAnimation: false, 6904 6905 allowClickWhenExpanded: false, 6906 6907 activeClass:'active', 6908 6909 opener:'.opener', 6910 6911 slider:'.slide', 6912 6913 animSpeed: 300, 6914 6915 collapsible:true, 6916 6917 event:'click' 6918 6919 },opt); 6920 6921 6922 6923 return this.each(function(){ 6924 6925 // options 6926 6927 var accordion = $(this); 6928 6929 var items = accordion.find(':has('+options.slider+')'); 6930 6931 6932 6933 items.each(function(){ 6934 6935 var item = $(this); 6936 6937 var opener = item.find(options.opener); 6938 6939 var slider = item.find(options.slider); 6940 6941 opener.bind(options.event, function(e){ 6942
6943 if(!slider.is(':animated')) { 6944 6945 if(item.hasClass(options.activeClass)) { 6946 6947 if(options.allowClickWhenExpanded) { 6948 6949 return; 6950 6951 } else if(options.collapsible) { 6952 6953 slider.slideUp(options.animSpeed, function(){ 6954 6955 hideSlide(slider); 6956 6957 item.removeClass(options.activeClass); 6958 6959 }); 6960 6961 } 6962 6963 } else { 6964 6965 // show active 6966 6967 var levelItems = item.siblings('.'+options.activeClass); 6968 6969 var sliderElements = levelItems.find(options.slider); 6970 6971 item.addClass(options.activeClass); 6972 6973 showSlide(slider).hide().slideDown(options.animSpeed); 6974 6975 6976 6977 // collapse others 6978 6979 sliderElements.slideUp(options.animSpeed, function(){ 6980 6981 levelItems.removeClass(options.activeClass); 6982 6983 hideSlide(sliderElements); 6984 6985 }); 6986 6987 } 6988 6989 } 6990 6991 e.preventDefault(); 6992 6993 }); 6994 6995 if(item.hasClass(options.activeClass)) showSlide(slider); else hideSlide(slider); 6996 6997 }); 6998 6999 }); 7000 7001 }; 7002 7003 7004 7005 // accordion slide visibility 7006 7007 var showSlide = function(slide) { 7008 7009 return slide.css({position:'', top: '', left: '', width: '' }); 7010 7011 }; 7012 7013 var hideSlide = function(slide) { 7014 7015 return slide.show().css({position:'absolute', top: -9999, left: -9999, width: slide.width() }); 7016 7017 }; 7018 7019}(jQuery)); 7020 7021 7022 7023/* 7024 7025 * jQuery <marquee> plugin 7026 7027 */ 7028 7029;(function($){ 7030 7031 function Marquee(options) { 7032 7033 this.options = $.extend({ 7034 7035 holder: null, 7036 7037 handleFlexible: true, 7038 7039 pauseOnHover: true, 7040 7041 hoverClass: 'hover', 7042 7043 direction: 'left', 7044 7045 cloneClass: 'cloned', 7046 7047 mask: null, 7048 7049 line: '>*', 7050 7051 items: '>*', 7052 7053 animSpeed: 10, // px per second 7054 7055 initialDelay: 0 7056 7057 }, options); 7058 7059 this.init(); 7060 7061 } 7062 7063 Marquee.prototype = { 7064 7065 init: function() { 7066 7067 if(this.options.holder) { 7068 7069 this.initStructure(); 7070 7071 this.attachEvents(); 7072 7073 } 7074 7075 }, 7076 7077 initStructure: function() { 7078 7079 // find elements 7080 7081 this.holder = $(this.options.holder); 7082 7083 this.mask = this.options.mask ? this.holder.find(this.options.mask) : this.holder, 7084 7085 this.line = this.mask.find(this.options.line), 7086 7087 this.items = this.line.find(this.options.items).css({'float':'left'}); 7088 7089 this.direction = (this.options.direction === 'left') ? -1 : 1; 7090 7091 this.recalculateDimensions(); 7092 7093 7094 7095 // prepare structure 7096 7097 this.cloneItems = this.items.clone().addClass(this.options.cloneClass).appendTo(this.line); 7098 7099 if(this.itemWidth >= this.maskWidth) { 7100 7101 this.activeLine = true; 7102 7103 this.offset = (this.direction === -1 ? 0 : this.maxOffset); 7104 7105 } else { 7106 7107 this.activeLine = false; 7108 7109 this.cloneItems.hide(); 7110 7111 this.offset = 0; 7112 7113 } 7114 7115 this.line.css({ 7116 7117 width: this.itemWidth * 2, 7118 7119 marginLeft: this.offset 7120 7121 }); 7122 7123 }, 7124 7125 attachEvents: function() { 7126 7127 // flexible layout handling 7128 7129 var self = this; 7130 7131 if(this.options.handleFlexible) { 7132 7133 this.resizeHandler = function() { 7134 7135 self.recalculateDimensions(); 7136 7137 if(self.itemWidth < self.maskWidth) { 7138 7139 self.activeLine = false; 7140 7141 self.cloneItems.hide(); 7142 7143 self.stopMoving(); 7144 7145 self.offset = 0; 7146 7147 self.line.css({marginLeft: self.offset}); 7148 7149 } else { 7150 7151 self.activeLine = true; 7152 7153 self.cloneItems.show(); 7154 7155 self.startMoving(); 7156 7157 } 7158 7159 }; 7160 7161 $(window).bind('resize orientationchange', this.resizeHandler); 7162 7163 } 7164 7165 7166 7167 // pause on hover 7168 7169 if(this.options.pauseOnHover) { 7170 7171 this.hoverHandler = function() { 7172 7173 self.stopMoving(); 7174 7175 self.holder.addClass(self.options.hoverClass); 7176 7177 }; 7178 7179 this.leaveHandler = function() { 7180 7181 self.startMoving(); 7182 7183 self.holder.removeClass(self.options.hoverClass); 7184 7185 }; 7186 7187 this.holder.bind({ mouseenter: this.hoverHandler, mouseleave: this.leaveHandler }); 7188 7189 } 7190 7191 7192 7193 // initial delay 7194 7195 setTimeout(function(){ 7196 7197 self.initialFlag = true; 7198 7199 self.startMoving(); 7200 7201 }, self.options.initialDelay || 1); 7202 7203 }, 7204 7205 recalculateDimensions: function() { 7206 7207 // calculate block dimensions 7208 7209 var self = this; 7210 7211 this.maskWidth = this.mask.width(); 7212 7213 this.itemWidth = 1; 7214 7215 this.items.each(function(){ 7216 7217 self.itemWidth += $(this).outerWidth(true); 7218 7219 }); 7220 7221 this.maxOffset = -this.itemWidth; 7222 7223 }, 7224 7225 startMoving: function() { 7226 7227 // start animation 7228 7229 var self = this; 7230 7231 if(self.activeLine && self.initialFlag) { 7232 7233 var targetOffset = (self.direction < 0 ? self.maxOffset : 0); 7234 7235 7236 7237 self.offset = parseInt(self.line.css('marginLeft'), 10) || 0; 7238 7239 self.line.stop().animate({ 7240 7241 marginLeft: targetOffset 7242 7243 }, { 7244 7245 duration: Math.abs(1000 * (self.offset - targetOffset) / self.options.animSpeed), 7246 7247 easing: 'linear', 7248 7249 complete: function() { 7250 7251 self.offset = (self.direction < 0 ? 0 : self.maxOffset); 7252 7253 self.line.css({marginLeft: self.offset}); 7254 7255 self.startMoving(); 7256 7257 } 7258 7259 }); 7260 7261 } 7262 7263 }, 7264
7265 stopMoving: function() { 7266 7267 // stop animation 7268 7269 this.line.stop(); 7270 7271 }, 7272 7273 destroy: function() { 7274 7275 this.stopMoving(); 7276 7277 this.cloneItems.remove(); 7278 7279 this.items.css({'float':''}); 7280 7281 this.line.css({marginLeft:'',width:''}); 7282 7283 this.holder.removeClass(this.options.hoverClass); 7284 7285 this.holder.unbind('mouseenter', this.hoverHandler); 7286 7287 this.holder.unbind('mouseleave', this.leaveHandler); 7288 7289 $(window).unbind('resize orientationchange', this.resizeHandler); 7290 7291 } 7292 7293 }; 7294 7295 7296 7297 // jQuery plugin interface 7298 7299 $.fn.marquee = function(opt) { 7300 7301 return this.each(function() { 7302 7303 jQuery(this).data('Marquee', new Marquee($.extend(opt, {holder: this}))); 7304 7305 }); 7306 7307 }; 7308 7309}(jQuery)); 7310 7311 7312 7313// set same height for blocks 7314 7315function setSameHeight(opt) { 7316 7317 // default options 7318 7319 var options = { 7320 7321 holder: null, 7322 7323 skipClass: 'same-height-ignore', 7324 7325 leftEdgeClass: 'same-height-left', 7326 7327 rightEdgeClass: 'same-height-right', 7328 7329 elements: '>*', 7330 7331 flexible: false, 7332 7333 multiLine: false, 7334 7335 useMinHeight: false, 7336 7337 biggestHeight: false 7338 7339 }; 7340 7341 for(var p in opt) { 7342 7343 if(opt.hasOwnProperty(p)) { 7344 7345 options[p] = opt[p]; 7346 7347 } 7348 7349 } 7350 7351 7352 7353 // init script 7354 7355 if(options.holder) { 7356 7357 var holders = lib.queryElementsBySelector(options.holder); 7358 7359 lib.each(holders, function(ind, curHolder){ 7360 7361 var curElements = [], resizeTimer, postResizeTimer; 7362 7363 var tmpElements = lib.queryElementsBySelector(options.elements, curHolder); 7364 7365 7366 7367 // get resize elements 7368 7369 for(var i = 0; i < tmpElements.length; i++) { 7370 7371 if(!lib.hasClass(tmpElements[i], options.skipClass)) { 7372 7373 curElements.push(tmpElements[i]); 7374 7375 } 7376 7377 } 7378 7379 if(!curElements.length) return; 7380 7381 7382 7383 // resize handler 7384 7385 function doResize() { 7386 7387 for(var i = 0; i < curElements.length; i++) { 7388 7389 curElements[i].style[options.useMinHeight && SameHeight.supportMinHeight ? 'minHeight' : 'height'] = ''; 7390 7391 } 7392 7393 7394 7395 if(options.multiLine) { 7396 7397 // resize elements row by row 7398 7399 SameHeight.resizeElementsByRows(curElements, options); 7400 7401 } else { 7402 7403 // resize elements by holder 7404 7405 SameHeight.setSize(curElements, curHolder, options); 7406 7407 } 7408 7409 } 7410 7411 doResize(); 7412 7413 7414 7415 // handle flexible layout / font resize 7416 7417 function flexibleResizeHandler() { 7418 7419 clearTimeout(resizeTimer); 7420 7421 resizeTimer = setTimeout(function(){ 7422 7423 doResize(); 7424 7425 clearTimeout(postResizeTimer); 7426 7427 postResizeTimer = setTimeout(doResize, 100); 7428 7429 },1); 7430 7431 } 7432 7433 if(options.flexible) { 7434 7435 addEvent(window, 'resize', flexibleResizeHandler); 7436 7437 addEvent(window, 'orientationchange', flexibleResizeHandler); 7438 7439 FontResizeEvent.onChange(flexibleResizeHandler); 7440 7441 } 7442 7443 // handle complete page load including images and fonts 7444 7445 addEvent(window, 'load', flexibleResizeHandler); 7446 7447 }); 7448 7449 } 7450 7451 7452 7453 // event handler helper functions 7454 7455 function addEvent(object, event, handler) { 7456 7457 if(object.addEventListener) object.addEventListener(event, handler, false); 7458 7459 else if(object.attachEvent) object.attachEvent('on'+event, handler); 7460 7461 } 7462 7463} 7464 7465 7466 7467/* 7468 7469 * SameHeight helper module 7470 7471 */ 7472 7473SameHeight = { 7474 7475 supportMinHeight: typeof document.documentElement.style.maxHeight !== 'undefined', // detect css min-height support 7476 7477 setSize: function(boxes, parent, options) { 7478 7479 var calcHeight, holderHeight = typeof parent === 'number' ? parent : this.getHeight(parent); 7480 7481 7482 7483 for(var i = 0; i < boxes.length; i++) { 7484 7485 var box = boxes[i]; 7486 7487 var depthDiffHeight = 0; 7488 7489 var isBorderBox = this.isBorderBox(box); 7490 7491 lib.removeClass(box, options.leftEdgeClass); 7492 7493 lib.removeClass(box, options.rightEdgeClass); 7494 7495 7496 7497 if(typeof parent != 'number') { 7498 7499 var tmpParent = box.parentNode; 7500 7501 while(tmpParent != parent) { 7502 7503 depthDiffHeight += this.getOuterHeight(tmpParent) - this.getHeight(tmpParent); 7504 7505 tmpParent = tmpParent.parentNode; 7506 7507 } 7508 7509 } 7510 7511 calcHeight = holderHeight - depthDiffHeight; 7512 7513 calcHeight -= isBorderBox ? 0 : this.getOuterHeight(box) - this.getHeight(box); 7514 7515 if(calcHeight > 0) { 7516 7517 box.style[options.useMinHeight && this.supportMinHeight ? 'minHeight' : 'height'] = calcHeight + 'px'; 7518 7519 } 7520 7521 } 7522 7523 7524 7525 lib.addClass(boxes[0], options.leftEdgeClass); 7526 7527 lib.addClass(boxes[boxes.length - 1], options.rightEdgeClass); 7528 7529 return calcHeight; 7530 7531 }, 7532 7533 getOffset: function(obj) { 7534 7535 if (obj.getBoundingClientRect) { 7536 7537 var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft; 7538 7539 var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; 7540 7541 var clientLeft = document.documentElement.clientLeft || document.body.clientLeft || 0; 7542 7543 var clientTop = document.documentElement.clientTop || document.body.clientTop || 0; 7544 7545 return { 7546 7547 top:Math.round(obj.getBoundingClientRect().top + scrollTop - clientTop), 7548 7549 left:Math.round(obj.getBoundingClientRect().left + scrollLeft - clientLeft) 7550 7551 }; 7552 7553 } else { 7554 7555 var posLeft = 0, posTop = 0; 7556 7557 while (obj.offsetParent) {posLeft += obj.offsetLeft; posTop += obj.offsetTop; obj = obj.offsetParent;} 7558
7559 return {top:posTop,left:posLeft}; 7560 7561 } 7562 7563 }, 7564 7565 getStyle: function(el, prop) { 7566 7567 if (document.defaultView && document.defaultView.getComputedStyle) { 7568 7569 return document.defaultView.getComputedStyle(el, null)[prop]; 7570 7571 } else if (el.currentStyle) { 7572 7573 return el.currentStyle[prop]; 7574 7575 } else { 7576 7577 return el.style[prop]; 7578 7579 } 7580 7581 }, 7582 7583 getStylesTotal: function(obj) { 7584 7585 var sum = 0; 7586 7587 for(var i = 1; i < arguments.length; i++) { 7588 7589 var val = parseFloat(this.getStyle(obj, arguments[i])); 7590 7591 if(!isNaN(val)) { 7592 7593 sum += val; 7594 7595 } 7596 7597 } 7598 7599 return sum; 7600 7601 }, 7602 7603 getHeight: function(obj) { 7604 7605 return obj.offsetHeight - this.getStylesTotal(obj, 'borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'); 7606 7607 }, 7608 7609 getOuterHeight: function(obj) { 7610 7611 return obj.offsetHeight; 7612 7613 }, 7614 7615 isBorderBox: function(obj) { 7616 7617 var f = this.getStyle, styleValue = f(obj, 'boxSizing') || f(obj, 'WebkitBoxSizing') || f(obj, 'MozBoxSizing'); 7618 7619 return styleValue === 'border-box'; 7620 7621 }, 7622 7623 resizeElementsByRows: function(boxes, options) { 7624 7625 var currentRow = [], maxHeight, maxCalcHeight = 0, firstOffset = this.getOffset(boxes[0]).top; 7626 7627 for(var i = 0; i < boxes.length; i++) { 7628 7629 if(this.getOffset(boxes[i]).top === firstOffset) { 7630 7631 currentRow.push(boxes[i]); 7632 7633 } else { 7634 7635 maxHeight = this.getMaxHeight(currentRow); 7636 7637 maxCalcHeight = Math.max(maxCalcHeight, this.setSize(currentRow, maxHeight, options)); 7638 7639 firstOffset = this.getOffset(boxes[i]).top; 7640 7641 currentRow = [boxes[i]]; 7642 7643 } 7644 7645 } 7646 7647 if(currentRow.length) { 7648 7649 maxHeight = this.getMaxHeight(currentRow); 7650 7651 maxCalcHeight = Math.max(maxCalcHeight, this.setSize(currentRow, maxHeight, options)); 7652 7653 } 7654 7655 if(options.biggestHeight) { 7656 7657 for(i = 0; i < boxes.length; i++) { 7658 7659 boxes[i].style[options.useMinHeight && this.supportMinHeight ? 'minHeight' : 'height'] = maxCalcHeight + 'px'; 7660 7661 } 7662 7663 } 7664 7665 }, 7666 7667 getMaxHeight: function(boxes) { 7668 7669 var maxHeight = 0; 7670 7671 for(var i = 0; i < boxes.length; i++) { 7672 7673 maxHeight = Math.max(maxHeight, this.getOuterHeight(boxes[i])); 7674 7675 } 7676 7677 return maxHeight; 7678 7679 } 7680 7681}; 7682 7683 7684 7685/* 7686 7687 * FontResize Event 7688 7689 */ 7690 7691FontResizeEvent = (function(window,document){ 7692 7693 var randomID = 'font-resize-frame-' + Math.floor(Math.random() * 1000); 7694 7695 var resizeFrame = document.createElement('iframe'); 7696 7697 resizeFrame.id = randomID; resizeFrame.className = 'font-resize-helper'; 7698 7699 resizeFrame.style.cssText = 'position:absolute;width:100em;height:10px;top:-9999px;left:-9999px;border-width:0'; 7700 7701 7702 7703 // wait for page load 7704 7705 function onPageReady() { 7706 7707 document.body.appendChild(resizeFrame); 7708 7709 7710 7711 // use native IE resize event if possible 7712 7713 if (/MSIE (6|7|8)/.test(navigator.userAgent)) { 7714 7715 resizeFrame.onresize = function() { 7716 7717 window.FontResizeEvent.trigger(resizeFrame.offsetWidth / 100); 7718 7719 }; 7720 7721 } 7722 7723 // use script inside the iframe to detect resize for other browsers 7724 7725 else { 7726 7727 var doc = resizeFrame.contentWindow.document; 7728 7729 doc.open(); 7730 7731 doc.write('<scri' + 'pt>window.onload = function(){var em = parent.document.getElementById("' + randomID + '");window.onresize = function(){if(parent.FontResizeEvent){parent.FontResizeEvent.trigger(em.offsetWidth / 100);}}};</scri' + 'pt>'); 7732 7733 doc.close(); 7734 7735 } 7736 7737 } 7738 7739 if(window.addEventListener) window.addEventListener('load', onPageReady, false); 7740 7741 else if(window.attachEvent) window.attachEvent('onload', onPageReady); 7742 7743 7744 7745 // public interface 7746 7747 var callbacks = []; 7748 7749 return { 7750 7751 onChange: function(f) { 7752 7753 if(typeof f === 'function') { 7754 7755 callbacks.push(f); 7756 7757 } 7758 7759 }, 7760 7761 trigger: function(em) { 7762 7763 for(var i = 0; i < callbacks.length; i++) { 7764 7765 callbacks[i](em); 7766 7767 } 7768 7769 } 7770 7771 }; 7772 7773}(this, document)); 7774 7775 7776 7777/* 7778 7779 * Utility module 7780 7781 */ 7782 7783lib = { 7784 7785 hasClass: function(el,cls) { 7786 7787 return el && el.className ? el.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)')) : false; 7788 7789 }, 7790 7791 addClass: function(el,cls) { 7792 7793 if (el && !this.hasClass(el,cls)) el.className += " "+cls; 7794 7795 }, 7796 7797 removeClass: function(el,cls) { 7798 7799 if (el && this.hasClass(el,cls)) {el.className=el.className.replace(new RegExp('(\\s|^)'+cls+'(\\s|$)'),' ');} 7800 7801 }, 7802 7803 extend: function(obj) { 7804 7805 for(var i = 1; i < arguments.length; i++) { 7806 7807 for(var p in arguments[i]) { 7808 7809 if(arguments[i].hasOwnProperty(p)) { 7810 7811 obj[p] = arguments[i][p]; 7812 7813 } 7814 7815 } 7816 7817 } 7818 7819 return obj; 7820 7821 }, 7822 7823 each: function(obj, callback) { 7824 7825 var property, len; 7826 7827 if(typeof obj.length === 'number') { 7828 7829 for(property = 0, len = obj.length; property < len; property++) { 7830 7831 if(callback.call(obj[property], property, obj[property]) === false) { 7832 7833 break; 7834 7835 } 7836 7837 } 7838 7839 } else { 7840 7841 for(property in obj) { 7842 7843 if(obj.hasOwnProperty(property)) { 7844 7845 if(callback.call(obj[property], property, obj[property]) === false) { 7846 7847 break; 7848 7849 } 7850 7851 } 7852 7853 } 7854 7855 } 7856 7857 }, 7858 7859 event: (function() { 7860 7861 var fixEvent = function(e) { 7862 7863 e = e || window.event; 7864 7865 if(e.isFixed) return e; else e.isFixed = true; 7866 7867 if(!e.target) e.target = e.srcElement; 7868 7869 e.preventDefault = e.preventDefault || function() {this.returnValue = false;}; 7870 7871 e.stopPropagation = e.stopPropagation || function() {this.cancelBubble = true;}; 7872 7873 return e; 7874 7875 }; 7876 7877 return { 7878 7879 add: function(elem, event, handler) { 7880 7881 if(!elem.events) { 7882 7883 elem.events = {}; 7884 7885 elem.handle = function(e) { 7886 7887 var ret, handlers = elem.events[e.type]; 7888 7889 e = fixEvent(e); 7890 7891 for(var i = 0, len = handlers.length; i < len; i++) { 7892 7893 if(handlers[i]) { 7894 7895 ret = handlers[i].call(elem, e); 7896 7897 if(ret === false) { 7898 7899 e.preventDefault(); 7900 7901 e.stopPropagation(); 7902 7903 } 7904 7905 } 7906 7907 } 7908 7909 }; 7910 7911 } 7912 7913 if(!elem.events[event]) { 7914 7915 elem.events[event] = []; 7916 7917 if(elem.addEventListener) elem.addEventListener(event, elem.handle, false); 7918 7919 else if(elem.attachEvent) elem.attachEvent('on'+event, elem.handle); 7920 7921 } 7922 7923 elem.events[event].push(handler); 7924 7925 }, 7926 7927 remove: function(elem, event, handler) { 7928 7929 var handlers = elem.events[event]; 7930
7931 for(var i = handlers.length - 1; i >= 0; i--) { 7932 7933 if(handlers[i] === handler) { 7934 7935 handlers.splice(i,1); 7936 7937 } 7938 7939 } 7940 7941 if(!handlers.length) { 7942 7943 delete elem.events[event]; 7944 7945 if(elem.removeEventListener) elem.removeEventListener(event, elem.handle, false); 7946 7947 else if(elem.detachEvent) elem.detachEvent('on'+event, elem.handle); 7948 7949 } 7950 7951 } 7952 7953 }; 7954 7955 }()), 7956 7957 queryElementsBySelector: function(selector, scope) { 7958 7959 scope = scope || document; 7960 7961 if(!selector) return []; 7962 7963 if(selector === '>*') return scope.children; 7964 7965 if(typeof document.querySelectorAll === 'function') { 7966 7967 return scope.querySelectorAll(selector); 7968 7969 } 7970 7971 var selectors = selector.split(','); 7972 7973 var resultList = []; 7974 7975 for(var s = 0; s < selectors.length; s++) { 7976 7977 var currentContext = [scope || document]; 7978 7979 var tokens = selectors[s].replace(/^\s+/,'').replace(/\s+$/,'').split(' '); 7980 7981 for (var i = 0; i < tokens.length; i++) { 7982 7983 token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,''); 7984 7985 if (token.indexOf('#') > -1) { 7986 7987 var bits = token.split('#'), tagName = bits[0], id = bits[1]; 7988 7989 var element = document.getElementById(id); 7990 7991 if (element && tagName && element.nodeName.toLowerCase() != tagName) { 7992 7993 return []; 7994 7995 } 7996 7997 currentContext = element ? [element] : []; 7998 7999 continue; 8000 8001 } 8002 8003 if (token.indexOf('.') > -1) { 8004 8005 var bits = token.split('.'), tagName = bits[0] || '*', className = bits[1], found = [], foundCount = 0; 8006 8007 for (var h = 0; h < currentContext.length; h++) { 8008 8009 var elements; 8010 8011 if (tagName == '*') { 8012 8013 elements = currentContext[h].getElementsByTagName('*'); 8014 8015 } else { 8016 8017 elements = currentContext[h].getElementsByTagName(tagName); 8018 8019 } 8020 8021 for (var j = 0; j < elements.length; j++) { 8022 8023 found[foundCount++] = elements[j]; 8024 8025 } 8026 8027 } 8028 8029 currentContext = []; 8030 8031 var currentContextIndex = 0; 8032 8033 for (var k = 0; k < found.length; k++) { 8034 8035 if (found[k].className && found[k].className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'))) { 8036 8037 currentContext[currentContextIndex++] = found[k]; 8038 8039 } 8040 8041 } 8042 8043 continue; 8044 8045 } 8046 8047 if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) { 8048 8049 var tagName = RegExp.$1 || '*', attrName = RegExp.$2, attrOperator = RegExp.$3, attrValue = RegExp.$4; 8050 8051 if(attrName.toLowerCase() == 'for' && this.browser.msie && this.browser.version < 8) { 8052 8053 attrName = 'htmlFor'; 8054 8055 } 8056 8057 var found = [], foundCount = 0; 8058 8059 for (var h = 0; h < currentContext.length; h++) { 8060 8061 var elements; 8062 8063 if (tagName == '*') { 8064 8065 elements = currentContext[h].getElementsByTagName('*'); 8066 8067 } else { 8068 8069 elements = currentContext[h].getElementsByTagName(tagName); 8070 8071 } 8072 8073 for (var j = 0; elements[j]; j++) { 8074 8075 found[foundCount++] = elements[j]; 8076 8077 } 8078 8079 } 8080 8081 currentContext = []; 8082 8083 var currentContextIndex = 0, checkFunction; 8084 8085 switch (attrOperator) { 8086 8087 case '=': checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue) }; break; 8088 8089 case '~': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('(\\s|^)'+attrValue+'(\\s|$)'))) }; break; 8090 8091 case '|': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))) }; break; 8092 8093 case '^': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0) }; break; 8094 8095 case '$': checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length) }; break; 8096 8097 case '*': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1) }; break; 8098 8099 default : checkFunction = function(e) { return e.getAttribute(attrName) }; 8100 8101 } 8102 8103 currentContext = []; 8104 8105 var currentContextIndex = 0; 8106 8107 for (var k = 0; k < found.length; k++) { 8108 8109 if (checkFunction(found[k])) { 8110 8111 currentContext[currentContextIndex++] = found[k]; 8112 8113 } 8114 8115 } 8116 8117 continue; 8118 8119 } 8120 8121 tagName = token; 8122 8123 var found = [], foundCount = 0; 8124 8125 for (var h = 0; h < currentContext.length; h++) { 8126 8127 var elements = currentContext[h].getElementsByTagName(tagName); 8128 8129 for (var j = 0; j < elements.length; j++) { 8130 8131 found[foundCount++] = elements[j]; 8132 8133 } 8134 8135 } 8136 8137 currentContext = found; 8138 8139 } 8140 8141 resultList = [].concat(resultList,currentContext); 8142 8143 } 8144 8145 return resultList; 8146 8147 }, 8148 8149 trim: function (str) { 8150 8151 return str.replace(/^\s+/, '').replace(/\s+$/, ''); 8152 8153 }, 8154 8155 bind: function(f, scope, forceArgs){ 8156 8157 return function() {return f.apply(scope, typeof forceArgs !== 'undefined' ? [forceArgs] : arguments);}; 8158 8159 } 8160 8161}; 8162 8163 8164 8165// DOM ready handler 8166 8167function bindReady(handler){ 8168 8169 var called = false;
8170 8171 var ready = function() { 8172 8173 if (called) return; 8174 8175 called = true; 8176 8177 handler(); 8178 8179 }; 8180 8181 if (document.addEventListener) { 8182 8183 document.addEventListener('DOMContentLoaded', ready, false); 8184 8185 } else if (document.attachEvent) { 8186 8187 if (document.documentElement.doScroll && window == window.top) { 8188 8189 var tryScroll = function(){ 8190 8191 if (called) return; 8192 8193 if (!document.body) return; 8194 8195 try { 8196 8197 document.documentElement.doScroll('left'); 8198 8199 ready(); 8200 8201 } catch(e) { 8202 8203 setTimeout(tryScroll, 0); 8204 8205 } 8206 8207 }; 8208 8209 tryScroll(); 8210 8211 } 8212 8213 document.attachEvent('onreadystatechange', function(){ 8214 8215 if (document.readyState === 'complete') { 8216 8217 ready(); 8218 8219 } 8220 8221 }); 8222 8223 } 8224 8225 if (window.addEventListener) window.addEventListener('load', ready, false); 8226 8227 else if (window.attachEvent) window.attachEvent('onload', ready); 8228 8229} 8230 8231 8232 8233 8234 8235/* 8236 8237 * jQuery Tabs plugin 8238 8239 */ 8240 8241;(function($){ 8242 8243 $.fn.contentTabs = function(o){ 8244 8245 // default options 8246 8247 var options = $.extend({ 8248 8249 activeClass:'active', 8250 8251 addToParent:false, 8252 8253 autoHeight:false, 8254 8255 autoRotate:false, 8256 8257 checkHash:false, 8258 8259 animSpeed:400, 8260 8261 switchTime:3000, 8262 8263 effect: 'none', // "fade", "slide" 8264 8265 tabLinks:'a', 8266 8267 attrib:'href', 8268 8269 event:'click' 8270 8271 },o); 8272 8273 8274 8275 return this.each(function(){ 8276 8277 var tabset = $(this), tabs = $(); 8278 8279 var tabLinks = tabset.find(options.tabLinks); 8280 8281 var tabLinksParents = tabLinks.parent(); 8282 8283 var prevActiveLink = tabLinks.eq(0), currentTab, animating; 8284 8285 var tabHolder; 8286 8287 8288 8289 // handle location hash 8290 8291 if(options.checkHash && tabLinks.filter('[' + options.attrib + '="' + location.hash + '"]').length) { 8292 8293 (options.addToParent ? tabLinksParents : tabLinks).removeClass(options.activeClass); 8294 8295 setTimeout(function() { 8296 8297 window.scrollTo(0,0); 8298 8299 },1); 8300 8301 } 8302 8303 8304 8305 // init tabLinks 8306 8307 tabLinks.each(function(){ 8308 8309 var link = $(this); 8310 8311 var href = link.attr(options.attrib); 8312 8313 var parent = link.parent(); 8314 8315 href = href.substr(href.lastIndexOf('#')); 8316 8317 8318 8319 // get elements 8320 8321 var tab = $(href).hide().addClass(tabHiddenClass); 8322 8323 tabs = tabs.add(tab); 8324 8325 link.data('cparent', parent); 8326 8327 link.data('ctab', tab); 8328 8329 8330 8331 // find tab holder 8332 8333 if(!tabHolder && tab.length) { 8334 8335 tabHolder = tab.parent(); 8336 8337 } 8338 8339 8340 8341 // show only active tab 8342 8343 var classOwner = options.addToParent ? parent : link; 8344 8345 if(classOwner.hasClass(options.activeClass) || (options.checkHash && location.hash === href)) { 8346 8347 classOwner.addClass(options.activeClass); 8348 8349 prevActiveLink = link; currentTab = tab; 8350 8351 tab.removeClass(tabHiddenClass).width(''); 8352 8353 contentTabsEffect[options.effect].show({tab:tab, fast:true}); 8354 8355 } else { 8356
8357 var tabWidth = tab.width(); 8358 8359 if(tabWidth) { 8360 8361 tab.width(tabWidth); 8362 8363 } 8364 8365 tab.addClass(tabHiddenClass); 8366 8367 } 8368 8369 8370 8371 // event handler 8372 8373 link.bind(options.event, function(e){ 8374 8375 if(link != prevActiveLink && !animating) { 8376 8377 switchTab(prevActiveLink, link); 8378 8379 prevActiveLink = link; 8380 8381 } 8382 8383 }); 8384 8385 if(options.attrib === 'href') { 8386 8387 link.bind('click', function(e){ 8388 8389 e.preventDefault(); 8390 8391 }); 8392 8393 } 8394 8395 }); 8396 8397 8398 8399 // tab switch function 8400 8401 function switchTab(oldLink, newLink) { 8402 8403 animating = true; 8404 8405 var oldTab = oldLink.data('ctab'); 8406 8407 var newTab = newLink.data('ctab'); 8408 8409 prevActiveLink = newLink; 8410 8411 currentTab = newTab; 8412 8413 8414 8415 // refresh pagination links 8416 8417 (options.addToParent ? tabLinksParents : tabLinks).removeClass(options.activeClass); 8418 8419 (options.addToParent ? newLink.data('cparent') : newLink).addClass(options.activeClass); 8420 8421 8422 8423 // hide old tab 8424 8425 resizeHolder(oldTab, true); 8426 8427 contentTabsEffect[options.effect].hide({ 8428 8429 speed: options.animSpeed, 8430 8431 tab:oldTab, 8432 8433 complete: function() { 8434 8435 // show current tab 8436 8437 resizeHolder(newTab.removeClass(tabHiddenClass).width('')); 8438 8439 contentTabsEffect[options.effect].show({ 8440 8441 speed: options.animSpeed, 8442 8443 tab:newTab, 8444 8445 complete: function() { 8446 8447 if(!oldTab.is(newTab)) { 8448 8449 oldTab.width(oldTab.width()).addClass(tabHiddenClass); 8450 8451 } 8452 8453 animating = false; 8454 8455 resizeHolder(newTab, false); 8456 8457 autoRotate(); 8458 8459 $(window).trigger('resize'); 8460 8461 } 8462 8463 }); 8464 8465 } 8466 8467 }); 8468 8469 } 8470 8471 8472 8473 // holder auto height 8474 8475 function resizeHolder(block, state) { 8476 8477 var curBlock = block && block.length ? block : currentTab; 8478 8479 if(options.autoHeight && curBlock) { 8480 8481 tabHolder.stop(); 8482 8483 if(state === false) { 8484 8485 tabHolder.css({height:''}); 8486 8487 } else { 8488 8489 var origStyles = curBlock.attr('style'); 8490 8491 curBlock.show().css({width:curBlock.width()}); 8492 8493 var tabHeight = curBlock.outerHeight(true); 8494 8495 if(!origStyles) curBlock.removeAttr('style'); else curBlock.attr('style', origStyles); 8496 8497 if(state === true) { 8498 8499 tabHolder.css({height: tabHeight}); 8500 8501 } else { 8502 8503 tabHolder.animate({height: tabHeight}, {duration: options.animSpeed}); 8504 8505 } 8506 8507 } 8508 8509 } 8510 8511 } 8512 8513 if(options.autoHeight) { 8514 8515 $(window).bind('resize orientationchange', function(){ 8516 8517 tabs.not(currentTab).removeClass(tabHiddenClass).show().each(function(){ 8518 8519 var tab = jQuery(this), tabWidth = tab.css({width:''}).width(); 8520 8521 if(tabWidth) { 8522 8523 tab.width(tabWidth); 8524 8525 } 8526 8527 }).hide().addClass(tabHiddenClass); 8528 8529 8530 8531 resizeHolder(currentTab, false); 8532 8533 }); 8534 8535 } 8536 8537 8538 8539 // autorotation handling 8540 8541 var rotationTimer; 8542 8543 function nextTab() { 8544 8545 var activeItem = (options.addToParent ? tabLinksParents : tabLinks).filter('.' + options.activeClass); 8546 8547 var activeIndex = (options.addToParent ? tabLinksParents : tabLinks).index(activeItem); 8548 8549 var newLink = tabLinks.eq(activeIndex < tabLinks.length - 1 ? activeIndex + 1 : 0); 8550 8551 prevActiveLink = tabLinks.eq(activeIndex); 8552 8553 switchTab(prevActiveLink, newLink); 8554 8555 } 8556 8557 function autoRotate() { 8558 8559 if(options.autoRotate && tabLinks.length > 1) { 8560 8561 clearTimeout(rotationTimer); 8562 8563 rotationTimer = setTimeout(function() { 8564 8565 if(!animating) { 8566 8567 nextTab(); 8568 8569 } else { 8570 8571 autoRotate(); 8572 8573 } 8574 8575 }, options.switchTime); 8576 8577 } 8578 8579 } 8580 8581 autoRotate(); 8582 8583 }); 8584 8585 }; 8586 8587 8588 8589 // add stylesheet for tabs on DOMReady 8590 8591 var tabHiddenClass = 'js-tab-hidden'; 8592 8593 (function() { 8594 8595 var tabStyleSheet = $('<style type="text/css">')[0]; 8596 8597 var tabStyleRule = '.'+tabHiddenClass; 8598 8599 tabStyleRule += '{position:absolute !important;left:-9999px !important;top:-9999px !important;display:block !important}'; 8600 8601 if (tabStyleSheet.styleSheet) { 8602 8603 tabStyleSheet.styleSheet.cssText = tabStyleRule; 8604 8605 } else { 8606 8607 tabStyleSheet.appendChild(document.createTextNode(tabStyleRule)); 8608 8609 } 8610 8611 $('head').append(tabStyleSheet); 8612 8613 }()); 8614 8615 8616 8617 // tab switch effects 8618 8619 var contentTabsEffect = { 8620 8621 none: { 8622 8623 show: function(o) { 8624 8625 o.tab.css({display:'block'}); 8626 8627 if(o.complete) o.complete(); 8628 8629 }, 8630 8631 hide: function(o) { 8632 8633 o.tab.css({display:'none'}); 8634 8635 if(o.complete) o.complete(); 8636 8637 } 8638 8639 }, 8640 8641 fade: { 8642 8643 show: function(o) { 8644 8645 if(o.fast) o.speed = 1; 8646 8647 o.tab.fadeIn(o.speed); 8648 8649 if(o.complete) setTimeout(o.complete, o.speed); 8650 8651 }, 8652 8653 hide: function(o) { 8654 8655 if(o.fast) o.speed = 1; 8656 8657 o.tab.fadeOut(o.speed); 8658 8659 if(o.complete) setTimeout(o.complete, o.speed); 8660 8661 } 8662 8663 }, 8664 8665 slide: { 8666 8667 show: function(o) { 8668 8669 var tabHeight = o.tab.show().css({width:o.tab.width()}).outerHeight(true); 8670 8671 var tmpWrap = $('<div class="effect-div">').insertBefore(o.tab).append(o.tab); 8672 8673 tmpWrap.css({width:'100%', overflow:'hidden', position:'relative'}); o.tab.css({marginTop:-tabHeight,display:'block'}); 8674 8675 if(o.fast) o.speed = 1; 8676 8677 o.tab.animate({marginTop: 0}, {duration: o.speed, complete: function(){ 8678 8679 o.tab.css({marginTop: '', width: ''}).insertBefore(tmpWrap); 8680 8681 tmpWrap.remove(); 8682 8683 if(o.complete) o.complete(); 8684 8685 }}); 8686 8687 }, 8688 8689 hide: function(o) { 8690 8691 var tabHeight = o.tab.show().css({width:o.tab.width()}).outerHeight(true); 8692 8693 var tmpWrap = $('<div class="effect-div">').insertBefore(o.tab).append(o.tab); 8694 8695 tmpWrap.css({width:'100%', overflow:'hidden', position:'relative'}); 8696 8697 8698 8699 if(o.fast) o.speed = 1; 8700 8701 o.tab.animate({marginTop: -tabHeight}, {duration: o.speed, complete: function(){ 8702 8703 o.tab.css({display:'none', marginTop:'', width:''}).insertBefore(tmpWrap); 8704 8705 tmpWrap.remove(); 8706 8707 if(o.complete) o.complete(); 8708 8709 }}); 8710 8711 } 8712 8713 } 8714 8715 }; 8716 8717}(jQuery)); 8718 8719 8720 8721 8722 8723/*! 8724 8725 * JavaScript Custom Forms : Select Module 8726 8727 * 8728 8729 * Copyright 2014 PSD2HTML (http://psd2html.com) 8730 8731 * Released under the MIT license (LICENSE.txt) 8732 8733 * 8734 8735 * Version: 1.0.0 8736 8737 */ 8738 8739;(function($, window) { 8740 8741 'use strict'; 8742 8743 8744 8745 jcf.addModule({ 8746 8747 name: 'Select', 8748 8749 selector: 'select', 8750 8751 options: { 8752 8753 element: null 8754 8755 }, 8756 8757 plugins: { 8758 8759 ListBox: ListBox, 8760 8761 ComboBox: ComboBox, 8762 8763 SelectList: SelectList 8764 8765 }, 8766 8767 matchElement: function(element) { 8768 8769 return element.is('select'); 8770 8771 }, 8772 8773 init: function() { 8774 8775 this.element = $(this.options.element); 8776 8777 this.createInstance(); 8778 8779 }, 8780 8781 isListBox: function() { 8782 8783 return this.element.is('[size]:not([jcf-size]), [multiple]'); 8784 8785 }, 8786 8787 createInstance: function() { 8788 8789 if(this.instance) { 8790 8791 this.instance.destroy(); 8792 8793 } 8794 8795 if(this.isListBox()) { 8796 8797 this.instance = new ListBox(this.options); 8798 8799 } else { 8800 8801 this.instance = new ComboBox(this.options); 8802 8803 } 8804 8805 }, 8806 8807 refresh: function() { 8808 8809 var typeMismatch = (this.isListBox() && this.instance instanceof ComboBox) || 8810 8811 (!this.isListBox() && this.instance instanceof ListBox); 8812 8813 8814 8815 if(typeMismatch) { 8816 8817 this.createInstance(); 8818 8819 } else { 8820 8821 this.instance.refresh(); 8822 8823 } 8824 8825 }, 8826 8827 destroy: function() { 8828 8829 this.instance.destroy(); 8830 8831 } 8832 8833 }); 8834 8835 8836 8837 // combobox module 8838 8839 function ComboBox(options) { 8840 8841 this.options = $.extend({ 8842 8843 wrapNative: true, 8844 8845 wrapNativeOnMobile: true, 8846 8847 fakeDropInBody: true, 8848 8849 useCustomScroll: true, 8850 8851 flipDropToFit: true, 8852 8853 maxVisibleItems: 10, 8854 8855 fakeAreaStructure: '<span class="jcf-select"><span class="jcf-select-text"></span><span class="jcf-select-opener"></span></span>', 8856 8857 fakeDropStructure: '<div class="jcf-select-drop"><div class="jcf-select-drop-content"></div></div>', 8858 8859 optionClassPrefix: 'jcf-option-', 8860 8861 selectClassPrefix: 'jcf-select-', 8862 8863 dropContentSelector: '.jcf-select-drop-content', 8864 8865 selectTextSelector: '.jcf-select-text', 8866 8867 dropActiveClass: 'jcf-drop-active', 8868 8869 flipDropClass: 'jcf-drop-flipped' 8870 8871 }, options); 8872 8873 this.init(); 8874 8875 } 8876 8877 $.extend(ComboBox.prototype, { 8878 8879 init: function(options) { 8880 8881 this.initStructure(); 8882 8883 this.bindHandlers(); 8884 8885 this.attachEvents(); 8886 8887 this.refresh(); 8888 8889 }, 8890 8891 initStructure: function() { 8892 8893 // prepare structure 8894 8895 this.win = $(window); 8896 8897 this.doc = $(document); 8898 8899 this.realElement = $(this.options.element); 8900 8901 this.fakeElement = $(this.options.fakeAreaStructure).insertAfter(this.realElement); 8902 8903 this.selectTextContainer = this.fakeElement.find(this.options.selectTextSelector); 8904 8905 this.selectText = $('<span></span>').appendTo(this.selectTextContainer); 8906 8907 makeUnselectable(this.fakeElement); 8908 8909 8910 8911 // copy classes from original select 8912
8913 this.fakeElement.addClass(getPrefixedClasses(this.realElement.prop('className'), this.options.selectClassPrefix)); 8914 8915 8916 8917 // detect device type and dropdown behavior 8918 8919 if(this.options.isMobileDevice && this.options.wrapNativeOnMobile && !this.options.wrapNative) { 8920 8921 this.options.wrapNative = true; 8922 8923 } 8924 8925 8926 8927 if(this.options.wrapNative) { 8928 8929 // wrap native select inside fake block 8930 8931 this.realElement.prependTo(this.fakeElement).css({ 8932 8933 position: 'absolute', 8934 8935 height: '100%', 8936 8937 width: '100%' 8938 8939 }).addClass(this.options.resetAppearanceClass); 8940 8941 } else { 8942 8943 // just hide native select 8944 8945 this.realElement.addClass(this.options.hiddenClass); 8946 8947 this.fakeElement.attr('title', this.realElement.attr('title')); 8948 8949 this.fakeDropTarget = this.options.fakeDropInBody ? $('body') : this.fakeElement; 8950 8951 } 8952 8953 }, 8954 8955 attachEvents: function() { 8956 8957 // delayed refresh handler 8958 8959 var self = this; 8960 8961 this.delayedRefresh = function() { 8962 8963 setTimeout(function() { 8964 8965 self.refresh(); 8966 8967 if(self.list) { 8968 8969 self.list.refresh(); 8970 8971 } 8972 8973 }, 1); 8974 8975 }; 8976 8977 8978 8979 // native dropdown event handlers 8980 8981 if(this.options.wrapNative) { 8982 8983 this.realElement.on({ 8984 8985 focus: this.onFocus, 8986 8987 change: this.onChange, 8988 8989 click: this.onChange, 8990 8991 keydown: this.onChange 8992 8993 }); 8994 8995 } else { 8996 8997 // custom dropdown event handlers 8998 8999 this.realElement.on({ 9000 9001 focus: this.onFocus, 9002 9003 change: this.onChange, 9004 9005 keydown: this.onKeyDown 9006 9007 }); 9008 9009 this.fakeElement.on({ 9010 9011 'jcf-pointerdown': this.onSelectAreaPress 9012 9013 }); 9014 9015 } 9016 9017 }, 9018 9019 onKeyDown: function(e) { 9020 9021 if(e.which === 13) { 9022 9023 this.toggleDropdown(); 9024 9025 } else { 9026 9027 this.delayedRefresh(); 9028 9029 } 9030 9031 }, 9032 9033 onChange: function() { 9034 9035 this.refresh(); 9036 9037 }, 9038 9039 onFocus: function() { 9040 9041 if(!this.pressedFlag || !this.focusedFlag) { 9042 9043 this.fakeElement.addClass(this.options.focusClass); 9044 9045 this.realElement.on('blur', this.onBlur); 9046 9047 this.toggleListMode(true); 9048 9049 this.focusedFlag = true; 9050 9051 } 9052 9053 }, 9054 9055 onBlur: function() { 9056 9057 if(!this.pressedFlag) { 9058 9059 this.fakeElement.removeClass(this.options.focusClass); 9060 9061 this.realElement.off('blur', this.onBlur); 9062 9063 this.toggleListMode(false); 9064 9065 this.focusedFlag = false; 9066 9067 } 9068 9069 }, 9070 9071 onResize: function() { 9072 9073 if(this.dropActive) { 9074 9075 this.hideDropdown(); 9076 9077 } 9078 9079 }, 9080 9081 onSelectDropPress: function() { 9082 9083 this.pressedFlag = true; 9084 9085 }, 9086 9087 onSelectDropRelease: function(e, pointerEvent) { 9088 9089 this.pressedFlag = false; 9090 9091 if(pointerEvent.pointerType === 'mouse') { 9092 9093 this.realElement.focus(); 9094 9095 } 9096 9097 }, 9098 9099 onSelectAreaPress: function(e) { 9100 9101 // skip click if drop inside fake element or real select is disabled 9102 9103 var dropClickedInsideFakeElement = !this.options.fakeDropInBody && $(e.target).closest(this.dropdown).length; 9104 9105 if(dropClickedInsideFakeElement || e.button > 1 || this.realElement.is(':disabled')) { 9106 9107 return; 9108 9109 } 9110 9111 9112 9113 // toggle dropdown visibility 9114 9115 this.toggleDropdown(); 9116 9117 9118 9119 // misc handlers 9120 9121 if(!this.focusedFlag) { 9122 9123 if(e.pointerType === 'mouse') { 9124 9125 this.realElement.focus(); 9126 9127 } else { 9128 9129 this.onFocus(e); 9130 9131 } 9132 9133 } 9134 9135 this.pressedFlag = true; 9136 9137 this.fakeElement.addClass(this.options.pressedClass); 9138 9139 this.doc.on('jcf-pointerup', this.onSelectAreaRelease); 9140 9141 }, 9142 9143 onSelectAreaRelease: function(e) { 9144 9145 if(this.focusedFlag && e.pointerType === 'mouse') { 9146 9147 this.realElement.focus(); 9148 9149 } 9150 9151 this.pressedFlag = false; 9152 9153 this.fakeElement.removeClass(this.options.pressedClass); 9154 9155 this.doc.off('jcf-pointerup', this.onSelectAreaRelease); 9156 9157 }, 9158 9159 onOutsideClick: function(e) { 9160 9161 var target = $(e.target), 9162 9163 clickedInsideSelect = target.closest(this.fakeElement).length || target.closest(this.dropdown).length; 9164 9165 9166 9167 if(!clickedInsideSelect) { 9168 9169 this.hideDropdown(); 9170 9171 } 9172 9173 }, 9174 9175 onSelect: function() { 9176 9177 this.hideDropdown(); 9178 9179 this.refresh(); 9180 9181 this.fireNativeEvent(this.realElement, 'change'); 9182 9183 }, 9184 9185 toggleListMode: function(state) { 9186 9187 if(!this.options.wrapNative) { 9188 9189 if(state) { 9190 9191 // temporary change select to list to avoid appearing of native dropdown 9192 9193 this.realElement.attr({ 9194 9195 size: 4, 9196 9197 'jcf-size': '' 9198 9199 }); 9200 9201 } else { 9202 9203 // restore select from list mode to dropdown select 9204 9205 if(!this.options.wrapNative) { 9206 9207 this.realElement.removeAttr('size jcf-size'); 9208 9209 } 9210 9211 } 9212 9213 } 9214 9215 }, 9216 9217 createDropdown: function() { 9218 9219 // destroy previous dropdown if needed 9220 9221 if(this.dropdown) { 9222 9223 this.list.destroy(); 9224 9225 this.dropdown.remove(); 9226 9227 } 9228 9229 9230 9231 // create new drop container 9232 9233 this.dropdown = $(this.options.fakeDropStructure).appendTo(this.fakeDropTarget); 9234
9235 this.dropdown.addClass(getPrefixedClasses(this.realElement.prop('className'), this.options.selectClassPrefix)); 9236 9237 makeUnselectable(this.dropdown); 9238 9239 9240 9241 // set initial styles for dropdown in body 9242 9243 if(this.options.fakeDropInBody) { 9244 9245 this.dropdown.css({ 9246 9247 position: 'absolute', 9248 9249 top: -9999 9250 9251 }); 9252 9253 } 9254 9255 9256 9257 // create new select list instance 9258 9259 this.list = new SelectList({ 9260 9261 useHoverClass: true, 9262 9263 handleResize: false, 9264 9265 alwaysPreventMouseWheel: true, 9266 9267 maxVisibleItems: this.options.maxVisibleItems, 9268 9269 useCustomScroll: this.options.useCustomScroll, 9270 9271 holder: this.dropdown.find(this.options.dropContentSelector), 9272 9273 element: this.realElement 9274 9275 }); 9276 9277 $(this.list).on({ 9278 9279 select: this.onSelect, 9280 9281 press: this.onSelectDropPress, 9282 9283 release: this.onSelectDropRelease 9284 9285 }); 9286 9287 }, 9288 9289 repositionDropdown: function() { 9290 9291 var selectOffset = this.fakeElement.offset(), 9292 9293 selectWidth = this.fakeElement.outerWidth(), 9294 9295 selectHeight = this.fakeElement.outerHeight(), 9296 9297 dropHeight = this.dropdown.outerHeight(), 9298 9299 winScrollTop = this.win.scrollTop(), 9300 9301 winHeight = this.win.height(), 9302 9303 calcTop, calcLeft, bodyOffset, needFlipDrop = false; 9304 9305 9306 9307 // check flip drop position 9308 9309 if(selectOffset.top + selectHeight + dropHeight > winScrollTop + winHeight && selectOffset.top - dropHeight > winScrollTop) { 9310 9311 needFlipDrop = true; 9312 9313 } 9314 9315 9316 9317 if(this.options.fakeDropInBody) { 9318 9319 bodyOffset = this.fakeDropTarget.css('position') !== 'static' ? this.fakeDropTarget.offset().top : 0; 9320 9321 if(this.options.flipDropToFit && needFlipDrop) { 9322 9323 // calculate flipped dropdown position 9324 9325 calcLeft = selectOffset.left; 9326 9327 calcTop = selectOffset.top - dropHeight - bodyOffset; 9328 9329 } else { 9330 9331 // calculate default drop position 9332 9333 calcLeft = selectOffset.left; 9334 9335 calcTop = selectOffset.top + selectHeight - bodyOffset; 9336 9337 } 9338 9339 9340 9341 // update drop styles 9342 9343 this.dropdown.css({ 9344 9345 width: selectWidth, 9346 9347 left: calcLeft, 9348 9349 top: calcTop 9350 9351 }); 9352 9353 } 9354 9355 9356 9357 // refresh flipped class 9358 9359 this.dropdown.add(this.fakeElement).toggleClass(this.options.flipDropClass, this.options.flipDropToFit && needFlipDrop); 9360 9361 }, 9362 9363 showDropdown: function() { 9364 9365 // create options list if not created 9366 9367 if(!this.dropdown) { 9368 9369 this.createDropdown(); 9370 9371 } 9372 9373 9374 9375 // show dropdown 9376 9377 this.dropActive = true; 9378 9379 this.dropdown.appendTo(this.fakeDropTarget); 9380 9381 this.fakeElement.addClass(this.options.dropActiveClass); 9382 9383 this.refreshSelectedText(); 9384 9385 this.repositionDropdown(); 9386 9387 this.list.setScrollTop(this.savedScrollTop); 9388 9389 this.list.refresh(); 9390 9391 9392 9393 // add temporary event handlers 9394 9395 this.win.on('resize', this.onResize); 9396 9397 this.doc.on('jcf-pointerdown', this.onOutsideClick); 9398 9399 }, 9400 9401 hideDropdown: function() { 9402 9403 if(this.dropdown) { 9404 9405 this.savedScrollTop = this.list.getScrollTop(); 9406 9407 this.fakeElement.removeClass(this.options.dropActiveClass + ' ' + this.options.flipDropClass); 9408 9409 this.dropdown.removeClass(this.options.flipDropClass).detach(); 9410 9411 this.doc.off('jcf-pointerdown', this.onOutsideClick); 9412 9413 this.win.off('resize', this.onResize); 9414 9415 this.dropActive = false; 9416 9417 } 9418 9419 }, 9420 9421 toggleDropdown: function() { 9422 9423 if(this.dropActive) { 9424 9425 this.hideDropdown(); 9426 9427 } else { 9428 9429 this.showDropdown(); 9430 9431 } 9432 9433 }, 9434 9435 refreshSelectedText: function() { 9436 9437 // redraw selected area 9438 9439 var selectedIndex = this.realElement.prop('selectedIndex'), 9440 9441 selectedOption = this.realElement.prop('options')[selectedIndex], 9442 9443 selectedOptionImage = selectedOption.getAttribute('data-image'), 9444 9445 selectedOptionClasses, 9446 9447 selectedFakeElement; 9448 9449 9450 9451 if(this.currentSelectedText !== selectedOption.innerHTML || this.currentSelectedImage !== selectedOptionImage) { 9452 9453 selectedOptionClasses = getPrefixedClasses(selectedOption.className, this.options.optionClassPrefix); 9454 9455 this.selectText.attr('class', selectedOptionClasses).html(selectedOption.innerHTML); 9456 9457 9458 9459 if(selectedOptionImage) { 9460 9461 if(!this.selectImage) { 9462 9463 this.selectImage = $('<img>').prependTo(this.selectTextContainer).hide(); 9464 9465 } 9466 9467 this.selectImage.attr('src', selectedOptionImage).show(); 9468 9469 } else if(this.selectImage) { 9470 9471 this.selectImage.hide(); 9472 9473 } 9474 9475 9476 9477 this.currentSelectedText = selectedOption.innerHTML; 9478 9479 this.currentSelectedImage = selectedOptionImage; 9480 9481 } 9482 9483 }, 9484 9485 refresh: function() { 9486 9487 // refresh fake select visibility 9488 9489 if(this.realElement.prop('style').display === 'none') { 9490 9491 this.fakeElement.hide(); 9492 9493 } else { 9494 9495 this.fakeElement.show(); 9496 9497 } 9498 9499 9500 9501 // refresh selected text 9502 9503 this.refreshSelectedText(); 9504 9505 9506 9507 // handle disabled state 9508 9509 this.fakeElement.toggleClass(this.options.disabledClass, this.realElement.is(':disabled')); 9510 9511 }, 9512 9513 destroy: function() { 9514 9515 // restore structure 9516 9517 if(this.options.wrapNative) { 9518 9519 this.realElement.insertBefore(this.fakeElement).css({ 9520 9521 position: '', 9522 9523 height: '', 9524 9525 width: '' 9526 9527 }).removeClass(this.options.resetAppearanceClass); 9528 9529 } else { 9530 9531 this.realElement.removeClass(this.options.hiddenClass); 9532 9533 if(this.realElement.is('[jcf-size]')) { 9534 9535 this.realElement.removeAttr('size jcf-size'); 9536 9537 } 9538 9539 } 9540 9541 9542 9543 // removing element will also remove its event handlers 9544 9545 this.fakeElement.remove(); 9546 9547 9548 9549 // remove other event handlers 9550 9551 this.doc.off('jcf-pointerup', this.onSelectAreaRelease); 9552 9553 this.realElement.off({ 9554 9555 focus: this.onFocus 9556 9557 }); 9558 9559 } 9560 9561 }); 9562 9563 9564 9565 // listbox module 9566 9567 function ListBox(options) { 9568 9569 this.options = $.extend({ 9570 9571 wrapNative: true, 9572 9573 useCustomScroll: true, 9574 9575 fakeStructure: '<span class="jcf-list-box"><span class="jcf-list-wrapper"></span></span>', 9576 9577 selectClassPrefix: 'jcf-select-', 9578 9579 listHolder: '.jcf-list-wrapper' 9580 9581 }, options); 9582 9583 this.init(); 9584 9585 } 9586 9587 $.extend(ListBox.prototype, { 9588 9589 init: function(options) { 9590 9591 this.bindHandlers(); 9592 9593 this.initStructure(); 9594 9595 this.attachEvents(); 9596 9597 }, 9598 9599 initStructure: function() { 9600 9601 var self = this; 9602 9603 this.realElement = $(this.options.element); 9604 9605 this.fakeElement = $(this.options.fakeStructure).insertAfter(this.realElement); 9606 9607 this.listHolder = this.fakeElement.find(this.options.listHolder); 9608 9609 makeUnselectable(this.fakeElement); 9610 9611 9612 9613 // copy classes from original select 9614
9615 this.fakeElement.addClass(getPrefixedClasses(this.realElement.prop('className'), this.options.selectClassPrefix)); 9616 9617 this.realElement.addClass(this.options.hiddenClass); 9618 9619 9620 9621 this.list = new SelectList({ 9622 9623 useCustomScroll: this.options.useCustomScroll, 9624 9625 holder: this.listHolder, 9626 9627 selectOnClick: false, 9628 9629 element: this.realElement 9630 9631 }); 9632 9633 }, 9634 9635 attachEvents: function() { 9636 9637 // delayed refresh handler 9638 9639 var self = this; 9640 9641 this.delayedRefresh = function() { 9642 9643 clearTimeout(self.refreshTimer); 9644 9645 self.refreshTimer = setTimeout(function() { 9646 9647 self.refresh(); 9648 9649 }, 1); 9650 9651 }; 9652 9653 9654 9655 // other event handlers 9656 9657 this.realElement.on({ 9658 9659 focus: this.onFocus, 9660 9661 click: this.delayedRefresh, 9662 9663 keydown: this.delayedRefresh 9664 9665 }); 9666 9667 9668 9669 // select list event handlers 9670 9671 $(this.list).on({ 9672 9673 select: this.onSelect, 9674 9675 press: this.onFakeOptionsPress, 9676 9677 release: this.onFakeOptionsRelease 9678 9679 }); 9680 9681 }, 9682 9683 onFakeOptionsPress: function(e, pointerEvent) { 9684 9685 this.pressedFlag = true; 9686 9687 if(pointerEvent.pointerType === 'mouse') { 9688 9689 this.realElement.focus(); 9690 9691 } 9692 9693 }, 9694 9695 onFakeOptionsRelease: function(e, pointerEvent) { 9696 9697 this.pressedFlag = false; 9698 9699 if(pointerEvent.pointerType === 'mouse') { 9700 9701 this.realElement.focus(); 9702 9703 } 9704 9705 }, 9706 9707 onSelect: function() { 9708 9709 this.fireNativeEvent(this.realElement, 'change'); 9710 9711 this.fireNativeEvent(this.realElement, 'click'); 9712 9713 }, 9714 9715 onFocus: function() { 9716 9717 if(!this.pressedFlag || !this.focusedFlag) { 9718 9719 this.fakeElement.addClass(this.options.focusClass); 9720 9721 this.realElement.on('blur', this.onBlur); 9722 9723 this.focusedFlag = true; 9724 9725 } 9726 9727 }, 9728 9729 onBlur: function() { 9730 9731 if(!this.pressedFlag) { 9732 9733 this.fakeElement.removeClass(this.options.focusClass); 9734 9735 this.realElement.off('blur', this.onBlur); 9736 9737 this.focusedFlag = false; 9738 9739 } 9740 9741 }, 9742 9743 refresh: function() { 9744 9745 this.fakeElement.toggleClass(this.options.disabledClass, this.realElement.is(':disabled')); 9746 9747 this.list.refresh(); 9748 9749 }, 9750 9751 destroy: function() { 9752 9753 this.list.destroy(); 9754 9755 this.realElement.insertBefore(this.fakeElement).removeClass(this.options.hiddenClass); 9756 9757 this.fakeElement.remove(); 9758 9759 } 9760 9761 }); 9762 9763 9764 9765 // options list module 9766 9767 function SelectList(options) { 9768 9769 this.options = $.extend({ 9770 9771 holder: null, 9772 9773 maxVisibleItems: 10, 9774 9775 selectOnClick: true, 9776 9777 useHoverClass: false, 9778 9779 useCustomScroll: false, 9780 9781 handleResize: true, 9782 9783 alwaysPreventMouseWheel: false, 9784 9785 indexAttribute: 'data-index', 9786 9787 cloneClassPrefix: 'jcf-option-', 9788 9789 containerStructure: '<span class="jcf-list"><span class="jcf-list-content"></span></span>', 9790 9791 containerSelector: '.jcf-list-content', 9792 9793 captionClass: 'jcf-optgroup-caption', 9794 9795 disabledClass: 'jcf-disabled', 9796 9797 optionClass: 'jcf-option', 9798 9799 groupClass: 'jcf-optgroup', 9800 9801 hoverClass: 'jcf-hover', 9802 9803 selectedClass: 'jcf-selected', 9804 9805 scrollClass: 'jcf-scroll-active' 9806 9807 }, options); 9808 9809 this.init(); 9810 9811 } 9812 9813 $.extend(SelectList.prototype, { 9814 9815 init: function() { 9816 9817 this.initStructure(); 9818 9819 this.refreshSelectedClass(); 9820 9821 this.attachEvents(); 9822 9823 }, 9824 9825 initStructure: function() { 9826 9827 this.element = $(this.options.element); 9828 9829 this.indexSelector = '[' + this.options.indexAttribute + ']'; 9830 9831 this.container = $(this.options.containerStructure).appendTo(this.options.holder); 9832 9833 this.listHolder = this.container.find(this.options.containerSelector); 9834 9835 this.lastClickedIndex = this.element.prop('selectedIndex'); 9836 9837 this.rebuildList(); 9838 9839 }, 9840 9841 attachEvents: function() { 9842 9843 this.bindHandlers(); 9844 9845 this.listHolder.on('jcf-pointerdown', this.indexSelector, this.onItemPress); 9846 9847 this.listHolder.on('jcf-pointerdown', this.onPress); 9848 9849 9850 9851 if(this.options.useHoverClass) { 9852 9853 this.listHolder.on('jcf-pointerover', this.indexSelector, this.onHoverItem); 9854 9855 } 9856 9857 }, 9858 9859 onPress: function(e) { 9860 9861 $(this).trigger('press', e); 9862 9863 this.listHolder.on('jcf-pointerup', this.onRelease); 9864 9865 }, 9866 9867 onRelease: function(e) { 9868 9869 $(this).trigger('release', e); 9870 9871 this.listHolder.off('jcf-pointerup', this.onRelease); 9872 9873 }, 9874 9875 onHoverItem: function(e) { 9876 9877 var hoverIndex = parseFloat(e.currentTarget.getAttribute(this.options.indexAttribute)); 9878 9879 this.fakeOptions.removeClass(this.options.hoverClass).eq(hoverIndex).addClass(this.options.hoverClass); 9880 9881 }, 9882 9883 onItemPress: function(e) { 9884 9885 if(e.pointerType === 'touch' || this.options.selectOnClick) { 9886 9887 // select option after "click" 9888 9889 this.tmpListOffsetTop = this.list.offset().top; 9890 9891 this.listHolder.on('jcf-pointerup', this.indexSelector, this.onItemRelease); 9892 9893 } else { 9894 9895 // select option immediately 9896 9897 this.onSelectItem(e); 9898 9899 } 9900 9901 }, 9902 9903 onItemRelease: function(e) { 9904 9905 // remove event handlers and temporary data 9906 9907 this.listHolder.off('jcf-pointerup', this.indexSelector, this.onItemRelease); 9908 9909 9910 9911 // simulate item selection 9912 9913 if(this.tmpListOffsetTop === this.list.offset().top) { 9914 9915 this.listHolder.on('click', this.indexSelector, this.onSelectItem); 9916 9917 } 9918 9919 delete this.tmpListOffsetTop; 9920 9921 }, 9922 9923 onSelectItem: function(e) { 9924 9925 var clickedIndex = parseFloat(e.currentTarget.getAttribute(this.options.indexAttribute)), 9926 9927 range; 9928 9929 9930 9931 // remove click event handler 9932 9933 this.listHolder.off('click', this.indexSelector, this.onSelectItem); 9934 9935 9936 9937 // ignore clicks on disabled options 9938 9939 if(e.button > 1 || this.realOptions[clickedIndex].disabled) { 9940 9941 return; 9942 9943 } 9944 9945 9946 9947 if(this.element.prop('multiple')) { 9948 9949 if(e.metaKey || e.ctrlKey || e.pointerType === 'touch') { 9950 9951 // if CTRL/CMD pressed or touch devices - toggle selected option 9952 9953 this.realOptions[clickedIndex].selected = !this.realOptions[clickedIndex].selected; 9954 9955 } else if(e.shiftKey) { 9956 9957 // if SHIFT pressed - update selection 9958 9959 range = [this.lastClickedIndex, clickedIndex].sort(function(a, b){ 9960 9961 return a - b; 9962 9963 }); 9964 9965 this.realOptions.each(function(index, option) { 9966 9967 option.selected = (index >= range[0] && index <= range[1]); 9968 9969 }); 9970 9971 } else { 9972 9973 // set single selected index 9974 9975 this.element.prop('selectedIndex', clickedIndex); 9976 9977 } 9978 9979 } else { 9980 9981 this.element.prop('selectedIndex', clickedIndex); 9982 9983 } 9984 9985 9986 9987 // save last clicked option 9988 9989 if(!e.shiftKey) { 9990 9991 this.lastClickedIndex = clickedIndex; 9992 9993 } 9994 9995 9996 9997 // refresh classes 9998 9999 this.refreshSelectedClass(); 10000 10001 10002 10003 // scroll to active item in desktop browsers 10004 10005 if(e.pointerType === 'mouse') { 10006 10007 this.scrollToActiveOption(); 10008 10009 } 10010 10011 10012 10013 // make callback when item selected 10014 10015 $(this).trigger('select'); 10016 10017 }, 10018 10019 rebuildList: function() { 10020 10021 // rebuild options 10022 10023 var self = this, 10024 10025 rootElement = this.element[0]; 10026 10027 10028 10029 // recursively create fake options 10030 10031 this.storedSelectHTML = rootElement.innerHTML; 10032 10033 this.optionIndex = 0; 10034 10035 this.list = $(this.createOptionsList(rootElement)); 10036 10037 this.listHolder.empty().append(this.list); 10038 10039 this.realOptions = this.element.find('option'); 10040 10041 this.fakeOptions = this.list.find(this.indexSelector); 10042 10043 this.fakeListItems = this.list.find('.' + this.options.captionClass + ',' + this.indexSelector); 10044 10045 delete this.optionIndex; 10046 10047 10048 10049 // detect max visible items 10050 10051 var maxCount = this.options.maxVisibleItems, 10052 10053 sizeValue = this.element.prop('size'); 10054 10055 if(sizeValue > 1) { 10056 10057 maxCount = sizeValue; 10058 10059 } 10060 10061 10062 10063 // handle scrollbar 10064 10065 var needScrollBar = this.fakeOptions.length > maxCount; 10066 10067 this.container.toggleClass(this.options.scrollClass, needScrollBar); 10068 10069 if(needScrollBar) { 10070 10071 // change max-height 10072 10073 this.listHolder.css({ 10074 10075 maxHeight: this.getOverflowHeight(maxCount), 10076 10077 overflow: 'auto' 10078 10079 }); 10080 10081 10082 10083 if(this.options.useCustomScroll && jcf.modules.Scrollable) { 10084 10085 // add custom scrollbar if specified in options 10086 10087 jcf.replace(this.listHolder, 'Scrollable', { 10088 10089 handleResize: this.options.handleResize, 10090 10091 alwaysPreventMouseWheel: this.options.alwaysPreventMouseWheel 10092 10093 }); 10094 10095 return; 10096 10097 } 10098 10099 } 10100 10101 10102 10103 // disable edge wheel scrolling 10104 10105 if(this.options.alwaysPreventMouseWheel) { 10106 10107 this.preventWheelHandler = function(e) { 10108 10109 var currentScrollTop = self.listHolder.scrollTop(), 10110 10111 maxScrollTop = self.listHolder.prop('scrollHeight') - self.listHolder.innerHe
10111ight(), 10112 10113 maxScrollLeft = self.listHolder.prop('scrollWidth') - self.listHolder.innerWidth(); 10114 10115 10116 10117 // check edge cases 10118 10119 if((currentScrollTop <= 0 && e.deltaY < 0) || (currentScrollTop >= maxScrollTop && e.deltaY > 0)) { 10120 10121 e.preventDefault(); 10122 10123 } 10124 10125 }; 10126 10127 this.listHolder.on('jcf-mousewheel', this.preventWheelHandler); 10128 10129 } 10130 10131 }, 10132 10133 refreshSelectedClass: function() { 10134 10135 var self = this, 10136 10137 selectedItem, 10138 10139 isMultiple = this.element.prop('multiple'), 10140 10141 selectedIndex = this.element.prop('selectedIndex'); 10142 10143 10144 10145 if(isMultiple) { 10146 10147 this.realOptions.each(function(index, option) { 10148 10149 self.fakeOptions.eq(index).toggleClass(self.options.selectedClass, !!option.selected); 10150 10151 }); 10152 10153 } else { 10154 10155 this.fakeOptions.removeClass(this.options.selectedClass + ' ' + this.options.hoverClass); 10156 10157 selectedItem = this.fakeOptions.eq(selectedIndex).addClass(this.options.selectedClass); 10158 10159 if(this.options.useHoverClass) { 10160 10161 selectedItem.addClass(this.options.hoverClass); 10162 10163 } 10164 10165 } 10166 10167 }, 10168 10169 scrollToActiveOption: function() { 10170 10171 // scroll to target option 10172 10173 var targetOffset = this.getActiveOptionOffset(); 10174 10175 this.listHolder.prop('scrollTop', targetOffset); 10176 10177 }, 10178 10179 getSelectedIndexRange: function() { 10180 10181 var firstSelected = -1, lastSelected = -1; 10182 10183 this.realOptions.each(function(index, option) { 10184 10185 if(option.selected) { 10186 10187 if(firstSelected < 0) { 10188 10189 firstSelected = index; 10190 10191 } 10192 10193 lastSelected = index; 10194 10195 } 10196 10197 }); 10198 10199 return [firstSelected, lastSelected]; 10200 10201 }, 10202 10203 getChangedSelectedIndex: function() { 10204 10205 var selectedIndex = this.element.prop('selectedIndex'), 10206 10207 targetIndex; 10208 10209 10210 10211 if(this.element.prop('multiple')) { 10212 10213 // multiple selects handling 10214 10215 if(!this.previousRange) { 10216 10217 this.previousRange = [selectedIndex, selectedIndex]; 10218 10219 } 10220 10221 this.currentRange = this.getSelectedIndexRange(); 10222 10223 targetIndex = this.currentRange[this.currentRange[0] !== this.previousRange[0] ? 0 : 1]; 10224 10225 this.previousRange = this.currentRange; 10226 10227 return targetIndex; 10228 10229 } else { 10230 10231 // single choice selects handling 10232 10233 return selectedIndex; 10234 10235 } 10236 10237 }, 10238 10239 getActiveOptionOffset: function() { 10240 10241 // calc values 10242 10243 var dropHeight = this.listHolder.height(), 10244 10245 dropScrollTop = this.listHolder.prop('scrollTop'), 10246 10247 currentIndex = this.getChangedSelectedIndex(), 10248 10249 fakeOption = this.fakeOptions.eq(currentIndex), 10250 10251 fakeOptionOffset = fakeOption.offset().top - this.list.offset().top, 10252 10253 fakeOptionHeight = fakeOption.innerHeight(); 10254 10255 10256 10257 // scroll list 10258 10259 if(fakeOptionOffset + fakeOptionHeight >= dropScrollTop + dropHeight) { 10260 10261 // scroll down (always scroll to option) 10262 10263 return fakeOptionOffset - dropHeight + fakeOptionHeight; 10264 10265 } else if(fakeOptionOffset < dropScrollTop) { 10266 10267 // scroll up to option 10268 10269 return fakeOptionOffset; 10270 10271 } 10272 10273 }, 10274 10275 getOverflowHeight: function(sizeValue) { 10276 10277 var item = this.fakeListItems.eq(sizeValue - 1), 10278 10279 listOffset = this.list.offset().top, 10280 10281 itemOffset = item.offset().top, 10282 10283 itemHeight = item.innerHeight(); 10284 10285 10286 10287 return itemOffset + itemHeight - listOffset; 10288 10289 }, 10290 10291 getScrollTop: function() { 10292 10293 return this.listHolder.scrollTop(); 10294 10295 }, 10296 10297 setScrollTop: function(value) { 10298 10299 this.listHolder.scrollTop(value); 10300 10301 }, 10302 10303 createOption: function(option) { 10304 10305 var newOption = document.createElement('span'); 10306 10307 newOption.className = this.options.optionClass; 10308 10309 newOption.innerHTML = option.innerHTML; 10310 10311 newOption.setAttribute(this.options.indexAttribute, this.optionIndex++); 10312 10313 10314 10315 var optionImage, optionImageSrc = option.getAttribute('data-image'); 10316 10317 if(optionImageSrc) { 10318 10319 optionImage = document.createElement('img'); 10320 10321 optionImage.src = optionImageSrc; 10322 10323 newOption.insertBefore(optionImage, newOption.childNodes[0]); 10324 10325 } 10326 10327 if(option.disabled) { 10328 10329 newOption.className += ' ' + this.options.disabledClass; 10330 10331 } 10332 10333 if(option.className) { 10334 10335 newOption.className += ' ' + getPrefixedClasses(option.className, this.options.cloneClassPrefix); 10336 10337 } 10338 10339 return newOption; 10340 10341 }, 10342 10343 createOptGroup: function(optgroup) { 10344 10345 var optGroupContainer = document.createElement('span'), 10346 10347 optGroupName = optgroup.getAttribute('label'), 10348 10349 optGroupCaption, optGroupList; 10350 10351 10352 10353 // create caption 10354 10355 optGroupCaption = document.createElement('span'); 10356 10357 optGroupCaption.className = this.options.captionClass; 10358 10359 optGroupCaption.innerHTML = optGroupName; 10360 10361 optGroupContainer.appendChild(optGroupCaption); 10362 10363 10364 10365 // create list of options 10366 10367 if(optgroup.children.length) { 10368 10369 optGroupList = this.createOptionsList(optgroup); 10370 10371 optGroupContainer.appendChild(optGroupList); 10372 10373 } 10374 10375 10376 10377 optGroupContainer.className = this.options.groupClass; 10378 10379 return optGroupContainer; 10380 10381 }, 10382 10383 createOptionContainer: function() { 10384 10385 var optionContainer = document.createElement('li'); 10386 10387 return optionContainer; 10388 10389 }, 10390 10391 createOptionsList: function(container) { 10392 10393 var self = this, 10394 10395 list = document.createElement('ul'); 10396 10397 10398 10399 $.each(container.children, function(index, currentNode) { 10400 10401 var item = self.createOptionContainer(currentNode), 10402 10403 newNode; 10404 10405 10406 10407 switch(currentNode.tagName.toLowerCase()) { 10408 10409 case 'option': newNode = self.createOption(currentNode); break; 10410 10411 case 'optgroup': newNode = self.createOptGroup(currentNode); break; 10412 10413 } 10414 10415 list.appendChild(item).appendChild(newNode); 10416 10417 }); 10418 10419 return list; 10420 10421 }, 10422 10423 refresh: function() { 10424 10425 // check for select innerHTML changes 10426 10427 if(this.storedSelectHTML !== this.element.prop('innerHTML')) { 10428 10429 this.rebuildList(); 10430 10431 } 10432 10433 10434 10435 // refresh custom scrollbar 10436 10437 var scrollInstance = jcf.getInstance(this.listHolder); 10438 10439 if(scrollInstance) { 10440 10441 scrollInstance.refresh(); 10442 10443 } 10444 10445 10446 10447 // scroll active option into view 10448 10449 this.scrollToActiveOption(); 10450 10451 10452 10453 // refresh selectes classes 10454 10455 this.refreshSelectedClass(); 10456 10457 }, 10458 10459 destroy: function() { 10460 10461 this.listHolder.off('jcf-mousewheel', this.preventWheelHandler); 10462 10463 this.listHolder.off('jcf-pointerdown', this.indexSelector, this.onSelectItem); 10464 10465 this.listHolder.off('jcf-pointerover', this.indexSelector, this.onHoverItem); 10466 10467 this.listHolder.off('jcf-pointerdown', this.onPress); 10468 10469 } 10470 10471 }); 10472 10473 10474 10475 // helper functions 10476
10477 var getPrefixedClasses = function(className, prefixToAdd) { 10478 10479 return className ? className.replace(/[\s]*([\S]+)+[\s]*/gi, prefixToAdd + '$1 ') : ''; 10480 10481 }; 10482 10483 var makeUnselectable = (function() { 10484 10485 var unselectableClass = jcf.getOptions().unselectableClass; 10486 10487 function preventHandler(e) { 10488 10489 e.preventDefault(); 10490 10491 } 10492 10493 return function(node) { 10494 10495 node.addClass(unselectableClass).on('selectstart', preventHandler); 10496 10497 }; 10498 10499 }()); 10500 10501 10502 10503}(jQuery, this)); 10504 10505 10506 10507 10508 10509/*!* SmoothScroll module*/ 10510 10511 10512 10513;(function($, exports) { 10514 10515 // private variables 10516 10517 var page, 10518 10519 win = $(window), 10520 10521 activeBlock, activeWheelHandler, 10522 10523 wheelEvents = ('onwheel' in document || document.documentMode >= 9 ? 'wheel' : 'mousewheel DOMMouseScroll'); 10524 10525 10526 10527 // animation handlers 10528 10529 function scrollTo(offset, options, callback) { 10530 10531 // initialize variables 10532 10533 var scrollBlock; 10534 10535 if (document.body) { 10536 10537 if (typeof options === 'number') { 10538 10539 options = { duration: options }; 10540 10541 } else { 10542 10543 options = options || {}; 10544 10545 } 10546 10547 page = page || $('html, body'); 10548 10549 scrollBlock = options.container || page; 10550 10551 } else { 10552 10553 return; 10554 10555 } 10556 10557 10558 10559 // treat single number as scrollTop 10560 10561 if (typeof offset === 'number') { 10562 10563 offset = { top: offset }; 10564 10565 } 10566 10567 10568 10569 // handle mousewheel/trackpad while animation is active 10570 10571 if (activeBlock && activeWheelHandler) { 10572 10573 activeBlock.off(wheelEvents, activeWheelHandler); 10574 10575 } 10576 10577 if (options.wheelBehavior && options.wheelBehavior !== 'none') { 10578 10579 activeWheelHandler = function(e) { 10580 10581 if (options.wheelBehavior === 'stop') { 10582 10583 scrollBlock.off(wheelEvents, activeWheelHandler); 10584 10585 scrollBlock.stop(); 10586 10587 } else if (options.wheelBehavior === 'ignore') { 10588 10589 e.preventDefault(); 10590 10591 } 10592 10593 }; 10594 10595 activeBlock = scrollBlock.on(wheelEvents, activeWheelHandler); 10596 10597 } 10598 10599 10600 10601 // start scrolling animation 10602 10603 scrollBlock.stop().animate({ 10604 10605 scrollLeft: offset.left, 10606 10607 scrollTop: offset.top 10608 10609 }, options.duration, function() { 10610 10611 if (activeWheelHandler) { 10612 10613 scrollBlock.off(wheelEvents, activeWheelHandler); 10614 10615 } 10616 10617 if ($.isFunction(callback)) { 10618 10619 callback(); 10620 10621 } 10622 10623 }); 10624 10625 } 10626 10627 10628 10629 // smooth scroll contstructor 10630 10631 function SmoothScroll(options) { 10632 10633 this.options = $.extend({ 10634 10635 anchorLinks: 'a[href^="#"]', // selector or jQuery object 10636 10637 container: null, // specify container for scrolling (default - whole page) 10638 10639 extraOffset: null, // function or fixed number 10640 10641 activeClasses: null, // null, "link", "parent" 10642 10643 easing: 'swing', // easing of scrolling 10644 10645 animMode: 'duration', // or "speed" mode 10646 10647 animDuration: 800, // total duration for scroll (any distance) 10648 10649 animSpeed: 1500, // pixels per second 10650 10651 anchorActiveClass: 'active', 10652 10653 sectionActiveClass: 'section-active', 10654 10655 wheelBehavior: 'stop', // "stop", "ignore" or "none" 10656 10657 useNativeAnchorScrolling: false // do not handle click in devices with native smooth scrolling 10658 10659 }, options); 10660 10661 this.init(); 10662 10663 } 10664 10665 SmoothScroll.prototype = { 10666 10667 init: function() { 10668 10669 this.initStructure(); 10670 10671 this.attachEvents(); 10672 10673 }, 10674 10675 initStructure: function() { 10676 10677 this.container = this.options.container ? $(this.options.container) : $('html,body'); 10678 10679 this.scrollContainer = this.options.container ? this.container : win; 10680 10681 this.anchorLinks = $(this.options.anchorLinks); 10682 10683 }, 10684 10685 getAnchorTarget: function(link) { 10686 10687 // get target block from link href 10688 10689 var targetId = $(link).attr('href'); 10690 10691 return $(targetId.length > 1 ? targetId : 'html'); 10692 10693 }, 10694 10695 getTargetOffset: function(block) { 10696 10697 // get target offset 10698 10699 var blockOffset = block.offset().top; 10700 10701 if (this.options.container) { 10702 10703 blockOffset -= this.container.offset().top - this.container.prop('scrollTop'); 10704 10705 } 10706 10707 10708 10709 // handle extra offset 10710 10711 if (typeof this.options.extraOffset === 'number') { 10712 10713 blockOffset -= this.options.extraOffset; 10714 10715 } else if (typeof this.options.extraOffset === 'function') { 10716 10717 blockOffset -= this.options.extraOffset(block); 10718 10719 } 10720 10721 return { top: blockOffset }; 10722 10723 }, 10724 10725 attachEvents: function() { 10726 10727 var self = this; 10728 10729 10730 10731 // handle active classes 10732 10733 if (this.options.activeClasses) { 10734 10735 // cache structure 10736 10737 this.anchorData = []; 10738 10739 this.anchorLinks.each(function() { 10740 10741 var link = jQuery(this), 10742 10743 targetBlock = self.getAnchorTarget(link), 10744 10745 anchorDataItem; 10746 10747 10748 10749 $.each(self.anchorData, function(index, item) { 10750 10751 if (item.block[0] === targetBlock[0]) { 10752 10753 anchorDataItem = item; 10754 10755 } 10756 10757 }); 10758 10759 10760 10761 if (anchorDataItem) { 10762 10763 anchorDataItem.link = anchorDataItem.link.add(link); 10764 10765 } else { 10766 10767 self.anchorData.push({ 10768 10769 link: link, 10770 10771 block: targetBlock 10772 10773 }); 10774 10775 } 10776 10777 }); 10778 10779 10780 10781 // add additional event handlers 10782 10783 this.resizeHandler = function() { 10784 10785 self.recalculateOffsets(); 10786 10787 }; 10788 10789 this.scrollHandler = function() { 10790 10791 self.refreshActiveClass(); 10792 10793 }; 10794 10795 10796 10797 this.recalculateOffsets(); 10798 10799 this.scrollContainer.on('scroll', this.scrollHandler); 10800 10801 win.on('resize', this.resizeHandler); 10802 10803 } 10804 10805 10806 10807 // handle click event 10808 10809 this.clickHandler = function(e) { 10810 10811 self.onClick(e); 10812 10813 }; 10814 10815 if (!this.options.useNativeAnchorScrolling) { 10816 10817 this.anchorLinks.on('click', this.clickHandler); 10818 10819 } 10820 10821 }, 10822 10823 recalculateOffsets: function() { 10824 10825 var self = this; 10826 10827 $.each(this.anchorData, function(index, data) { 10828 10829 data.offset = self.getTargetOffset(data.block); 10830 10831 data.height = data.block.outerHeight(); 10832 10833 }); 10834 10835 this.refreshActiveClass(); 10836 10837 }, 10838 10839 refreshActiveClass: function() { 10840 10841 var self = this, 10842 10843 foundFlag = false, 10844 10845 containerHeight = this.container.prop('scrollHeight'), 10846 10847 viewPortHeight = this.scrollContainer.height(), 10848 10849 scrollTop = this.options.container ? this.container.prop('scrollTop') : win.scrollTop(); 10850 10851 10852 10853 // user function instead of default handler 10854 10855 if (this.options.customScrollHandler) { 10856 10857 this.options.customScrollHandler.call(this, scrollTop, this.anchorData); 10858 10859 return; 10860 10861 } 10862 10863 10864 10865 // sort anchor data by offsets 10866 10867 this.anchorData.sort(function(a, b) { 10868 10869 return a.offset.top - b.offset.top; 10870 10871 }); 10872 10873 function toggleActiveClass(anchor, block, state) { 10874 10875 anchor.toggleClass(self.options.anchorActiveClass, state); 10876 10877 block.toggleClass(self.options.sectionActiveClass, state); 10878 10879 } 10880 10881 10882 10883 // default active class handler 10884 10885 $.each(this.anchorData, function(index) { 10886 10887 var reverseIndex = self.anchorData.length - index - 1, 10888 10889 data = self.anchorData[reverseIndex], 10890 10891 anchorElement = (self.options.activeClasses === 'parent' ? data.link.parent() : data.link); 10892 10893 10894 10895 if (scrollTop >= containerHeight - viewPortHeight) { 10896 10897 // handle last section 10898 10899 if (reverseIndex === self.anchorData.length - 1) { 10900 10901 toggleActiveClass(anchorElement, data.block, true); 10902 10903 } else { 10904 10905 toggleActiveClass(anchorElement, data.block, false); 10906 10907 } 10908 10909 } else { 10910 10911 // handle other sections 10912 10913 if (!foundFlag && (scrollTop >= data.offset.top - 1 || reverseIndex === 0)) { 10914 10915 foundFlag = true; 10916 10917 toggleActiveClass(anchorElement, data.block, true); 10918 10919 } else { 10920 10921 toggleActiveClass(anchorElement, data.block, false); 10922 10923 } 10924 10925 } 10926 10927 }); 10928 10929 }, 10930 10931 calculateScrollDuration: function(offset) { 10932 10933 var distance; 10934 10935 if (this.options.animMode === 'speed') { 10936 10937 distance = Math.abs(this.scrollContainer.scrollTop() - offset.top); 10938 10939 return (distance / this.options.animSpeed) * 1000; 10940 10941 } else { 10942 10943 return this.options.animDuration; 10944 10945 } 10946 10947 }, 10948 10949 onClick: function(e) { 10950 10951 var targetBlock = this.getAnchorTarget(e.currentTarget), 10952 10953 targetOffset = this.getTargetOffset(targetBlock); 10954 10955 10956 10957 e.preventDefault(); 10958 10959 scrollTo(targetOffset, { 10960 10961 container: this.container, 10962 10963 wheelBehavior: this.options.wheelBehavior, 10964 10965 duration: this.calculateScrollDuration(targetOffset) 10966 10967 }); 10968 10969 }, 10970 10971 destroy: function() { 10972 10973 if (this.options.activeClasses) { 10974 10975 win.off('resize', this.resizeHandler); 10976 10977 this.scrollContainer.off('scroll', this.scrollHandler); 10978 10979 } 10980 10981 this.anchorLinks.off('click', this.clickHandler); 10982 10983 } 10984 10985 }; 10986 10987 10988 10989 // public API 10990 10991 $.extend(SmoothScroll, { 10992 10993 scrollTo: function(blockOrOffset, durationOrOptions, callback) { 10994 10995 scrollTo(blockOrOffset, durationOrOptions, callback); 10996 10997 } 10998 10999 }); 11000 11001 11002 11003 // export module 11004 11005 exports.SmoothScroll = SmoothScroll; 11006 11007}(jQuery, this)); 11008 11009 11010 11011/*! 11012 11013 * Google Map module 11014 11015 */ 11016 11017 11018 11019;(function($) { 11020 11021 function GoogleMapAPI(options) { 11022 11023 this.options = $.extend({ 11024 11025 mapTypeId: google.maps.MapTypeId.ROADMAP 11026 11027 }, options); 11028 11029 this.init(); 11030 11031 } 11032 11033 11034 11035 GoogleMapAPI.prototype = { 11036 11037 init: function() { 11038 11039 this.findStructure(); 11040 11041 this.getInfoWindowContent(); 11042 11043 this.createMap(); 11044 11045 this.createMarker(); 11046 11047 this.createInfoWindow(); 11048 11049 }, 11050 11051 11052 11053 findStructure: function() { 11054 11055 this.container = $(this.options.container); 11056 11057 this.lat = parseFloat(this.container.attr('data-lat')); 11058 11059 this.lng = parseFloat(this.container.attr('data-lng')); 11060 11061 this.coords = new google.maps.LatLng(this.lat, this.lng); 11062 11063 this.zoom = parseInt(this.container.attr('data-zoom')); 11064 11065 this.infoWindowContent = this.container.find('.map-info'); 11066 11067 this.mapOptions = { 11068 11069 mapTypeId: this.options.mapTypeId, 11070 11071 panControl: this.options.panControl, 11072 11073 zoomControl: this.options.zoomControl, 11074 11075 streetViewControl: this.options.streetViewControl, 11076 11077 mapTypeControl: this.options.mapTypeControl, 11078 11079 center: this.coords, 11080 11081 scrollwheel: this.options.scrollwheel, 11082 11083 zoom: this.zoom 11084 11085 }; 11086 11087 }, 11088 11089 11090 11091 getInfoWindowContent: function() { 11092 11093 this.infoWindowContent = this.container.find(this.options.mapInfoContent); 11094 11095 }, 11096 11097 11098 11099 createMap: function() { 11100 11101 this.map = new google.maps.Map(this.container.get(0), this.mapOptions); 11102 11103 }, 11104 11105 11106 11107 createMarker: function() { 11108 11109 this.marker = new google.maps.Marker({ 11110 11111 icon: this.options.marker, 11112 11113 position: this.coords 11114 11115 }); 11116 11117 11118 11119 this.marker.setMap(this.map); 11120 11121 }, 11122 11123 11124 11125 createInfoWindow: function() { 11126 11127 var self = this; 11128 11129 this.infoWindow = new google.maps.InfoWindow({ 11130 11131 content: this.infoWindowContent.get(0) 11132 11133 }); 11134 11135 this.marker.addListener('click', function() { 11136 11137 self.infoWindow.open(self.map, self.marker); 11138 11139 }) 11140 11141 } 11142 11143 }; 11144 11145 11146 11147 $.fn.googleMapAPI = function(opt) { 11148 11149 return this.each(function() { 11150 11151 $(this).data('GoogleMapAPI', new GoogleMapAPI($.extend(opt, {container: this}))); 11152 11153 }); 11154 11155 }; 11156 11157}(jQuery)); 11158 11159 11160 11161/* 11162 11163 * Responsive Layout helper 11164 11165 */ 11166 11167ResponsiveHelper = (function($){ 11168 11169 // init variables 11170 11171 var handlers = [], 11172 11173 prevWinWidth, 11174 11175 win = $(window), 11176 11177 nativeMatchMedia = false;
11178 11179 11180 11181 // detect match media support 11182 11183 if(window.matchMedia) { 11184 11185 if(window.Window && window.matchMedia === Window.prototype.matchMedia) { 11186 11187 nativeMatchMedia = true; 11188 11189 } else if(window.matchMedia.toString().indexOf('native') > -1) { 11190 11191 nativeMatchMedia = true; 11192 11193 } 11194 11195 } 11196 11197 11198 11199 // prepare resize handler 11200 11201 function resizeHandler() { 11202 11203 var winWidth = win.width(); 11204 11205 if(winWidth !== prevWinWidth) { 11206 11207 prevWinWidth = winWidth; 11208 11209 11210 11211 // loop through range groups 11212 11213 $.each(handlers, function(index, rangeObject){ 11214 11215 // disable current active area if needed 11216 11217 $.each(rangeObject.data, function(property, item) { 11218 11219 if(item.currentActive && !matchRange(item.range[0], item.range[1])) { 11220 11221 item.currentActive = false; 11222 11223 if(typeof item.disableCallback === 'function') { 11224 11225 item.disableCallback(); 11226 11227 } 11228 11229 } 11230 11231 }); 11232 11233 11234 11235 // enable areas that match current width 11236 11237 $.each(rangeObject.data, function(property, item) { 11238 11239 if(!item.currentActive && matchRange(item.range[0], item.range[1])) { 11240 11241 // make callback 11242 11243 item.currentActive = true; 11244 11245 if(typeof item.enableCallback === 'function') { 11246 11247 item.enableCallback(); 11248 11249 } 11250 11251 } 11252 11253 }); 11254 11255 }); 11256 11257 } 11258 11259 } 11260 11261 win.bind('load resize orientationchange', resizeHandler); 11262 11263 11264 11265 // test range 11266 11267 function matchRange(r1, r2) { 11268 11269 var mediaQueryString = ''; 11270 11271 if(r1 > 0) { 11272 11273 mediaQueryString += '(min-width: ' + r1 + 'px)'; 11274 11275 } 11276 11277 if(r2 < Infinity) { 11278 11279 mediaQueryString += (mediaQueryString ? ' and ' : '') + '(max-width: ' + r2 + 'px)'; 11280 11281 } 11282 11283 return matchQuery(mediaQueryString, r1, r2); 11284 11285 } 11286 11287 11288 11289 // media query function 11290 11291 function matchQuery(query, r1, r2) { 11292 11293 if(window.matchMedia && nativeMatchMedia) { 11294 11295 return matchMedia(query).matches; 11296 11297 } else if(window.styleMedia) { 11298 11299 return styleMedia.matchMedium(query); 11300 11301 } else if(window.media) { 11302 11303 return media.matchMedium(query); 11304 11305 } else { 11306 11307 return prevWinWidth >= r1 && prevWinWidth <= r2; 11308 11309 } 11310 11311 } 11312 11313 11314 11315 // range parser 11316 11317 function parseRange(rangeStr) { 11318 11319 var rangeData = rangeStr.split('..'); 11320 11321 var x1 = parseInt(rangeData[0], 10) || -Infinity; 11322 11323 var x2 = parseInt(rangeData[1], 10) || Infinity; 11324 11325 return [x1, x2].sort(function(a, b){ 11326 11327 return a - b; 11328 11329 }); 11330 11331 } 11332 11333 11334 11335 // export public functions 11336 11337 return { 11338 11339 addRange: function(ranges) { 11340 11341 // parse data and add items to collection 11342 11343 var result = {data:{}}; 11344 11345 $.each(ranges, function(property, data){ 11346 11347 result.data[property] = { 11348 11349 range: parseRange(property), 11350 11351 enableCallback: data.on, 11352 11353 disableCallback: data.off 11354 11355 }; 11356 11357 }); 11358 11359 handlers.push(result); 11360 11361 11362 11363 // call resizeHandler to recalculate all events 11364 11365 prevWinWidth = null; 11366 11367 resizeHandler(); 11368 11369 } 11370 11371 }; 11372 11373}(jQuery));
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.