jsdk-offical
Version:
JSDK is the most comprehensive TypeScript framework, like JDK.
267 lines (222 loc) • 9.55 kB
text/typescript
/**
* @project JSDK
* @license MIT
* @website https://github.com/fengboyue/jsdk
*
* @version 2.0.0
* @author Frank.Feng
*/
/// <reference path="Widget.ts"/>
module JS {
export namespace fx {
export enum TabFaceMode {
horizontal = 'horizontal',
vertical = 'vertical',
pill = 'pill',
outline = 'outline',
underline = 'underline'
}
export type TabEvents = WidgetEvents | 'activing' | 'actived';
export interface TabListeners extends WidgetListeners<Tab> {
activing?: (this: Tab, e: Event, toEl: JQuery, fromEl: JQuery) => void;
actived?: (this: Tab, e: Event, toEl: JQuery, fromEl: JQuery) => void;
}
export type TabItem = {
heading: string;
content?: string | Element | JQuery;
disabled?: boolean;
}
export class TabConfig extends WidgetConfig<Tab> {
activeIndex?: number = 0;
faceMode?: TabFaceMode | Array<TabFaceMode> = null; //外观模式
data?: TabItem[];
headCls?: string;
headLeftWidth?: string | number = '15%';
headStyle?: string;
listeners?: TabListeners;
}
export class Tab extends Widget {
/**
* @constructor
* @param {TabConfig} cfg
*/
constructor(cfg: TabConfig) {
super(cfg);
}
public disableTab(num: number) {
let index = this._limitIndex(num);
if(index<0) return this;
let cfg = <TabConfig>this._config;
cfg.data[index].disabled = true;
let tab = $(`#${this.id}_headers li:nth-child(${index + 1}) a`);
tab.addClass('disabled');
return this
}
public enableTab(num: number) {
let index = this._limitIndex(num);
if(index<0) return this;
let cfg = <TabConfig>this._config;
cfg.data[index].disabled = false;
let tab = $(`#${this.id}_headers li:nth-child(${index + 1}) a`);
tab.removeClass('disabled');
return this
}
public isEnabledTab(num: number): boolean {
let size = this.length();
if ( size==0 || num < 1 || num > size) return false;
let cfg = <TabConfig>this._config;
return cfg.data && !cfg.data[num-1].disabled;
}
public activeTab(num: number) {
let index = this._limitIndex(num);
if(index<0) return this;
let cfg = <TabConfig>this._config;
cfg.activeIndex = index;
cfg.data[index].disabled = false;
let tab = $(`#${this.id}_headers li:nth-child(${index + 1}) a`);
tab.removeClass('disabled').css('display', '').tab('show');
return this;
}
public isActivedTab(num: number): boolean {
let tab = $(`#${this.id}_headers li:nth-child(${num}) a`);
return tab.length == 1 && tab.hasClass('active')
}
private _limitIndex(num: number) {
let size = this.length();
if(size==0) return -1;
if (num >= size) {
return size - 1
} else if (num < 1) return 0;
return num-1
}
public hideTab(num: number) {
this.activeTab(num-1);
$(`#${this.id}_headers li:nth-child(${num}) a`).css('display', 'none');
return this
}
public showTab(num: number) {
$(`#${this.id}_headers li:nth-child(${num}) a`).css('display', '');
return this
}
public isShownTab(num: number): boolean {
let tab = $(`#${this.id}_headers li:nth-child(${num}) a`);
return tab.length == 1 && tab.css('display') != 'none'
}
public getActiveIndex(): number {
return (<TabConfig>this._config).activeIndex+1;
}
public clear() {
return this.tabs(null)
}
public tabs(): TabItem[]
public tabs(items: TabItem[]): this
public tabs(items?: TabItem[]): any {
if (arguments.length == 0) return (<TabConfig>this._config).data;
(<TabConfig>this._config).data = items;
this.render();
return this
}
public addTab(tabs: TabItem | TabItem[], from?: number) {
let size = this.length();
if (!Types.isDefined(from) || from > size) {
from = size+1
} else if (size==0||from < 1) from = 1;
let cfg = <TabConfig>this._config;
cfg.data = cfg.data || [];
cfg.data.add(Arrays.toArray(tabs), from-1);
this.render();
return this
}
public removeTab(num: number) {
if (num > this.length() || num < 1) return this;
let cfg = <TabConfig>this._config;
cfg.data = cfg.data || [];
cfg.data.remove(num-1);
this.render();
return this
}
public removeTabHeading(heading: string) {
let cfg = <TabConfig>this._config;
cfg.data = cfg.data || [];
let i = cfg.data.findIndex((item: TabItem) => {
return heading == item.heading
}, 0)
if (i < 0) return this;
return this.removeTab(i+1)
}
public length(): number {
let data = (<TabConfig>this._config).data;
return data ? data.length : 0;
}
private _head(item: TabItem, i: number) {
return `
<li class="nav-item">
<a id="${this.id}_${i}-tab" jsfx-index="${i}" class="nav-link ${item.disabled ? 'disabled' : ''}"
data-toggle="tab" href="#${this.id}_${i}" role="tab" aria-controls="${this.id}_${i}" aria-selected="false">
${item.heading}</a>
</li>
`
}
private _content(item: TabItem, i: number) {
let html = Types.isString(item.content) ? <string>item.content : $(item.content).html();
return `<div class="tab-pane fade" id="${this.id}_${i}" role="tabpanel" aria-labelledby="${this.id}_${i}-tab">${html || ''}</div>`
}
private _html() {
let cfg = <TabConfig>this._config,
data: TabItem[] = cfg.data,
heads = '',
contents = '';
if (!data) return '';
data.forEach((item, i) => {
heads += this._head(item, i);
contents += this._content(item, i);
})
let cls = '';
if (this._hasFaceMode(TabFaceMode.pill)) {
cls += ' nav-pills'
} else if (this._hasFaceMode(TabFaceMode.underline)) {
cls += ' jsfx-tab-underline'
} else {
cls += ' nav-tabs'
}
cls += ' ' + cfg.colorMode || '';
let isVtl = this._hasFaceMode(TabFaceMode.vertical);
if (isVtl) cls += ' flex-column';
let hHtml = `<ul id="${this.id}_headers" role="tablist" class="nav${cls} ${cfg.headCls || ''}" style="${cfg.headStyle || ''}">${heads}</ul>`,
cHtml = `<div class="${isVtl ? 'vertical' : ''} tab-content" style="height:${CssTool.normValue(cfg.height, '100%')};">${contents}</div>`,
leftWidth = CssTool.normValue(cfg.headLeftWidth, '100%');
return isVtl ?
`
<div class="w-100">
<div style="float:left;width:${leftWidth};">${hHtml}</div>
<div style="margin-left:${leftWidth};">${cHtml}</div>
</div>
` : `${hHtml}${cHtml}`
}
protected _render() {
this.widgetEl.html(this._html());
if (this.length() > 0) {
let tablist = this.widgetEl.find('ul[role=tablist]');
tablist.on('show.bs.tab', (e: JQuery.Event) => {
this._fire('activing', [e.target, e.relatedTarget])
});
tablist.on('shown.bs.tab', (e: JQuery.Event) => {
this._fire('actived', [e.target, e.relatedTarget])
});
this.activeTab(this.getActiveIndex());
}
}
protected _destroy() {
this.widgetEl.find('a[role=tab]').each(function () { $(this).tab('dispose') });
super._destroy();
}
}
}
}
import Tab = JS.fx.Tab;
import TabFaceMode = JS.fx.TabFaceMode;
import TabEvents = JS.fx.TabEvents;
import TabListeners = JS.fx.TabListeners;
import TabItem = JS.fx.TabItem;
import TabConfig = JS.fx.TabConfig;