[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 YUI.add('yui2-tabview', function(Y) { 2 var YAHOO = Y.YUI2; 3 /* 4 Copyright (c) 2011, Yahoo! Inc. All rights reserved. 5 Code licensed under the BSD License: 6 http://developer.yahoo.com/yui/license.html 7 version: 2.9.0 8 */ 9 (function() { 10 11 /** 12 * The tabview module provides a widget for managing content bound to tabs. 13 * @module tabview 14 * @requires yahoo, dom, event, element 15 * 16 */ 17 18 var Y = YAHOO.util, 19 Dom = Y.Dom, 20 Event = Y.Event, 21 document = window.document, 22 23 // STRING CONSTANTS 24 ACTIVE = 'active', 25 ACTIVE_INDEX = 'activeIndex', 26 ACTIVE_TAB = 'activeTab', 27 DISABLED = 'disabled', 28 CONTENT_EL = 'contentEl', 29 ELEMENT = 'element', 30 31 /** 32 * A widget to control tabbed views. 33 * @namespace YAHOO.widget 34 * @class TabView 35 * @extends YAHOO.util.Element 36 * @constructor 37 * @param {HTMLElement | String | Object} el(optional) The html 38 * element that represents the TabView, or the attribute object to use. 39 * An element will be created if none provided. 40 * @param {Object} attr (optional) A key map of the tabView's 41 * initial attributes. Ignored if first arg is attributes object. 42 */ 43 TabView = function(el, attr) { 44 attr = attr || {}; 45 if (arguments.length == 1 && !YAHOO.lang.isString(el) && !el.nodeName) { 46 attr = el; // treat first arg as attr object 47 el = attr.element || null; 48 } 49 50 if (!el && !attr.element) { // create if we dont have one 51 el = this._createTabViewElement(attr); 52 } 53 TabView.superclass.constructor.call(this, el, attr); 54 }; 55 56 YAHOO.extend(TabView, Y.Element, { 57 /** 58 * The className to add when building from scratch. 59 * @property CLASSNAME 60 * @default "navset" 61 */ 62 CLASSNAME: 'yui-navset', 63 64 /** 65 * The className of the HTMLElement containing the TabView's tab elements 66 * to look for when building from existing markup, or to add when building 67 * from scratch. 68 * All childNodes of the tab container are treated as Tabs when building 69 * from existing markup. 70 * @property TAB_PARENT_CLASSNAME 71 * @default "nav" 72 */ 73 TAB_PARENT_CLASSNAME: 'yui-nav', 74 75 /** 76 * The className of the HTMLElement containing the TabView's label elements 77 * to look for when building from existing markup, or to add when building 78 * from scratch. 79 * All childNodes of the content container are treated as content elements when 80 * building from existing markup. 81 * @property CONTENT_PARENT_CLASSNAME 82 * @default "nav-content" 83 */ 84 CONTENT_PARENT_CLASSNAME: 'yui-content', 85 86 _tabParent: null, 87 _contentParent: null, 88 89 /** 90 * Adds a Tab to the TabView instance. 91 * If no index is specified, the tab is added to the end of the tab list. 92 * @method addTab 93 * @param {YAHOO.widget.Tab} tab A Tab instance to add. 94 * @param {Integer} index The position to add the tab. 95 * @return void 96 */ 97 addTab: function(tab, index) { 98 var tabs = this.get('tabs'), 99 tabParent = this._tabParent, 100 contentParent = this._contentParent, 101 tabElement = tab.get(ELEMENT), 102 contentEl = tab.get(CONTENT_EL), 103 activeIndex = this.get(ACTIVE_INDEX), 104 before; 105 106 if (!tabs) { // not ready yet 107 this._queue[this._queue.length] = ['addTab', arguments]; 108 return false; 109 } 110 111 before = this.getTab(index); 112 index = (index === undefined) ? tabs.length : index; 113 114 tabs.splice(index, 0, tab); 115 116 if (before) { 117 tabParent.insertBefore(tabElement, before.get(ELEMENT)); 118 if (contentEl) { 119 contentParent.appendChild(contentEl); 120 } 121 } else { 122 tabParent.appendChild(tabElement); 123 if (contentEl) { 124 contentParent.appendChild(contentEl); 125 } 126 } 127 128 if ( !tab.get(ACTIVE) ) { 129 tab.set('contentVisible', false, true); /* hide if not active */ 130 if (index <= activeIndex) { 131 this.set(ACTIVE_INDEX, activeIndex + 1, true); 132 } 133 } else { 134 this.set(ACTIVE_TAB, tab, true); 135 this.set('activeIndex', index, true); 136 } 137 138 this._initTabEvents(tab); 139 }, 140 141 _initTabEvents: function(tab) { 142 tab.addListener( tab.get('activationEvent'), tab._onActivate, this, tab); 143 tab.addListener('activationEventChange', tab._onActivationEventChange, this, tab); 144 }, 145 146 _removeTabEvents: function(tab) { 147 tab.removeListener(tab.get('activationEvent'), tab._onActivate, this, tab); 148 tab.removeListener('activationEventChange', tab._onActivationEventChange, this, tab); 149 }, 150 151 /** 152 * Routes childNode events. 153 * @method DOMEventHandler 154 * @param {event} e The Dom event that is being handled. 155 * @return void 156 */ 157 DOMEventHandler: function(e) { 158 var target = Event.getTarget(e), 159 tabParent = this._tabParent, 160 tabs = this.get('tabs'), 161 tab, 162 tabEl, 163 contentEl; 164 165 166 if (Dom.isAncestor(tabParent, target) ) { 167 for (var i = 0, len = tabs.length; i < len; i++) { 168 tabEl = tabs[i].get(ELEMENT); 169 contentEl = tabs[i].get(CONTENT_EL); 170 171 if ( target == tabEl || Dom.isAncestor(tabEl, target) ) { 172 tab = tabs[i]; 173 break; // note break 174 } 175 } 176 177 if (tab) { 178 tab.fireEvent(e.type, e); 179 } 180 } 181 }, 182 183 /** 184 * Returns the Tab instance at the specified index. 185 * @method getTab 186 * @param {Integer} index The position of the Tab. 187 * @return YAHOO.widget.Tab 188 */ 189 getTab: function(index) { 190 return this.get('tabs')[index]; 191 }, 192 193 /** 194 * Returns the index of given tab. 195 * @method getTabIndex 196 * @param {YAHOO.widget.Tab} tab The tab whose index will be returned. 197 * @return int 198 */ 199 getTabIndex: function(tab) { 200 var index = null, 201 tabs = this.get('tabs'); 202 for (var i = 0, len = tabs.length; i < len; ++i) { 203 if (tab == tabs[i]) { 204 index = i; 205 break; 206 } 207 } 208 209 return index; 210 }, 211 212 /** 213 * Removes the specified Tab from the TabView. 214 * @method removeTab 215 * @param {YAHOO.widget.Tab} item The Tab instance to be removed. 216 * @return void 217 */ 218 removeTab: function(tab) { 219 var tabCount = this.get('tabs').length, 220 activeIndex = this.get(ACTIVE_INDEX), 221 index = this.getTabIndex(tab); 222 223 if ( tab === this.get(ACTIVE_TAB) ) { 224 if (tabCount > 1) { // select another tab 225 if (index + 1 === tabCount) { // if last, activate previous 226 this.set(ACTIVE_INDEX, index - 1); 227 } else { // activate next tab 228 this.set(ACTIVE_INDEX, index + 1); 229 } 230 } else { // no more tabs 231 this.set(ACTIVE_TAB, null); 232 } 233 } else if (index < activeIndex) { 234 this.set(ACTIVE_INDEX, activeIndex - 1, true); 235 } 236 237 this._removeTabEvents(tab); 238 this._tabParent.removeChild( tab.get(ELEMENT) ); 239 this._contentParent.removeChild( tab.get(CONTENT_EL) ); 240 this._configs.tabs.value.splice(index, 1); 241 242 tab.fireEvent('remove', { type: 'remove', tabview: this }); 243 }, 244 245 /** 246 * Provides a readable name for the TabView instance. 247 * @method toString 248 * @return String 249 */ 250 toString: function() { 251 var name = this.get('id') || this.get('tagName'); 252 return "TabView " + name; 253 }, 254 255 /** 256 * The transiton to use when switching between tabs. 257 * @method contentTransition 258 */ 259 contentTransition: function(newTab, oldTab) { 260 if (newTab) { 261 newTab.set('contentVisible', true); 262 } 263 if (oldTab) { 264 oldTab.set('contentVisible', false); 265 } 266 }, 267 268 /** 269 * setAttributeConfigs TabView specific properties. 270 * @method initAttributes 271 * @param {Object} attr Hash of initial attributes 272 */ 273 initAttributes: function(attr) { 274 TabView.superclass.initAttributes.call(this, attr); 275 276 if (!attr.orientation) { 277 attr.orientation = 'top'; 278 } 279 280 var el = this.get(ELEMENT); 281 282 if (!this.hasClass(this.CLASSNAME)) { 283 this.addClass(this.CLASSNAME); 284 } 285 286 /** 287 * The Tabs belonging to the TabView instance. 288 * @attribute tabs 289 * @type Array 290 */ 291 this.setAttributeConfig('tabs', { 292 value: [], 293 readOnly: true 294 }); 295 296 /** 297 * The container of the tabView's label elements. 298 * @property _tabParent 299 * @private 300 * @type HTMLElement 301 */ 302 this._tabParent = 303 this.getElementsByClassName(this.TAB_PARENT_CLASSNAME, 304 'ul' )[0] || this._createTabParent(); 305 306 /** 307 * The container of the tabView's content elements. 308 * @property _contentParent 309 * @type HTMLElement 310 * @private 311 */ 312 this._contentParent = 313 this.getElementsByClassName(this.CONTENT_PARENT_CLASSNAME, 314 'div')[0] || this._createContentParent(); 315 316 /** 317 * How the Tabs should be oriented relative to the TabView. 318 * Valid orientations are "top", "left", "bottom", and "right" 319 * @attribute orientation 320 * @type String 321 * @default "top" 322 */ 323 this.setAttributeConfig('orientation', { 324 value: attr.orientation, 325 method: function(value) { 326 var current = this.get('orientation'); 327 this.addClass('yui-navset-' + value); 328 329 if (current != value) { 330 this.removeClass('yui-navset-' + current); 331 } 332 333 if (value === 'bottom') { 334 this.appendChild(this._tabParent); 335 } 336 } 337 }); 338 339 /** 340 * The index of the tab currently active. 341 * @attribute activeIndex 342 * @type Int 343 */ 344 this.setAttributeConfig(ACTIVE_INDEX, { 345 value: attr.activeIndex, 346 validator: function(value) { 347 var ret = true, 348 tab; 349 if (value) { // cannot activate if disabled 350 tab = this.getTab(value); 351 if (tab && tab.get(DISABLED)) { 352 ret = false; 353 } 354 } 355 return ret; 356 } 357 }); 358 359 /** 360 * The tab currently active. 361 * @attribute activeTab 362 * @type YAHOO.widget.Tab 363 */ 364 this.setAttributeConfig(ACTIVE_TAB, { 365 value: attr[ACTIVE_TAB], 366 method: function(tab) { 367 var activeTab = this.get(ACTIVE_TAB); 368 369 if (tab) { 370 tab.set(ACTIVE, true); 371 } 372 373 if (activeTab && activeTab !== tab) { 374 activeTab.set(ACTIVE, false); 375 } 376 377 if (activeTab && tab !== activeTab) { // no transition if only 1 378 this.contentTransition(tab, activeTab); 379 } else if (tab) { 380 tab.set('contentVisible', true); 381 } 382 }, 383 validator: function(value) { 384 var ret = true; 385 if (value && value.get(DISABLED)) { // cannot activate if disabled 386 ret = false; 387 } 388 return ret; 389 } 390 }); 391 392 this.on('activeTabChange', this._onActiveTabChange); 393 this.on('activeIndexChange', this._onActiveIndexChange); 394 395 if ( this._tabParent ) { 396 this._initTabs(); 397 } 398 399 // Due to delegation we add all DOM_EVENTS to the TabView container 400 // but IE will leak when unsupported events are added, so remove these 401 this.DOM_EVENTS.submit = false; 402 this.DOM_EVENTS.focus = false; 403 this.DOM_EVENTS.blur = false; 404 this.DOM_EVENTS.change = false; 405 406 for (var type in this.DOM_EVENTS) { 407 if ( YAHOO.lang.hasOwnProperty(this.DOM_EVENTS, type) ) { 408 this.addListener.call(this, type, this.DOMEventHandler); 409 } 410 } 411 }, 412 413 /** 414 * Removes selected state from the given tab if it is the activeTab 415 * @method deselectTab 416 * @param {Int} index The tab index to deselect 417 */ 418 deselectTab: function(index) { 419 if (this.getTab(index) === this.get(ACTIVE_TAB)) { 420 this.set(ACTIVE_TAB, null); 421 } 422 }, 423 424 /** 425 * Makes the tab at the given index the active tab 426 * @method selectTab 427 * @param {Int} index The tab index to be made active 428 */ 429 selectTab: function(index) { 430 this.set(ACTIVE_TAB, this.getTab(index)); 431 }, 432 433 _onActiveTabChange: function(e) { 434 var activeIndex = this.get(ACTIVE_INDEX), 435 newIndex = this.getTabIndex(e.newValue); 436 437 if (activeIndex !== newIndex) { 438 if (!(this.set(ACTIVE_INDEX, newIndex)) ) { // NOTE: setting 439 // revert if activeIndex update fails (cancelled via beforeChange) 440 this.set(ACTIVE_TAB, e.prevValue); 441 } 442 } 443 }, 444 445 _onActiveIndexChange: function(e) { 446 // no set if called from ActiveTabChange event 447 if (e.newValue !== this.getTabIndex(this.get(ACTIVE_TAB))) { 448 if (!(this.set(ACTIVE_TAB, this.getTab(e.newValue))) ) { // NOTE: setting 449 // revert if activeTab update fails (cancelled via beforeChange) 450 this.set(ACTIVE_INDEX, e.prevValue); 451 } 452 } 453 }, 454 455 /** 456 * Creates Tab instances from a collection of HTMLElements. 457 * @method _initTabs 458 * @private 459 * @return void 460 */ 461 _initTabs: function() { 462 var tabs = Dom.getChildren(this._tabParent), 463 contentElements = Dom.getChildren(this._contentParent), 464 activeIndex = this.get(ACTIVE_INDEX), 465 tab, 466 attr, 467 active; 468 469 for (var i = 0, len = tabs.length; i < len; ++i) { 470 attr = {}; 471 472 if (contentElements[i]) { 473 attr.contentEl = contentElements[i]; 474 } 475 476 tab = new YAHOO.widget.Tab(tabs[i], attr); 477 this.addTab(tab); 478 479 if (tab.hasClass(tab.ACTIVE_CLASSNAME) ) { 480 active = tab; 481 } 482 } 483 if (activeIndex != undefined) { // not null or undefined 484 this.set(ACTIVE_TAB, this.getTab(activeIndex)); 485 } else { 486 this._configs[ACTIVE_TAB].value = active; // dont invoke method 487 this._configs[ACTIVE_INDEX].value = this.getTabIndex(active); 488 } 489 }, 490 491 _createTabViewElement: function(attr) { 492 var el = document.createElement('div'); 493 494 if ( this.CLASSNAME ) { 495 el.className = this.CLASSNAME; 496 } 497 498 return el; 499 }, 500 501 _createTabParent: function(attr) { 502 var el = document.createElement('ul'); 503 504 if ( this.TAB_PARENT_CLASSNAME ) { 505 el.className = this.TAB_PARENT_CLASSNAME; 506 } 507 508 this.get(ELEMENT).appendChild(el); 509 510 return el; 511 }, 512 513 _createContentParent: function(attr) { 514 var el = document.createElement('div'); 515 516 if ( this.CONTENT_PARENT_CLASSNAME ) { 517 el.className = this.CONTENT_PARENT_CLASSNAME; 518 } 519 520 this.get(ELEMENT).appendChild(el); 521 522 return el; 523 } 524 }); 525 526 527 YAHOO.widget.TabView = TabView; 528 })(); 529 530 (function() { 531 var Y = YAHOO.util, 532 Dom = Y.Dom, 533 Lang = YAHOO.lang, 534 535 536 // STRING CONSTANTS 537 ACTIVE_TAB = 'activeTab', 538 LABEL = 'label', 539 LABEL_EL = 'labelEl', 540 CONTENT = 'content', 541 CONTENT_EL = 'contentEl', 542 ELEMENT = 'element', 543 CACHE_DATA = 'cacheData', 544 DATA_SRC = 'dataSrc', 545 DATA_LOADED = 'dataLoaded', 546 DATA_TIMEOUT = 'dataTimeout', 547 LOAD_METHOD = 'loadMethod', 548 POST_DATA = 'postData', 549 DISABLED = 'disabled', 550 551 /** 552 * A representation of a Tab's label and content. 553 * @namespace YAHOO.widget 554 * @class Tab 555 * @extends YAHOO.util.Element 556 * @constructor 557 * @param element {HTMLElement | String} (optional) The html element that 558 * represents the Tab. An element will be created if none provided. 559 * @param {Object} properties A key map of initial properties 560 */ 561 Tab = function(el, attr) { 562 attr = attr || {}; 563 if (arguments.length == 1 && !Lang.isString(el) && !el.nodeName) { 564 attr = el; 565 el = attr.element; 566 } 567 568 if (!el && !attr.element) { 569 el = this._createTabElement(attr); 570 } 571 572 this.loadHandler = { 573 success: function(o) { 574 this.set(CONTENT, o.responseText); 575 }, 576 failure: function(o) { 577 } 578 }; 579 580 Tab.superclass.constructor.call(this, el, attr); 581 582 this.DOM_EVENTS = {}; // delegating to tabView 583 }; 584 585 YAHOO.extend(Tab, YAHOO.util.Element, { 586 /** 587 * The default tag name for a Tab's inner element. 588 * @property LABEL_INNER_TAGNAME 589 * @type String 590 * @default "em" 591 */ 592 LABEL_TAGNAME: 'em', 593 594 /** 595 * The class name applied to active tabs. 596 * @property ACTIVE_CLASSNAME 597 * @type String 598 * @default "selected" 599 */ 600 ACTIVE_CLASSNAME: 'selected', 601 602 /** 603 * The class name applied to active tabs. 604 * @property HIDDEN_CLASSNAME 605 * @type String 606 * @default "yui-hidden" 607 */ 608 HIDDEN_CLASSNAME: 'yui-hidden', 609 610 /** 611 * The title applied to active tabs. 612 * @property ACTIVE_TITLE 613 * @type String 614 * @default "active" 615 */ 616 ACTIVE_TITLE: 'active', 617 618 /** 619 * The class name applied to disabled tabs. 620 * @property DISABLED_CLASSNAME 621 * @type String 622 * @default "disabled" 623 */ 624 DISABLED_CLASSNAME: DISABLED, 625 626 /** 627 * The class name applied to dynamic tabs while loading. 628 * @property LOADING_CLASSNAME 629 * @type String 630 * @default "disabled" 631 */ 632 LOADING_CLASSNAME: 'loading', 633 634 /** 635 * Provides a reference to the connection request object when data is 636 * loaded dynamically. 637 * @property dataConnection 638 * @type Object 639 */ 640 dataConnection: null, 641 642 /** 643 * Object containing success and failure callbacks for loading data. 644 * @property loadHandler 645 * @type object 646 */ 647 loadHandler: null, 648 649 _loading: false, 650 651 /** 652 * Provides a readable name for the tab. 653 * @method toString 654 * @return String 655 */ 656 toString: function() { 657 var el = this.get(ELEMENT), 658 id = el.id || el.tagName; 659 return "Tab " + id; 660 }, 661 662 /** 663 * setAttributeConfigs Tab specific properties. 664 * @method initAttributes 665 * @param {Object} attr Hash of initial attributes 666 */ 667 initAttributes: function(attr) { 668 attr = attr || {}; 669 Tab.superclass.initAttributes.call(this, attr); 670 671 /** 672 * The event that triggers the tab's activation. 673 * @attribute activationEvent 674 * @type String 675 */ 676 this.setAttributeConfig('activationEvent', { 677 value: attr.activationEvent || 'click' 678 }); 679 680 /** 681 * The element that contains the tab's label. 682 * @attribute labelEl 683 * @type HTMLElement 684 */ 685 this.setAttributeConfig(LABEL_EL, { 686 value: attr[LABEL_EL] || this._getLabelEl(), 687 method: function(value) { 688 value = Dom.get(value); 689 var current = this.get(LABEL_EL); 690 691 if (current) { 692 if (current == value) { 693 return false; // already set 694 } 695 696 current.parentNode.replaceChild(value, current); 697 this.set(LABEL, value.innerHTML); 698 } 699 } 700 }); 701 702 /** 703 * The tab's label text (or innerHTML). 704 * @attribute label 705 * @type String 706 */ 707 this.setAttributeConfig(LABEL, { 708 value: attr.label || this._getLabel(), 709 method: function(value) { 710 var labelEl = this.get(LABEL_EL); 711 if (!labelEl) { // create if needed 712 this.set(LABEL_EL, this._createLabelEl()); 713 } 714 715 labelEl.innerHTML = value; 716 } 717 }); 718 719 /** 720 * The HTMLElement that contains the tab's content. 721 * @attribute contentEl 722 * @type HTMLElement 723 */ 724 this.setAttributeConfig(CONTENT_EL, { 725 value: attr[CONTENT_EL] || document.createElement('div'), 726 method: function(value) { 727 value = Dom.get(value); 728 var current = this.get(CONTENT_EL); 729 730 if (current) { 731 if (current === value) { 732 return false; // already set 733 } 734 if (!this.get('selected')) { 735 Dom.addClass(value, this.HIDDEN_CLASSNAME); 736 } 737 current.parentNode.replaceChild(value, current); 738 this.set(CONTENT, value.innerHTML); 739 } 740 } 741 }); 742 743 /** 744 * The tab's content. 745 * @attribute content 746 * @type String 747 */ 748 this.setAttributeConfig(CONTENT, { 749 value: attr[CONTENT] || this.get(CONTENT_EL).innerHTML, 750 method: function(value) { 751 this.get(CONTENT_EL).innerHTML = value; 752 } 753 }); 754 755 /** 756 * The tab's data source, used for loading content dynamically. 757 * @attribute dataSrc 758 * @type String 759 */ 760 this.setAttributeConfig(DATA_SRC, { 761 value: attr.dataSrc 762 }); 763 764 /** 765 * Whether or not content should be reloaded for every view. 766 * @attribute cacheData 767 * @type Boolean 768 * @default false 769 */ 770 this.setAttributeConfig(CACHE_DATA, { 771 value: attr.cacheData || false, 772 validator: Lang.isBoolean 773 }); 774 775 /** 776 * The method to use for the data request. 777 * @attribute loadMethod 778 * @type String 779 * @default "GET" 780 */ 781 this.setAttributeConfig(LOAD_METHOD, { 782 value: attr.loadMethod || 'GET', 783 validator: Lang.isString 784 }); 785 786 /** 787 * Whether or not any data has been loaded from the server. 788 * @attribute dataLoaded 789 * @type Boolean 790 */ 791 this.setAttributeConfig(DATA_LOADED, { 792 value: false, 793 validator: Lang.isBoolean, 794 writeOnce: true 795 }); 796 797 /** 798 * Number if milliseconds before aborting and calling failure handler. 799 * @attribute dataTimeout 800 * @type Number 801 * @default null 802 */ 803 this.setAttributeConfig(DATA_TIMEOUT, { 804 value: attr.dataTimeout || null, 805 validator: Lang.isNumber 806 }); 807 808 /** 809 * Arguments to pass when POST method is used 810 * @attribute postData 811 * @default null 812 */ 813 this.setAttributeConfig(POST_DATA, { 814 value: attr.postData || null 815 }); 816 817 /** 818 * Whether or not the tab is currently active. 819 * If a dataSrc is set for the tab, the content will be loaded from 820 * the given source. 821 * @attribute active 822 * @type Boolean 823 */ 824 this.setAttributeConfig('active', { 825 value: attr.active || this.hasClass(this.ACTIVE_CLASSNAME), 826 method: function(value) { 827 if (value === true) { 828 this.addClass(this.ACTIVE_CLASSNAME); 829 this.set('title', this.ACTIVE_TITLE); 830 } else { 831 this.removeClass(this.ACTIVE_CLASSNAME); 832 this.set('title', ''); 833 } 834 }, 835 validator: function(value) { 836 return Lang.isBoolean(value) && !this.get(DISABLED) ; 837 } 838 }); 839 840 /** 841 * Whether or not the tab is disabled. 842 * @attribute disabled 843 * @type Boolean 844 */ 845 this.setAttributeConfig(DISABLED, { 846 value: attr.disabled || this.hasClass(this.DISABLED_CLASSNAME), 847 method: function(value) { 848 if (value === true) { 849 this.addClass(this.DISABLED_CLASSNAME); 850 } else { 851 this.removeClass(this.DISABLED_CLASSNAME); 852 } 853 }, 854 validator: Lang.isBoolean 855 }); 856 857 /** 858 * The href of the tab's anchor element. 859 * @attribute href 860 * @type String 861 * @default '#' 862 */ 863 this.setAttributeConfig('href', { 864 value: attr.href || 865 this.getElementsByTagName('a')[0].getAttribute('href', 2) || '#', 866 method: function(value) { 867 this.getElementsByTagName('a')[0].href = value; 868 }, 869 validator: Lang.isString 870 }); 871 872 /** 873 * The Whether or not the tab's content is visible. 874 * @attribute contentVisible 875 * @type Boolean 876 * @default false 877 */ 878 this.setAttributeConfig('contentVisible', { 879 value: attr.contentVisible, 880 method: function(value) { 881 if (value) { 882 Dom.removeClass(this.get(CONTENT_EL), this.HIDDEN_CLASSNAME); 883 884 if ( this.get(DATA_SRC) ) { 885 // load dynamic content unless already loading or loaded and caching 886 if ( !this._loading && !(this.get(DATA_LOADED) && this.get(CACHE_DATA)) ) { 887 this._dataConnect(); 888 } 889 } 890 } else { 891 Dom.addClass(this.get(CONTENT_EL), this.HIDDEN_CLASSNAME); 892 } 893 }, 894 validator: Lang.isBoolean 895 }); 896 }, 897 898 _dataConnect: function() { 899 if (!Y.Connect) { 900 return false; 901 } 902 903 Dom.addClass(this.get(CONTENT_EL).parentNode, this.LOADING_CLASSNAME); 904 this._loading = true; 905 this.dataConnection = Y.Connect.asyncRequest( 906 this.get(LOAD_METHOD), 907 this.get(DATA_SRC), 908 { 909 success: function(o) { 910 this.loadHandler.success.call(this, o); 911 this.set(DATA_LOADED, true); 912 this.dataConnection = null; 913 Dom.removeClass(this.get(CONTENT_EL).parentNode, 914 this.LOADING_CLASSNAME); 915 this._loading = false; 916 }, 917 failure: function(o) { 918 this.loadHandler.failure.call(this, o); 919 this.dataConnection = null; 920 Dom.removeClass(this.get(CONTENT_EL).parentNode, 921 this.LOADING_CLASSNAME); 922 this._loading = false; 923 }, 924 scope: this, 925 timeout: this.get(DATA_TIMEOUT) 926 }, 927 928 this.get(POST_DATA) 929 ); 930 }, 931 _createTabElement: function(attr) { 932 var el = document.createElement('li'), 933 a = document.createElement('a'), 934 label = attr.label || null, 935 labelEl = attr.labelEl || null; 936 937 a.href = attr.href || '#'; // TODO: Use Dom.setAttribute? 938 el.appendChild(a); 939 940 if (labelEl) { // user supplied labelEl 941 if (!label) { // user supplied label 942 label = this._getLabel(); 943 } 944 } else { 945 labelEl = this._createLabelEl(); 946 } 947 948 a.appendChild(labelEl); 949 950 return el; 951 }, 952 953 _getLabelEl: function() { 954 return this.getElementsByTagName(this.LABEL_TAGNAME)[0]; 955 }, 956 957 _createLabelEl: function() { 958 var el = document.createElement(this.LABEL_TAGNAME); 959 return el; 960 }, 961 962 963 _getLabel: function() { 964 var el = this.get(LABEL_EL); 965 966 if (!el) { 967 return undefined; 968 } 969 970 return el.innerHTML; 971 }, 972 973 _onActivate: function(e, tabview) { 974 var tab = this, 975 silent = false; 976 977 Y.Event.preventDefault(e); 978 if (tab === tabview.get(ACTIVE_TAB)) { 979 silent = true; // dont fire activeTabChange if already active 980 } 981 tabview.set(ACTIVE_TAB, tab, silent); 982 }, 983 984 _onActivationEventChange: function(e) { 985 var tab = this; 986 987 if (e.prevValue != e.newValue) { 988 tab.removeListener(e.prevValue, tab._onActivate); 989 tab.addListener(e.newValue, tab._onActivate, this, tab); 990 } 991 } 992 }); 993 994 995 /** 996 * Fires when a tab is removed from the tabview 997 * @event remove 998 * @type CustomEvent 999 * @param {Event} An event object with fields for "type" ("remove") 1000 * and "tabview" (the tabview instance it was removed from) 1001 */ 1002 1003 YAHOO.widget.Tab = Tab; 1004 })(); 1005 1006 YAHOO.register("tabview", YAHOO.widget.TabView, {version: "2.9.0", build: "2800"}); 1007 1008 }, '2.9.0' ,{"requires": ["yui2-yahoo", "yui2-dom", "yui2-event", "yui2-skin-sam-tabview", "yui2-element"], "optional": ["yui2-connection"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |