tym-table-editor
Version:
'tym-table-editor' is a simple table editor component.
765 lines (564 loc) • 19.5 kB
Markdown
# `[tym-table-editor]`
`tym-table-editor` は,シンプルなtable編集の `angular` コンポーネントです。
<br>
表示サンプル (Display image)

動作イメージ (Demo screen)
[https://shinichi-tym.github.io/tym-ng-ws-demo/index.html#tym-table-editor]
## インストール `(Installation)`
<br>
次のコマンド実行します。
```
npm install tym-table-editor
```
<br>
---
<br>
> ## 基本的な使い方 `(Basic usage)`
<br>
表示される場所に htmlタグ を用意し,その中に `<ngx-tym-table-editor>` タグを作成します。
``` html
<div style="width:90%;height:400px;overflow:auto;">
<ngx-tym-table-editor #tymTableEditor
[data]="data"
><ngx-tym-table-editor>
</div>
```
コンポーネントを利用できるようにします。
``` typescript :app.module.ts
:
import { TymTableEditorModule } from "tym-table-editor";
:
@NgModule({
declarations: [ .. ],
imports: [ TymTableEditorModule ],
```
コンポーネントの機能を利用する。
``` typescript :app.component.ts
:
import { TymTableEditorComponent } from "tym-table-editor";
import { TYM_EDITOR_DEF } from "tym-table-editor";
:
@ViewChild("tymTableEditor")
private tymTableEditor?: TymTableEditorComponent;
:
//
this.tymTableEditor?.getCells(...);
```
TymModalService / TymTableInputComponent を利用できるようにします。
``` typescript :app.component.ts
:
import { TymTableInputComponent } from "tym-table-editor";
import { TymModalService } from "tym-modals";
:
constructor(
private modal: TymModalService
:
// TymTableInputComponent を利用し日付(<input type=date>)を入力できるようにする
let def: TYM_EDITOR_DEF = {
col: 1,
editfnc: async (elm: HTMLElement, val: string, type?: string, col?: number) => {
const provider = TymTableInputComponent.provider('date', val, elm);
const componentRef = await this.modal.open(
TymTableInputComponent, provider, false, () => { });
const component = componentRef.instance as TymTableInputComponent;
return (component.vals.isEscape) ? val : component.vals.ret;
}
}
```
表示するためのデータを用意します。
``` typescript
let data = [
[ 'data 1', 'data 2', 123, ''],
[ '3', '4', 12345, 'data data data data 4'],
[ '', '', 1234567, 'data data data data 5']
];
```
<br>
---
<br>
> ## 機能 `(Features)`
<br>
- [基本機能](#基本機能) (Basic Function)
- [キーボード操作](#キーボード操作) (Keyboard operation)
- [セルサイズ自動変更](#セルサイズ自動変更) (Cell Size Auto Change)
- [セルサイズ変更](#セルサイズ変更) (Cell Size Change)
- [セル選択](#セル選択) (Cell Selection)
- [セル形式](#セル形式) (Cell Type)
- [表示文字編集機能](#表示文字編集機能) (String Formatter)
- [文字編集機能切替](#文字編集機能切替) (Switching String Editor)
- [コンテキストイベント](#コンテキストイベント) (Contextmenu event)
- [カスタマイズ](#カスタマイズ) (Customization)
- *`please wait...`*
<br>
- [公開関数](#公開関数) (Public Functions)
<br>
---
<br>
> ### 基本機能
<br>
- `row, col, data` 値を指定すると,その値に従ってテーブルを表示します。
- [定義]
``` html
<ngx-tym-table-editor #tymTableEditor
[row]="row"
[col]="col"
[defs]="defs"
[data]="data"
[menu]="menu"
[opts]="opts"
></ngx-tym-table-editor>
```
- `row: number`
- 表示する行数, 省略時は30行 (supports 1~99)
- `col: number`
- 表示する列数, 省略時は20列 (supports 1~99)
- `defs: TYM_EDITOR_DEF[]`
``` typescript
/** カラム定義 */
export type TYM_EDITOR_DEF = {
/** 対象列番号(1~) */
col: number;
/** 対象列タイプ */
type?: string;
/** 対象列揃え指定 {'left' | 'center' | 'right'}, 規定値: 'left' */
align?: 'left' | 'center' | 'right';
/** 表示モードだけにする, 規定値: false */
readonly?: boolean;
/** 値を表示文字に変換する関数, 規定値: なし */
viewfnc?: (val: string, type?: string, col?: number) => string;
/** 値を編集する関数, 規定値: なし */
editfnc?: (elm: HTMLElement, val: string, type?: string, col?: number) => Promise<string | null>;
}
```
- `data: string[][]`
- 表示するデータ
- `menu: (event: MouseEvent, row1: number, col1: number, row2: number, col2: number): boolean`
- コンテキストメニューイベント関数
- `opts: TYM_EDITOR_OPTS`
``` typescript
/** オプション定義 */
export type TYM_EDITOR_OPTS = {
/** 選択, カレントセルを折り返ししない */
whiteSpaceNoWrap?: boolean;
/** 編集モードの解除時に列のリサイズを実行する */
editModeAutoResize?: boolean;
/** フラットデザインにする */
flatDesign?: boolean;
/** 垂直方向のリサイズを無しにする */
noVerticalResize?: boolean;
}
```
<br>
---
<br>
> ### キーボード操作
<br>
[表示モード]
- 上下左右のキーでフォーカス位置を移動できます。
- `Shift` キーと上下左右キーで選択範囲を変更できます。
- `Shift` キーとマウスクリックで選択範囲を変更できます。
- `Shift` キー無し, 上下左右キーで選択範囲が解除されます。
- `Tab`, `Shift+Tab` キーでフォーカス位置を左右に移動できます。
- `Enter`, `Shift+Enter` キーでフォーカス位置を上下に移動できます。
- `Tab`, `Shift+Tab` キーでは, 選択範囲内を移動します。
- `Enter`, `Shift+Enter` キーでは, 選択範囲内を移動します。
- `Home`, `End` キーでフォーカス位置を行頭行末に移動できます。
- `Ctrl+Home`, `Ctrl+End` キーでフォーカス位置をテーブルの先頭末尾に移動できます。
- `F2` キーで **編集モード** になります。
- `Backspace` キーで文字を消去し **編集モード** になります。
- `Delete` キーでフォーカス位置または選択範囲内の文字を消去します。
- `Shift+Delete` キーでフォーカス位置または選択範囲内の文字を切り取ります。
- `Ctrl+x` キーでフォーカス位置または選択範囲内の文字を切り取ります。
- `Ctrl+c`, `Ctrl+Insert` キーでフォーカス位置または選択範囲内の文字をコピーします。
- `Ctrl+v`, `Shift+Insert` キーでフォーカス位置に文字列を貼り付けます。
文字列は, 単純文字列またはタブ文字/改行文字区切りの文字群。
- `Ctrl+z` キーで変更を元に戻します。
- `Ctrl+y`, `Ctrl+Shift+z` キーで元に戻した変更をやり直します。
- `Escape` キー 2回 でクリップボードを消去します。
- その他のキーで **編集モード** になり, 入力した文字に置き換えます。
[編集モード]
- `Tab`, `Shift+Tab` キーで **表示モード** になります。
- `Tab`, `Shift+Tab` キーで, 入力文字を確定し, フォーカス位置を左右に移動できます。
- `Enter`, `Shift+Enter` キーで **表示モード** になります。
- `Enter`, `Shift+Enter` キーで, 入力文字を確定し, フォーカス位置を上下に移動できます。
- `Tab`, `Shift+Tab` キーでは, 選択範囲内を移動します。
- `Enter`, `Shift+Enter` キーでは, 選択範囲内を移動します。
- `Shift` キーとマウスクリックで **表示モード** になり, 選択範囲を変更できます。
- `Escape` キーで編集を中止し, **表示モード** になります。
<br>
---
<br>
> ### セルサイズ自動変更
<br>
- 初期表示時に表示する文字の長さによって, セルの幅を広げで表示します(上限あり)。
- フォーカスのあるセルの文字が表示幅を超えている場合, セルの行数を広げて表示します。
- 選択範囲に文字が表示幅を超えているセルがある場合, 行数を広げて表示します。
- `opts.whiteSpaceNoWrap=true` を設定した場合は, 行数を広げて表示しません。
<br>
---
<br>
> ### セルサイズ変更
<br>
- 行ヘッダー, 列ヘッダーをマウスでリサイズできます(not firefox)。
- 列ヘッダーをダブルクリックすると, 文字の長さによって, セルの幅を広げます(上限あり)。
<br>
---
<br>
> ### セル選択
<br>
- `Shift` キーと上下左右キーで選択範囲を変更できます。
- `Shift` キー無し, 上下左右キーで選択範囲が解除されます。
- マウスドラッグでセルが選択されます。
- 行ヘッダー, 列ヘッダーをクリックすると行/列が選択されます。
- 行ヘッダー, 列ヘッダーをドラッグすると複数の行/列が選択されます。
<br>
---
<br>
> ### セル形式
<br>
- `defs[n].type` にセル(列)の形式を指定できます。
- セル形式は, 処理に影響をあたえません。
- セル形式は, 表示文字編集機能, 文字編集機能切替 の引数となります。
- `defs[n].align` にセルの値揃えを指定できます。
- `defs[n].readonly` を設定すると, 編集モードにならなくなります。
`公開関数` で値は変更できます。
<br>
---
<br>
> ### 表示文字編集機能
<br>
- `defs[n].viewfnc` に表示文字編集する関数を指定できます。
- [引数]
- `val: string`
- 対象セルのオリジナルの文字
- `type: string`
- `defs[n].type` に指定した文字
- `col: number`
- 対象セルの列番号
- [戻値]
- `val: string`
- 編集後の文字
``` typescript
// 例
let def: TYM_EDITOR_DEF = {
col: 3,
align: 'right',
type: 'number',
viewfnc: (val: string, type?: string, col?: number) => {
console.log(type, col, val);
return /^[+,-]?([0-9]\d*|0)$/.test(val) ? parseInt(val).toLocaleString() : val;
}
}
let defs = [def];
```
<br>
> ### 文字編集機能切替
<br>
- `defs[n].editfnc` に文字編集する関数を指定できます。
- [引数]
- `elm: HTMLElement`
- 対象セルのエレメント
- `val: string`
- 対象セルのオリジナルの文字
- `type: string`
- `defs[n].type`に指定した文字
- `col: number`
- 対象セルの列番号
- [戻値]
- `val: string | null`
- 編集後の文字, `null` の場合は反映されません
``` typescript
// TymModalService / TymTableInputComponent を利用した例
let def: TYM_EDITOR_DEF = {
col: 3,
align: 'right',
type: 'number',
editfnc: async (elm: HTMLElement, val: string, type?: string, col?: number): Promise<string | null> => {
const provider = TymTableInputComponent.provider(type || 'text', val, elm);
const componentRef = await this.modal.open(TymTableInputComponent, provider, false, () => { });
const component = componentRef.instance as TymTableInputComponent;
return (component.vals.isEscape) ? null : component.vals.ret;
}
}
let defs = [def];
```
<br>
> ### コンテキストイベント
<br>
- `menu` に イベント関数を設定します。右クリックすると実行されます。
- [引数]
- `event: MouseEvent`
- 対象セルのエレメント
- `row1, col1: number`
- 対象セルのオリジナルの文字
- `row2, col2: number`
- 対象セルのオリジナルの文字
- [戻値]
- `true :` イベント有効
- `false :` イベント無効
``` typescript
// TymMenuComponent を利用した例
import { TymMenuComponent } from "tym-modals";
:
editor_menu = (event: MouseEvent, row1: number, col1: number, row2: number, col2: number) => {
TymMenuComponent.MENU_DEFS = {
'row': {
'': '行',
'insert': '行挿入',
'remove': '行削除'
},
};
const provider = TymMenuComponent.provider(
[[['row', false], ['insert', true], ['remove', true]]],
(gid: string, id: string) => {
if (id == 'insert') this.tymTableEditor?.insertRow(row1);
if (id == 'remove') this.tymTableEditor?.removeRow(row1);
},
event.clientX, event.clientY
);
this.modal.open(TymMenuComponent, provider, false);
event.stopPropagation();
return true;
}
```
<br>
> ### カスタマイズ
<br>
- `opts` 値を設定するとカスタマイズできます。
``` typescript
opts = {
whiteSpaceNoWrap: true,
editModeAutoResize: true,
flatDesign: true,
noVerticalResize: true
}
```
- `whiteSpaceNoWrap` を設定すると, 選択およびカレントセルを折り返ししないようにします。
- `editModeAutoResize` を設定すると, 編集モードの解除時に列をリサイズします。
- `flatDesign` を設定すると, フラットデザインにします。
- `noVerticalResize` を設定すると, 垂直方向のリサイズを無しにする。
<br>

<br>
---
<br>
> ### 公開関数
<br>
- [セルの文字列を取得する関数](#セルの文字列を取得する関数) (getCells)
- [テーブルにデータを設定する関数](#テーブルにデータを設定する関数) (setData)
- [テーブルからデータを取得する関数](#テーブルからデータを取得する関数) (getData)
- [テーブルに行を挿入する](#テーブルに行を挿入する) (insertRow)
- [テーブルから行を削除する](#テーブルから行を削除する) (removeRow)
- [テーブルに列の挿入する](#テーブルに列の挿入する) (insertCol)
- [テーブルに列の削除する](#テーブルに列の削除する) (insertCol)
- [テキストをコピーする](#テキストをコピーする) (copy)
- [テキストを貼り付ける](#テキストを貼り付ける) (paste)
- [テキストを消去する](#テキストを消去する) (delete)
- [編集を元に戻す](#編集を元に戻す) (undo)
- [編集をやり直す](#編集をやり直す) (redo)
<br>
> #### セルの文字列を取得する関数
<br>
``` typescript
let data: string[][] = [], rows: string[] = [];
const fnc = (row: number, col: number, val: string, eol?: boolean) => {
console.log(`row=${row},col=${col},val=${val},eol=${eol}`);
rows.push(val);
if (eol) {
data.push([...rows]);
rows = [];
}
}
this.tymTableEditor?.getCells(rownum, colnum, fnc);
console.log(data);
```
- 指定した行数, 列数分の文字列を取得する。
- 指定した 行数 x 列数 回コールバック関数を呼び出す。
- [引数]
- `rownum: number`
- 取得する行数
- `colnum: number`
- 取得する列数
- `fnc: function`
- 取得用コールバック関数
- [戻値]
- なし
- [コールバック関数引数]
- `row: number`
- 行番号
- `col: number`
- 列番号
- `val: string`
- セル値
- `eol: boolean`
- `true :` 行中の最後のセル
- `false :` 行中の最後以外のセル
- [コールバック関数戻値]
- なし
<br>
> #### テーブルにデータを設定する関数
<br>
``` typescript
let data: any[][] = [
[ 'data 1', 'data 2', 123, ''],
[ '3', '4', 12345, 'data data data data 4'],
[ '', '', 1234567, 'data data data data 5']
];
this.tymTableEditor?.setData(data);
this.tymTableEditor?.setData(data, row1, col1);
```
- 指定したデータをテーブルに設定する。
- `row1, col1` を指定すると, 指定位置から設定する。
- [引数]
- `data: any[][]`
- 設定するデータ
- `row1: number`
- 取得する開始行番号
- `col1: number`
- 取得する開始列番号
- [戻値]
- なし
<br>
> #### テーブルからデータを取得する関数
<br>
``` typescript
let data = this.tymTableEditor?.getData(rownum, colnum);
let range = this.tymTableEditor?.getData(row1, col1, row2, col2);
```
- `rownum, colnum` を指定すると, 先頭から指定した範囲のデータを取得する。
- `row1, col1, row2, col2` を指定すると, 指定した範囲のデータを取得する。
- [引数]
- `rownum: number`
- 取得する行数
- `colnum: number`
- 取得する列数
- `row1: number`
- 取得する開始行番号
- `col1: number`
- 取得する開始列番号
- `row2: number`
- 取得する終了行番号
- `col2: number`
- 取得する終了列番号
- [戻値]
- `data: any[][]`
- 取得したデータ
<br>
> #### テーブルに行を挿入する
<br>
``` typescript
insertRow(row);
```
- 指定した行番号の行の前に行を挿入する。
- [引数]
- `row: number`
- 挿入する行番号
- [戻値]
なし
<br>
> #### テーブルから行を削除する
<br>
``` typescript
removeRow(row);
```
- 指定した行番号の行を削除する。
- [引数]
- `row: number`
- 削除する行番号
- [戻値]
なし
<br>
> #### テーブルに列の挿入する
<br>
``` typescript
insertCol(col);
let def = { col: col, align: 'right' }
insertCol(col, def);
```
- 指定した列番号の列の前に列を挿入する。
- [引数]
- `col: number`
- 挿入する列番号
- `def: TYM_EDITOR_DEF`
- 定義情報
- [戻値]
なし
<br>
> #### テーブルに列の削除する
<br>
``` typescript
removeCol(col);
```
- 指定した列番号の列を削除する。
- [引数]
- `col: number`
- 削除する列番号
- [戻値]
なし
<br>
> #### テキストをコピーする
<br>
``` typescript
copy();
```
- 選択範囲のセルをコピーする。
- [引数]
なし
- [戻値]
なし
<br>
> #### テキストを貼り付ける
<br>
``` typescript
paste();
```
- カレントセルから貼り付ける。
- [引数]
なし
- [戻値]
なし
<br>
> #### テキストを消去する
<br>
``` typescript
delete();
```
- 選択範囲のテキストを消去する。
- [引数]
なし
- [戻値]
なし
<br>
> #### 編集を元に戻す
<br>
``` typescript
undo();
```
- 編集内容をもとに戻す。
- [引数]
なし
- [戻値]
なし
<br>
> #### 編集をやり直す
<br>
``` typescript
redo();
```
- 編集内容をやり直す。
- [引数]
なし
- [戻値]
なし
<br>
---
### `comments`
```text
* supports angular 17, 18 and 19.
```
---
### ライセンス (License)
The components in tym-ng-ws are released under the MIT license. [Read license](//github.com/shinichi-tym/tym-ng-ws/blob/main/LICENSE).
---
Copyrights belong to shinichi tayama (shinichi.tym).