|
1 | 1 | /**
|
2 | 2 | * jquery-bootstrap-scrolling-tabs
|
3 |
| - * @version v1.2.2 |
| 3 | + * @version v2.0.0 |
4 | 4 | * @link https://github.com/mikejacobson/jquery-bootstrap-scrolling-tabs
|
5 | 5 | * @author Mike Jacobson <[email protected]>
|
6 | 6 | * @license MIT License, http://www.opensource.org/licenses/MIT
|
7 | 7 | */
|
8 |
| - |
9 | 8 | /**
|
10 | 9 | * jQuery plugin version of Angular directive angular-bootstrap-scrolling-tabs:
|
11 | 10 | * https://github.com/mikejacobson/angular-bootstrap-scrolling-tabs
|
|
95 | 94 | * scroll arrow to slide the tabs right.
|
96 | 95 | * enableSwiping:
|
97 | 96 | * set to true if you want to enable horizontal swiping
|
98 |
| - * for touch screens. This simply enables horizontal |
99 |
| - * scrolling--and therefore the horizontal scrollbar--for |
100 |
| - * the tabs. For WebKit-based browsers, the scrollbar |
101 |
| - * will then be hidden via CSS (because the plugin will |
102 |
| - * add CSS class scrtabs-allow-scrollbar to the parent |
103 |
| - * element) but for browsers that don't support |
104 |
| - * ::-webkit-scrollbar, the scrollbar will be visible. |
| 97 | + * for touch screens. |
105 | 98 | * widthMultiplier:
|
106 | 99 | * set to a value less than 1 if you want the tabs
|
107 | 100 | * container to be less than the full width of its
|
|
232 | 225 | ;(function ($, window) {
|
233 | 226 | 'use strict';
|
234 | 227 |
|
| 228 | + /* exported CONSTANTS */ |
235 | 229 | var CONSTANTS = {
|
236 | 230 | CONTINUOUS_SCROLLING_TIMEOUT_INTERVAL: 50, // timeout interval for repeatedly moving the tabs container
|
237 | 231 | // by one increment while the mouse is held down--decrease to
|
|
243 | 237 | DATA_KEY_IS_MOUSEDOWN: 'scrtabsismousedown',
|
244 | 238 |
|
245 | 239 | CSS_CLASSES: {
|
246 |
| - ALLOW_SCROLLBAR: 'scrtabs-allow-scrollbar', |
247 | 240 | SCROLL_ARROW_DISABLE: 'scrtabs-disable'
|
248 | 241 | },
|
249 | 242 |
|
|
257 | 250 | DROPDOWN_MENU_HIDE: 'hide.bs.dropdown.scrtabs',
|
258 | 251 | DROPDOWN_MENU_SHOW: 'show.bs.dropdown.scrtabs',
|
259 | 252 | FORCE_REFRESH: 'forcerefresh.scrtabs',
|
260 |
| - MOUSEDOWN: 'mousedown.scrtabs touchstart.scrtabs', |
261 |
| - MOUSEUP: 'mouseup.scrtabs touchend.scrtabs', |
262 |
| - WINDOW_RESIZE: 'resize.scrtabs', |
263 |
| - TABS_READY: 'ready.scrtabs' |
| 253 | + MOUSEDOWN: 'mousedown.scrtabs', |
| 254 | + MOUSEUP: 'mouseup.scrtabs', |
| 255 | + TABS_READY: 'ready.scrtabs', |
| 256 | + TOUCH_END: 'touchend.scrtabs', |
| 257 | + TOUCH_MOVE: 'touchmove.scrtabs', |
| 258 | + TOUCH_START: 'touchstart.scrtabs', |
| 259 | + WINDOW_RESIZE: 'resize.scrtabs' |
264 | 260 | }
|
265 | 261 | };
|
266 | 262 |
|
|
306 | 302 | var ehd = this;
|
307 | 303 |
|
308 | 304 | ehd.setElementReferences();
|
309 |
| - ehd.setEventListeners(); |
| 305 | + ehd.setEventListeners(options); |
| 306 | + }; |
| 307 | + |
| 308 | + p.listenForTouchEvents = function () { |
| 309 | + var ehd = this, |
| 310 | + stc = ehd.stc, |
| 311 | + smv = stc.scrollMovement, |
| 312 | + ev = CONSTANTS.EVENTS; |
| 313 | + |
| 314 | + var touching = false; |
| 315 | + var touchStartX; |
| 316 | + var startingContainerLeftPos; |
| 317 | + var newLeftPos; |
| 318 | + |
| 319 | + stc.$movableContainer |
| 320 | + .on(ev.TOUCH_START, function (e) { |
| 321 | + touching = true; |
| 322 | + startingContainerLeftPos = stc.movableContainerLeftPos; |
| 323 | + touchStartX = e.originalEvent.changedTouches[0].pageX; |
| 324 | + }) |
| 325 | + .on(ev.TOUCH_END, function () { |
| 326 | + touching = false; |
| 327 | + }) |
| 328 | + .on(ev.TOUCH_MOVE, function (e) { |
| 329 | + if (!touching) { |
| 330 | + return; |
| 331 | + } |
| 332 | + |
| 333 | + var touchPageX = e.originalEvent.changedTouches[0].pageX; |
| 334 | + var diff = touchPageX - touchStartX; |
| 335 | + var minPos; |
| 336 | + |
| 337 | + newLeftPos = startingContainerLeftPos + diff; |
| 338 | + if (newLeftPos > 0) { |
| 339 | + newLeftPos = 0; |
| 340 | + } else { |
| 341 | + minPos = smv.getMinPos(); |
| 342 | + if (newLeftPos < minPos) { |
| 343 | + newLeftPos = minPos; |
| 344 | + } |
| 345 | + } |
| 346 | + stc.movableContainerLeftPos = newLeftPos; |
| 347 | + stc.$movableContainer.css('left', smv.getMovableContainerCssLeftVal()); |
| 348 | + smv.refreshScrollArrowsDisabledState(); |
| 349 | + }); |
310 | 350 | };
|
311 | 351 |
|
312 | 352 | p.refreshAllElementSizes = function () {
|
|
400 | 440 | ehd.setMovableContainerWidth();
|
401 | 441 | };
|
402 | 442 |
|
403 |
| - p.setEventListeners = function () { |
| 443 | + p.setEventListeners = function (settings) { |
404 | 444 | var ehd = this,
|
405 | 445 | stc = ehd.stc,
|
406 | 446 | evh = stc.eventHandlers,
|
407 | 447 | ev = CONSTANTS.EVENTS;
|
408 | 448 |
|
| 449 | + if (settings.enableSwiping) { |
| 450 | + ehd.listenForTouchEvents(); |
| 451 | + } |
| 452 | + |
409 | 453 | stc.$slideLeftArrow
|
410 | 454 | .off('.scrtabs')
|
411 | 455 | .on(ev.MOUSEDOWN, function (e) { evh.handleMousedownOnSlideMovContainerLeftArrow.call(evh, e); })
|
|
526 | 570 |
|
527 | 571 | // prototype methods
|
528 | 572 | (function (p){
|
529 |
| - p.handleClickOnSlideMovContainerLeftArrow = function (e) { |
| 573 | + p.handleClickOnSlideMovContainerLeftArrow = function () { |
530 | 574 | var evh = this,
|
531 | 575 | stc = evh.stc;
|
532 | 576 |
|
533 | 577 | stc.scrollMovement.incrementMovableContainerLeft();
|
534 | 578 | };
|
535 | 579 |
|
536 |
| - p.handleClickOnSlideMovContainerRightArrow = function (e) { |
| 580 | + p.handleClickOnSlideMovContainerRightArrow = function () { |
537 | 581 | var evh = this,
|
538 | 582 | stc = evh.stc;
|
539 | 583 |
|
540 | 584 | stc.scrollMovement.incrementMovableContainerRight();
|
541 | 585 | };
|
542 | 586 |
|
543 |
| - p.handleMousedownOnSlideMovContainerLeftArrow = function (e) { |
| 587 | + p.handleMousedownOnSlideMovContainerLeftArrow = function () { |
544 | 588 | var evh = this,
|
545 | 589 | stc = evh.stc;
|
546 | 590 |
|
547 | 591 | stc.$slideLeftArrow.data(CONSTANTS.DATA_KEY_IS_MOUSEDOWN, true);
|
548 | 592 | stc.scrollMovement.continueSlideMovableContainerLeft();
|
549 | 593 | };
|
550 | 594 |
|
551 |
| - p.handleMousedownOnSlideMovContainerRightArrow = function (e) { |
| 595 | + p.handleMousedownOnSlideMovContainerRightArrow = function () { |
552 | 596 | var evh = this,
|
553 | 597 | stc = evh.stc;
|
554 | 598 |
|
555 | 599 | stc.$slideRightArrow.data(CONSTANTS.DATA_KEY_IS_MOUSEDOWN, true);
|
556 | 600 | stc.scrollMovement.continueSlideMovableContainerRight();
|
557 | 601 | };
|
558 | 602 |
|
559 |
| - p.handleMouseupOnSlideMovContainerLeftArrow = function (e) { |
| 603 | + p.handleMouseupOnSlideMovContainerLeftArrow = function () { |
560 | 604 | var evh = this,
|
561 | 605 | stc = evh.stc;
|
562 | 606 |
|
563 | 607 | stc.$slideLeftArrow.data(CONSTANTS.DATA_KEY_IS_MOUSEDOWN, false);
|
564 | 608 | };
|
565 | 609 |
|
566 |
| - p.handleMouseupOnSlideMovContainerRightArrow = function (e) { |
| 610 | + p.handleMouseupOnSlideMovContainerRightArrow = function () { |
567 | 611 | var evh = this,
|
568 | 612 | stc = evh.stc;
|
569 | 613 |
|
570 | 614 | stc.$slideRightArrow.data(CONSTANTS.DATA_KEY_IS_MOUSEDOWN, false);
|
571 | 615 | };
|
572 | 616 |
|
573 |
| - p.handleWindowResize = function (e) { |
| 617 | + p.handleWindowResize = function () { |
574 | 618 | var evh = this,
|
575 | 619 | stc = evh.stc,
|
576 | 620 | newWinWidth = stc.$win.width();
|
|
765 | 809 | smv.enableSlideRightArrow();
|
766 | 810 | };
|
767 | 811 |
|
768 |
| - p.scrollToActiveTab = function (options) { |
| 812 | + p.scrollToActiveTab = function () { |
769 | 813 | var smv = this,
|
770 | 814 | stc = smv.stc,
|
771 | 815 | RIGHT_OFFSET_BUFFER = 20,
|
|
801 | 845 | smv.slideMovableContainerToLeftPos();
|
802 | 846 | return true;
|
803 | 847 | } else {
|
804 |
| - leftScrollArrowWidth = stc.$slideLeftArrow.outerWidth(); |
| 848 | + leftScrollArrowWidth = stc.$slideLeftArrow.outerWidth(); |
805 | 849 | if (activeTabLeftPos < leftScrollArrowWidth) { // active tab off left side
|
806 | 850 | stc.movableContainerLeftPos += leftScrollArrowWidth - activeTabLeftPos;
|
807 | 851 | smv.slideMovableContainerToLeftPos();
|
|
820 | 864 |
|
821 | 865 | // make sure LeftPos is set so that a tab edge will be against the
|
822 | 866 | // left scroll arrow so we won't have a partial, cut-off tab
|
823 |
| - stc.$tabsLiCollection.each(function (index) { |
| 867 | + stc.$tabsLiCollection.each(function () { |
824 | 868 | var tabWidth = $(this).width();
|
825 | 869 |
|
826 | 870 | totalTabWidth += tabWidth;
|
|
952 | 996 | }(ScrollingTabsControl.prototype));
|
953 | 997 |
|
954 | 998 |
|
| 999 | + /* exported buildNavTabsAndTabContentForTargetElementInstance */ |
955 | 1000 | var tabElements = (function () {
|
956 | 1001 |
|
957 | 1002 | return {
|
|
1128 | 1173 | return;
|
1129 | 1174 | }
|
1130 | 1175 |
|
1131 |
| - tabs.forEach(function(tab, index) { |
| 1176 | + tabs.forEach(function(tab) { |
1132 | 1177 | tabElements
|
1133 | 1178 | .getNewElTabLi(tab, propNames, true) // true -> forceActiveTab
|
1134 | 1179 | .appendTo($navTabs);
|
|
1209 | 1254 | return $scroller;
|
1210 | 1255 | }
|
1211 | 1256 |
|
| 1257 | + /* exported listenForDropdownMenuTabs, |
| 1258 | + refreshTargetElementInstance, |
| 1259 | + scrollToActiveTab */ |
1212 | 1260 | function checkForTabAdded(refreshData) {
|
1213 | 1261 | var updatedTabsArray = refreshData.updatedTabsArray,
|
1214 | 1262 | propNames = refreshData.propNames,
|
|
1359 | 1407 | }
|
1360 | 1408 |
|
1361 | 1409 | // the tab order changed...
|
1362 |
| - updatedTabsArray.forEach(function (t, i) { |
| 1410 | + updatedTabsArray.forEach(function (t) { |
1363 | 1411 | var paneId = t[propNames.paneId];
|
1364 | 1412 |
|
1365 | 1413 | newTabsCollection.push(
|
|
1471 | 1519 | 'left': ddMenuTargetLeft
|
1472 | 1520 | });
|
1473 | 1521 |
|
1474 |
| - function handleClickOnDropdownMenuItem(e) { |
| 1522 | + function handleClickOnDropdownMenuItem() { |
1475 | 1523 | var $selectedMenuItemAnc = $(this),
|
1476 | 1524 | $selectedMenuItemLi = $selectedMenuItemAnc.parent('li'),
|
1477 | 1525 | $selectedMenuItemDropdownMenu = $selectedMenuItemLi.parent('.dropdown-menu'),
|
|
1590 | 1638 | $targetEls.trigger(CONSTANTS.EVENTS.TABS_READY);
|
1591 | 1639 | };
|
1592 | 1640 |
|
1593 |
| - if (settings.enableSwiping) { |
1594 |
| - $targetEl.parent().addClass(CONSTANTS.CSS_CLASSES.ALLOW_SCROLLBAR); |
1595 |
| - $targetEl.data('scrtabs').enableSwipingElement = 'parent'; |
1596 |
| - } |
1597 |
| - |
1598 | 1641 | wrapNavTabsInstanceInScroller($targetEl, settings, readyCallback);
|
1599 | 1642 | });
|
1600 | 1643 |
|
|
1607 | 1650 | $targetEls.trigger(CONSTANTS.EVENTS.TABS_READY);
|
1608 | 1651 | };
|
1609 | 1652 |
|
1610 |
| - var $newTargetEl = buildNavTabsAndTabContentForTargetElementInstance($targetEl, settings, readyCallback); |
1611 |
| - |
1612 |
| - if (settings.enableSwiping) { |
1613 |
| - $newTargetEl.addClass(CONSTANTS.CSS_CLASSES.ALLOW_SCROLLBAR); |
1614 |
| - $newTargetEl.data('scrtabs').enableSwipingElement = 'self'; |
1615 |
| - } |
| 1653 | + buildNavTabsAndTabContentForTargetElementInstance($targetEl, settings, readyCallback); |
1616 | 1654 | });
|
1617 | 1655 | },
|
1618 | 1656 |
|
|
0 commit comments