import {NgModule,Component,ElementRef,OnDestroy,Input,Output,EventEmitter,HostListener,AfterContentInit, ContentChildren,ContentChild,QueryList,TemplateRef,EmbeddedViewRef,ViewContainerRef} from '@angular/core'; import {CommonModule} from '@angular/common'; import {SharedModule,PrimeTemplate} from '../common/shared'; import {BlockableUI} from '../common/blockableui'; let idx: number = 0; @Component({ selector: '[p-tabViewNav]', host:{ '[class.ui-tabview-nav]': 'true', '[class.ui-helper-reset]': 'true', '[class.ui-helper-clearfix]': 'false', '[class.ui-widget-header]': 'true', '[class.ui-corner-all]': 'true' }, template: `
  • {{tab.header}}
  • `, }) export class TabViewNav { @Input() tabs: TabPanel[]; @Input() orientation: string = 'top'; @Output() onTabClick: EventEmitter = new EventEmitter(); @Output() onTabCloseClick: EventEmitter = new EventEmitter(); getDefaultHeaderClass(tab:TabPanel) { let styleClass = 'ui-corner-' + this.orientation; if(tab.headerStyleClass) { styleClass = styleClass + " " + tab.headerStyleClass; } return styleClass; } clickTab(event, tab: TabPanel) { this.onTabClick.emit({ originalEvent: event, tab: tab }) } clickClose(event, tab: TabPanel) { this.onTabCloseClick.emit({ originalEvent: event, tab: tab }) } } @Component({ selector: 'p-tabPanel', template: `
    ` }) export class TabPanel implements AfterContentInit,OnDestroy { @Input() header: string; @Input() disabled: boolean; @Input() closable: boolean; @Input() headerStyle: any; @Input() headerStyleClass: string; @Input() leftIcon: string; @Input() rightIcon: string; @Input() cache: boolean = true; @ContentChildren(PrimeTemplate) templates: QueryList; constructor(public viewContainer: ViewContainerRef) {} closed: boolean; view: EmbeddedViewRef; _selected: boolean; loaded: boolean; id: string = `ui-tabpanel-${idx++}`; contentTemplate: TemplateRef; ngAfterContentInit() { this.templates.forEach((item) => { switch(item.getType()) { case 'content': this.contentTemplate = item.template; break; default: this.contentTemplate = item.template; break; } }); } @Input() get selected(): boolean { return this._selected; } set selected(val: boolean) { this._selected = val; this.loaded = true; } ngOnDestroy() { this.view = null; } } @Component({ selector: 'p-tabView', template: `
        `, }) export class TabView implements AfterContentInit,BlockableUI { @Input() orientation: string = 'top'; @Input() style: any; @Input() styleClass: string; @Input() controlClose: boolean; @ContentChildren(TabPanel) tabPanels: QueryList; @Output() onChange: EventEmitter = new EventEmitter(); @Output() onClose: EventEmitter = new EventEmitter(); @Output() activeIndexChange: EventEmitter = new EventEmitter(); initialized: boolean; tabs: TabPanel[]; _activeIndex: number; _lazy: boolean; preventActiveIndexPropagation: boolean; constructor(public el: ElementRef) {} @Input() get lazy(): boolean { return this._lazy; } set lazy(val: boolean) { this._lazy = val; console.log('Lazy property of TabView is deprecated, use an ngTemplate inside a TabPanel instead for Lazy Loading'); } ngAfterContentInit() { this.initTabs(); this.tabPanels.changes.subscribe(_ => { this.initTabs(); }); } initTabs(): void { this.tabs = this.tabPanels.toArray(); let selectedTab: TabPanel = this.findSelectedTab(); if(!selectedTab && this.tabs.length) { if(this.activeIndex != null && this.tabs.length > this.activeIndex) this.tabs[this.activeIndex].selected = true; else this.tabs[0].selected = true; } } open(event: Event, tab: TabPanel) { if(tab.disabled) { if(event) { event.preventDefault(); } return; } if(!tab.selected) { let selectedTab: TabPanel = this.findSelectedTab(); if(selectedTab) { selectedTab.selected = false } tab.selected = true; let selectedTabIndex = this.findTabIndex(tab); this.preventActiveIndexPropagation = true; this.activeIndexChange.emit(selectedTabIndex); this.onChange.emit({originalEvent: event, index: selectedTabIndex}); } if(event) { event.preventDefault(); } } close(event: Event, tab: TabPanel) { if(this.controlClose) { this.onClose.emit({ originalEvent: event, index: this.findTabIndex(tab), close: () => { this.closeTab(tab); }} ); } else { this.closeTab(tab); this.onClose.emit({ originalEvent: event, index: this.findTabIndex(tab) }); } event.stopPropagation(); } closeTab(tab: TabPanel) { if(tab.selected) { tab.selected = false; for(let i = 0; i < this.tabs.length; i++) { let tabPanel = this.tabs[i]; if(!tabPanel.closed&&!tab.disabled) { tabPanel.selected = true; break; } } } tab.closed = true; } findSelectedTab() { for(let i = 0; i < this.tabs.length; i++) { if(this.tabs[i].selected) { return this.tabs[i]; } } return null; } findTabIndex(tab: TabPanel) { let index = -1; for(let i = 0; i < this.tabs.length; i++) { if(this.tabs[i] == tab) { index = i; break; } } return index; } getBlockableElement(): HTMLElement { return this.el.nativeElement.children[0]; } @Input() get activeIndex(): number { return this._activeIndex; } set activeIndex(val:number) { this._activeIndex = val; if(this.preventActiveIndexPropagation) { this.preventActiveIndexPropagation = false; return; } if(this.tabs && this.tabs.length && this._activeIndex != null && this.tabs.length > this._activeIndex) { this.findSelectedTab().selected = false; this.tabs[this._activeIndex].selected = true; } } } @NgModule({ imports: [CommonModule,SharedModule], exports: [TabView,TabPanel,TabViewNav,SharedModule], declarations: [TabView,TabPanel,TabViewNav] }) export class TabViewModule { }