1// v.1.15 08.27.25 2// Pavlo Tkach 3(function ($) { 4 5 var methods = { 6 init : function( options ) { 7 var options = $.extend({ 8 type: 'details', // string: 'details'|'accordion'|'tabs'|'toggler' 9 toggleClass: 'open', //string 10 wrapperSelector: '.accordion', // selector wrapperSelector of items and outer titles 11 itemSelector: '.tab', 12 titleInSelector: '.title', 13 titleOutSelector: '.titles > li', 14 bodySelector: '.body', 15 toggleSelf: false, 16 toggleAllSelector: false, 17 copyTitle: false, 18 titleInClass: 'title', 19 heightStyle: 'content', //'content'|'auto'|[number] 20 itemClick: false, 21 disableTabClass: 'disabled', 22 addToggleElements: [], // [{'class':'selector',..},{..}] If the tab is active/disactive, the 'class' add/remove to elements with 'selector' 23 activeTabNumber: false, // number preset active tab or false 24 activeTabByURL: false, //logical/string, preset active tab by URL anchor or parameter. If string - it's the parameters name. If "true" - the parameters name = 'id' 25 cookieName: '', 26 scrollToTab: false, // 27 preventDefault: false, //cancel default action after a click on the link element of tab (mode 'tabs') 28 shift: 0, 29 duration: 400, 30 togglerContainer: {name:'',inner:'',outer:''}, 31 innerEventContainer: '', 32 outerEventContainer: '', 33 onClickBefore: function() {}, 34 onClickAfter: function() {}, 35 }, options); 36 37 if ( this.data('toggler') ) { 38 options = this.data('toggler'); 39 } else { 40 this.data('toggler',options); 41 }; 42 43 var tClass = options.toggleClass, 44 $elements = this, $elm, lev = 0, $wrap, $items, $links, $body, 45 id, duration = options.duration, ate = [], 46 shift = ((typeof (options.scrollToTab) == "object") && ("shift" in options.scrollToTab))?options.scrollToTab.shift:0, 47 ntc = (typeof options.togglerContainer.name == 'undefined')?'':options.togglerContainer.name, 48 itc = options.togglerContainer.inner, 49 otc = options.togglerContainer.outer, 50 onClickBefore = options.onClickBefore, 51 onClickAfter = options.onClickAfter, 52 type = (options.type == 'accordion')?'a':((options.type == 'tabs')?'ta':((options.type == 'toggler')?'to':'d')), 53 cook = ((typeof (options.cookieName) == 'string') && options.cookieName)?true:false; 54 55 if ( !$elements || !$elements.length ) return; 56 57 function getQueryVariable(variable) { 58 var query = window.location.search.substring(1); 59 var vars = query.split("&"); 60 for (var i=0;i<vars.length;i++) { 61 var pair = vars[i].split("="); 62 if(pair[0] == variable){return pair[1];} 63 } 64 return(false); 65 }; 66 function handClickBd(event) { 67 var $t = event.data.to, itc = event.data.itc, ate = event.data.ate, 68 e = event || window.event, $o = $(e.target || e.srcElement); 69 // ToggleElements 70 if ( $o !== $t) { 71 if ( !itc || (itc && !$o.closest(itc).length) ) { 72 for (var i = 0; i < ate.length; i++) { 73 for (var cls in ate[i]) { 74 var $elt = $(ate[i][cls]); 75 if ($elt.length) { 76 $elt.removeClass(cls); 77 } 78 } 79 } 80 $t.removeClass('open'); 81 } 82 } 83 }; 84 function handClickTiA(event) { 85 var ate = event.data.ate, 86 $titleI = event.data.elm, hide = false;
87 var $wrap = $titleI.closest(options.wrapperSelector), 88 $items = $wrap.find(options.itemSelector), 89 $titleIs = $items.find(options.titleInSelector), 90 $item = $items.eq($titleIs.index($titleI)), 91 $elmbodys = $items.find(options.bodySelector), 92 $elmbody = $item.find(options.bodySelector); 93 94 if ($.isFunction(onClickBefore)) { 95 onClickBefore.call(this); 96 }; 97 if ($item.hasClass(tClass)) hide = true; 98 event.stopPropagation(); 99 100 if (options.toggleSelf) { 101 if ($item.hasClass(tClass)) { 102 hide = true; 103 $item.removeClass(tClass); 104 $elmbody.hide(duration); 105 } else { 106 $item.addClass(tClass); 107 $elmbody.show(duration); 108 }; 109 // addToggleElements 110 for (var cls in ate) { 111 var sel = ate[cls], $elt = $(sel); 112 if ($elt.length) { 113 if (hide) $elt.removeClass(cls) 114 else $elt.addClass(cls); 115 } 116 } 117 } else { 118 if (!$item.hasClass(tClass)) { 119 var dur = options.scrollToTab?0:duration; 120 $items.removeClass(tClass); 121 $elmbodys.hide(dur); 122 $item.addClass(tClass); 123 $elmbody.show(dur); 124 } 125 }; 126 if ($.isFunction(onClickAfter)) { 127 onClickAfter.call(this); 128 }; 129 // scrollToTab 130 if (options.scrollToTab && !options.toggleSelf) { 131 var top = $item.offset().top; 132 $('html, body').animate({ 133 scrollTop: top - shift 134 }, duration); 135 }; 136 //add the active tab id to URL 137 if ( options.activeTabByURL ) { 138 var id = $item.attr('id'), href = window.location.href; 139 if ( href.indexOf('#') != -1 ) href = href.substr(0,href.indexOf('#')); 140 if ( id ) { 141 window.location = href + '#'+id; 142 } 143 }; 144 //save to cookie 145 if ( cook ) { 146 let str=''; 147 $items.filter('.open').each(function() { 148 str = str + ($(this).attr('id')?$(this).attr('id'):'') + ($(this).attr('id')?' ':''); 149 }); 150 str = str.slice(0,-1); 151 if ( $.fn.cookie ) { 152 $.cookie(options.cookieName, str); 153 } else { 154 Cookies.set(options.cookieName, str); 155 } 156 }; 157 }; 158 function handClickTAll(event) { 159 var $elm = event.data.elm, $items = event.data.items, hide = false, 160 $elmbodys = $items.find(options.bodySelector); 161 162 if ($items.eq(0).hasClass('tall')) hide = true; 163 event.stopPropagation(); 164 165 if (hide) { 166 $items.removeClass(tClass).removeClass('tall'); 167 $elmbodys.hide(duration); 168 $elm.removeClass(tClass); 169 } else { 170 $items.addClass(tClass).addClass('tall'); 171 $elmbodys.show(duration); 172 $elm.addClass(tClass); 173 }; 174 // scrollToTab 175 if (options.scrollToTab && !options.toggleSelf) { 176 var top = $item.offset().top; 177 $('html, body').animate({ 178 scrollTop: top - shift 179 }, duration); 180 }; 181 //save to cookie 182 if ( cook ) { 183 if ( $.fn.cookie ) { 184 $.cookie(options.cookieName, 'all'); 185 } else { 186 Cookies.set(options.cookieName, 'all'); 187 } 188 }; 189 }; 190 function handClickToT(event) { 191 var $titleO = event.data.elm; 192 var $wrap = $titleO.closest(options.wrapperSelector), 193 $items = $wrap.find(options.itemSelector), 194 $titleOs = $wrap.find(options.titleOutSelector), 195 $item = $items.eq($titleOs.index($titleO)); 196 197 if ($.isFunction(onClickBefore)) { 198 onClickBefore.call(this); 199 }; 200 201 event.stopPropagation(); 202 $titleOs.removeClass(tClass); 203 $items.find(options.bodySelector).hide(0); 204 $titleO.addClass(tClass); 205 $items.removeClass(tClass); 206 $item.addClass(tClass); 207 $item.find(options.bodySelector).show(0); 208 209 //add the active tab id to URL 210 if ( options.activeTabByURL ) { 211 var id = $item.attr('id'), href = window.location.href; 212 if ( href.indexOf('#') != -1 ) href = href.substr(0,href.indexOf('#')); 213 if ( id ) { 214 window.location = href + '#'+id; 215 } 216 }; 217 218 if ($.isFunction(onClickAfter)) { 219 onClickAfter.call(this); 220 }; 221 if (options.preventDefault) { 222 event.preventDefault(); 223 return false;
224 }; 225 }; 226 function handClickTiT(event) { 227 var $titleI = event.data.elm; 228 var $wrap = $titleI.closest(options.wrapperSelector), 229 $items = $wrap.find(options.itemSelector), 230 $titleIs = $items.find(options.titleInSelector), 231 $titleOs = $wrap.find(options.titleOutSelector), 232 $item = $items.eq($titleIs.index($titleI)), 233 $titleO = $titleOs.eq($titleIs.index($titleI)); 234 var dur = options.scrollToTab?0:duration, 235 $elmbody = $item.find(options.bodySelector); 236 237 if (options.toggleSelf || (!options.toggleSelf && !$item.hasClass(tClass))) { 238 if ($.isFunction(onClickBefore)) { 239 onClickBefore.call(this); 240 }; 241 }; 242 243 if (options.toggleSelf) { 244 if ($item.hasClass(tClass)) { 245 hide = true; 246 $item.removeClass(tClass); 247 $elmbody.hide(duration); 248 } else { 249 $item.addClass(tClass); 250 $elmbody.show(duration); 251 }; 252 } else { 253 if (!$item.hasClass(tClass)) { 254 $items.removeClass(tClass); 255 $titleOs.removeClass(tClass); 256 $items.find(options.bodySelector).hide(dur); 257 $titleO.addClass(tClass); 258 $item.addClass(tClass); 259 $elmbody.show(dur); 260 if (options.scrollToTab) { 261 var top = $item.offset().top; 262 $('html, body').animate({ 263 scrollTop: top - shift 264 }, duration); 265 } 266 }; 267 }; 268 //add the active tab id to URL 269 if ( options.activeTabByURL ) { 270 var id = $item.attr('id'), href = window.location.href; 271 if ( href.indexOf('#') != -1 ) href = href.substr(0,href.indexOf('#')); 272 if ( id ) { 273 window.location = href + '#'+id; 274 } 275 }; 276 if (options.toggleSelf || (!options.toggleSelf && !$item.hasClass(tClass))) { 277 if ($.isFunction(onClickAfter)) { 278 onClickAfter.call(this); 279 }; 280 }; 281 }; 282 function handClickTiD(event) { 283 var $elm = event.data.elm; 284 if ($.isFunction(onClickBefore)) { 285 onClickBefore.call(this); 286 }; 287 event.stopPropagation(); 288 $elm.toggleClass(tClass); 289 if ($.isFunction(onClickAfter)) { 290 onClickAfter.call(this); 291 }; 292 }; 293 function handClickTT(event) { 294 var ate = event.data.ate, hide = false, 295 $items = event.data.elm; 296 297 if ($.isFunction(onClickBefore)) { 298 onClickBefore.call(this); 299 }; 300 event.stopPropagation(); 301 if ($(this).hasClass(tClass)) { 302 hide = true; 303 $items.removeClass(tClass); 304 } else { 305 hide = false;
306 $items.addClass(tClass); 307 }; 308 // addToggleElements 309 for (var i = 0; i < ate.length; i++) { 310 for (var cls in ate[i]) { 311 var $elt = $(ate[i][cls]); 312 if ($elt.length) { 313 if (hide) $elt.removeClass(cls) 314 else $elt.addClass(cls); 315 } 316 } 317 }; 318 if ($.isFunction(onClickAfter)) { 319 onClickAfter.call(this); 320 }; 321 if (options.preventDefault) { 322 event.preventDefault(); 323 return false; 324 }; 325 }; 326 327 if (type == 'ta' && !$elements.hasClass(tClass)) options.activeTabNumber = 1; 328 329 $elements.each(function(itm){ 330 var $titleO, $titleOs, $titleI, $titleIs, $item, $items, $elmbody, $elmbodys; 331 332 if (type == 'a') { //accordion 333 $item = $(this); 334 $wrap = $item.closest(options.wrapperSelector); 335 $items = $wrap.find(options.itemSelector); 336 $titleIs = $items.find(options.titleInSelector); 337 $titleI = $item.find(options.titleInSelector); 338 $elmbody = $item.find(options.bodySelector); 339 ate = options.addToggleElements[$items.index($item)]; 340 // heightStyle 341 if ( options.heightStyle === "auto" ) { 342 $elmbodys = $items.find(options.bodySelector); 343 maxHeight = 0; 344 $elmbodys.each(function() { 345 maxHeight = Math.max( maxHeight, $(this).css("height", "").height() ); 346 }).height( maxHeight ); 347 } else if ( typeof options.heightStyle === 'number' ){ 348 $elmbodys = $items.find(options.bodySelector); 349 $elmbodys.height(options.heightStyle).css({'overflow-y':'auto'}); 350 }; 351 // class preset 352 if ($item.hasClass(tClass)) { 353 $elmbody.css({'display':'block'}); 354 } else { $elmbody.css({'display':'none'});} 355 if (options.itemClick) { 356 $item.off('click.toggler'); 357 if ( !$(this).hasClass('options.disableTabClass') ) $item.on('click.toggler',{ate: ate, elm: $titleI}, handClickTiA ); 358 } else { 359 $titleI.off('click.toggler'); 360 if ( !$(this).hasClass('options.disableTabClass') ) $titleI.on('click.toggler',{ate: ate, elm: $titleI}, handClickTiA ); 361 } 362 //toggle all tabs 363 if (options.toggleSelf && options.toggleAllSelector && $(options.toggleAllSelector).length) { 364 $(options.toggleAllSelector).each(function() { 365 $(this).off('click.toggler').on('click.toggler',{elm: $(this), items: $items}, handClickTAll ); 366 }); 367 } 368 369 // activeTabNumber preset 370 if ( options.activeTabNumber && ($items.index($item) == (options.activeTabNumber-1)) ) { 371 if (!options.toggleSelf) { 372 $items.removeClass(tClass); 373 $items.find(options.bodySelector).css({'display':'none'}); 374 }; 375 $item.addClass(tClass); 376 $item.find(options.bodySelector).css({'display':'block'}); 377 }; 378 } else if (type == 'ta') { //tabs 379 $titleO = $(this), 380 $wrap = $titleO.closest(options.wrapperSelector); 381 $items = $wrap.find(options.itemSelector); 382 $titleOs = $wrap.find(options.titleOutSelector); 383 $item = $items.eq($titleOs.index($titleO)); 384 $titleI = $(document.createElement('div')); 385 $titleI.addClass(options.titleInClass).text($titleO.text()); 386 $elmbody = $item.find(options.bodySelector); 387 388 if (options.copyTitle && $item.length === 1 && !$item.find(options.titleInSelector).length) { 389 $titleI.prependTo($item); 390 } else { 391 $titleI = $item.children(options.titleInSelector); 392 } 393 // class preset 394 if ($item.hasClass(tClass)) { 395 $elmbody.css({'display':'block'}); 396 } else { $elmbody.css({'display':'none'});} 397 $titleO.off('click.toggler'); 398 $titleI.off('click.toggler'); 399 if ( !$(this).hasClass('options.disableTabClass') ) { 400 $titleO.on('click.toggler',{elm: $titleO}, handClickToT); 401 $titleI.on('click.toggler',{elm: $titleI}, handClickTiT); 402 } 403 // activeTabNumber preset 404 if ( options.activeTabNumber && ($titleOs.index($titleO) == (options.activeTabNumber-1)) ) { 405 $items.removeClass(tClass); 406 $items.find(options.bodySelector).css({'display':'none'}); 407 $titleOs.removeClass(tClass); 408 $item.addClass(tClass); 409 $titleO.addClass(tClass); 410 $elmbody.css({'display':'block'}); 411 }; 412 } else if (type == 'to') { //toggle 413 var ate = options.addToggleElements; 414 $(this).off('click.toggler'); 415 $(this).on('click.toggler',{ate: ate, elm: $elements}, handClickTT); 416 if (otc) { 417 $(otc).off('click.TC' + ntc + itm + '.toggler'); 418 $(otc).on('click.TC' + ntc + itm + '.toggler',{to:$(this),itc:itc,ate:ate},handClickBd); 419 } 420 421 } else { // details 422 $item = $(this); 423 $item.off('click.toggler'); 424 $item.on('click.toggler',{elm: $item}, handClickTiD); 425 }; 426 427 }); 428 var id, $ae={} , aid = []; 429 // get id active tab from url 430 function isCssIdValid (id) { 431 re = /^[A-Za-z]+[\w\-\:\.]*$/ 432 return re.test(id) 433 }; 434 if ( options.activeTabByURL ) { 435 var idp = ( options.activeTabByURL === true )?'id':options.activeTabByURL, 436 hash = window.location.hash, id1 = decodeURIComponent(hash?hash.substr(1,hash.length-1):''); 437 id = getQueryVariable(idp); 438 hash = isCssIdValid(id1)?"#"+id1:''; 439 id = id?"#"+id:decodeURIComponent(hash); 440 }; 441 // get id active tab by cookie 442 if ( cook ) { 443 if ( $.fn.cookie ) { 444 if ( !($.cookie(options.cookieName) == null) ){ 445 aid = $.cookie(options.cookieName).split(' '); 446 for (var i = 0; i < aid.length; i++) { 447 if (aid[i] !== '') { 448 aid[i] = '#'+aid[i]; 449 if (i==0) id = aid[0]; 450 } 451 } 452 }; 453 } else { 454 if ( !(Cookies.get(options.cookieName) == null) ){ 455 aid = Cookies.get(options.cookieName).split(' '); 456 for (var i = 0; i < aid.length; i++) { 457 if (aid[i] !== '') { 458 aid[i] = '#'+aid[i]; 459 if (i==0) id = aid[0]; 460 } 461 } 462 }; 463 } 464 }; 465 if ( options.activeTabByURL || cook ) { 466 if (type == 'a') { 467 if ( cook && aid.length > 1 ) { 468 for (var i = 0; i < aid.length; i++) { 469 $ae = $(aid[i]).find(options.titleInSelector); 470 if ($ae.length) $ae.click(); 471 }; 472 } else { 473 if ($ae.length && options.scrollToTab) { 474 $('html, body').animate({ 475 scrollTop: $(id).offset().top - options.shift 476 }, 100); 477 } 478 }; 479 } else if (type == 'ta') {
480 if (id) $ae = $wrap.find(options.titleOutSelector+'[href="'+id+'"]'); 481 if ($ae.length) $ae.click(); 482 } else if (type == 'd') { 483 var $e = $(id), $ae = $e; 484 var $p,l = $e.length?true:false; 485 while (l) { 486 $e = $e.parents(options.itemSelector); 487 if ( $e && $elements.is($e) ) { 488 $ae = $ae.add($e); 489 } else { 490 l = false; 491 } 492 }; 493 if ($ae.length) $ae.addClass(tClass); 494 }; 495 }; 496 497 return this; 498 }, 499 refresh : function(options) { 500 if ( options.type == 'accordion' && options.heightStyle === "auto" ) { 501 var $elmbodys = $(this).find(options.bodySelector); 502 maxHeight = 0; 503 $elmbodys.each(function() { 504 maxHeight = Math.max( maxHeight, $(this).css("height", "").height() ); 505 }).height( maxHeight ); 506 }; 507 }, 508 destroy : function(options) { 509 var options = this.data('toggler'); 510 this.each(function(i){ 511 if (options.type == 'tabs') { 512 var $titleO = $(this), 513 $wrap = $titleO.closest(options.wrapperSelector); 514 $items = $wrap.find(options.itemSelector); 515 $titleOs = $wrap.find(options.titleOutSelector); 516 $item = $items.eq($titleOs.index($titleO)); 517 $titleI = $item.find(options.titleInSelector); 518 $titleI.off('.toggler'); 519 } else { 520 var $item = $(this), $titleI; 521 if (options.itemClick) { 522 $item.off('.toggler'); 523 } else { 524 $titleI = $item.find(options.titleInSelector); 525 $titleI.off('.toggler'); 526 }; 527 if (!oec) { 528 $(oec).off('click.TC'+options.togglerContainer.name+'.toggler'); 529 }; 530 } 531 }); 532 } 533 }; 534 535 $.fn.toggler = function( method ) { 536 if ( methods[method] ) { 537 return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )); 538 } else if ( typeof method === 'object' || ! method ) { 539 return methods.init.apply( this, arguments ); 540 } else { 541 $.error( 'Method with the name ' + method + ' does not exist for jQuery.toggler' ); 542 } 543 }; 544 545}) (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.