angular2 隨鼠標移動伸縮的表格創建組件

功能目標:

    用於獲取用戶輸入表格行、列數的組件,隨鼠標移動,表格行列數變化,覆蓋區域填充藍色,效果如下圖所示。

    

思路:

   通過ngFor動態構造表格的行和列,通過maxrow,maxcol 控制表格白色區域,用rows,cols控制表格藍色區域,使maxrow大於rows、maxcol大於cols。 

   由於ngFor沒有i<n迭代功能,使用[0,1,2....]數組來實現。

代碼:

import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
    selector: 'app-tablecreator',
    template: ` 
    <table border="1" cellpadding="8" style="border-collapse:collapse;" (mouseover)="mouseover($event)" (click)="cellclick.emit($event)">
        <tbody>
            <tr *ngFor="let i of numbers.slice(0,maxrow)">
                <td *ngFor="let j of numbers.slice(0,maxcol)" [style.background-color]="(i<rows&&j<cols)?'blue':'white'"></td>
            </tr>
        </tbody>
    </table>
    <div>{{rows}}×{{cols}}</div>
      `
})
export class TableCreatorComponent {
    @Input() rows: number;
    @Input() cols: number;
    @Output() cellclick = new EventEmitter<Event>();
    numbers: number[];
    get maxrow() {
        return this.rows < 4 ? 5 : this.rows + 1;
    }
    get maxcol() {
        return this.cols < 4 ? 5 : this.cols + 1;
    }
    constructor() {
        this.rows = 1;
        this.cols = 1;
        this.numbers = Array(100).fill(0).map((x, i) => i);
    }

    mouseover(e) {
        let node = (e.srcElement != null) ? e.srcElement : e.target;
        const td = this.getParentByName(node, 'TD');

        if (td != null) {
            const row2 = this.getParentByName(td, 'TR');
            this.rows = row2.sectionRowIndex + 1;
            this.cols = td.cellIndex + 1;
            this.consume(e);
        }
    }

	/**
	 * Returns the first ancestor of the current selection with the given name.
	 */
    getParentByName(node, name, stopAt?) {
        while (node != null) {
            if (node.nodeName == name) {
                return node;
            }

            if (node == stopAt) {
                return null;
            }

            node = node.parentNode;
        }

        return node;
    }

    consume(evt: Event): void {
        if (evt.preventDefault) {
            evt.stopPropagation();
            evt.preventDefault();
        }

        // Opera
        evt.isConsumed = true;

        // Other browsers
        if (!evt.preventDefault) {
            evt.returnValue = false;
        }
    }
}

使用:

    截圖中使用了按鈕和primeng OverlayPanel,tablecreator置於OverlayPanel中,在點擊按鈕時toggle OverlayPanel,在表格cellclick時再次toggle OverlayPanel。

    注意cellclick toggle 時需要給出與第一次toggle等價的target,否則OverlayPanel會再次出現在別的位置。

<button pButton type="button" icon="fa fa-table" [title]="'table'|lang" (click)="op.toggle($event)"></button>
<p-overlayPanel #op>
    <app-tablecreator (cellclick)="op.toggle(null,op.target)"></app-tablecreator>
</p-overlayPanel>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章