Skip to content

一覧の行に操作ボタン(参照コピー・コピー・移動・削除)を付ける ​

第1版作成 最終更新 (日本時間)
確認バージョン1.5.8.1

参照コピー・コピー・移動・削除は編集画面のコマンドにしかなく、一覧からは 1 件ずつ編集画面を開く必要があります。これらを一覧の各行のボタンから使えるようにする改修の設計メモです。本体の標準機能ではありません。

前提にした現行実装(1.5.8.1) ​

一覧の行 ​

一覧の行は HtmlGrids.cs で <tr class="grid-row"> として出力され、data-id(レコード ID)、ロック中のレコードには data-locked="1" が付きます(HtmlGrids.cs)。

先頭のセルはモードで変わります(HtmlGrids.cs)。

モード先頭のセル
一覧で編集する(editRow)再読み込み(ReloadRow)と行のコピー(CopyRow、作成権限があるとき)
通常チェックボックス(grid-check)

行のセルをクリックすると、gridevents.js のハンドラが編集画面へ移動します。一覧に new-tab クラスがあれば別タブ、#EditorDialog があればダイアログで開きます(gridevents.js)。

編集画面のコマンド ​

HtmlCommands.cs の表示条件です。

ボタンcontrolId動作表示条件
コピーOpenCopyDialogCommandコピーのダイアログを開く($p.openDialog)作成権限、かつ AllowCopy(フォルダは常に)
参照コピーReferenceCopyCommandlocation.href で /items/{SiteId}/new?CopyFrom={Id} へ移動作成権限、フォルダでない、AllowReferenceCopy
移動MoveTargetsCommand移動先のダイアログ($p.moveTargets)更新権限、MoveTargets の設定あり
削除DeleteCommand$p.send で削除削除権限

参照コピーは新規作成画面への移動なので、リンクにすれば別タブで開けます。コピーはダイアログでコメント・通知・リマインダーのコピー有無を選んでから(HtmlCopies.cs)サーバーで Copy を実行し、結果を編集画面に表示します。

設計 ​

方針の比較 ​

方針内容評価
1. 列の GridDesign で HTML を組む列の表示を [ColumnName] のプレースホルダで差し替える既存機能を使う値の表示用の仕組みで、権限による出し分けやボタンの処理を持たない
2. 操作ボタン専用の列を足す(推奨)一覧の列として「操作」列を定義し、セルにボタンを出す一覧編集モードの先頭セルと同じ作りにできる

操作列の定義 ​

項目値
列名_ActionButtons(先頭の _ で特殊な列と分かるようにする)
表示名操作
一覧に表示できる
編集・ソートできない

テーブルの管理 > 一覧の「利用可能な列」に出し、有効にするだけで使えるようにします。GridSelectableOptions に追加し、列の詳細設定ダイアログでボタンごとの表示と別タブで開くかを選べるようにします。

設定既定
参照コピーを表示オン
コピーを表示オン
移動を表示オン
削除を表示オン
参照コピーを別タブで開くオフ
コピーを別タブで開くオフ

各ボタンの動作 ​

図を読み込み中…

改修箇所 ​

ファイル改修内容
Libraries/HtmlParts/HtmlGrids.cs列のループで _ActionButtons のときにボタンのセルを出す
Libraries/Settings/Column.cs操作列を表すフラグ
Libraries/Settings/SiteSettings.cs選べる列への追加、別タブ設定(例: GridActionNewTab)
Libraries/Settings/ColumnUtilities.cs一覧の列定義に操作列を含める
Models/Sites/SiteUtilities.cs一覧タブの設定 UI
App_Data/Definitions/ の列定義操作列の定義
新規 gridactions.js削除・移動・コピーのハンドラ
ボタンの描画(案)
csharp
private static HtmlBuilder GridActionButtons(
    this HtmlBuilder hb, Context context, SiteSettings ss, long dataId, bool isHistory)
{
    return hb
        .A(
            href: $"{Locations.ItemNew(context: context, id: ss.SiteId)}?CopyFrom={dataId}",
            target: ss.GridActionNewTab == true ? "_blank" : null,
            title: Displays.ReferenceCopy(context: context),
            css: "grid-action-button",
            _using: !isHistory
                && context.CanCreate(ss: ss)
                && ss.AllowReferenceCopy == true)
        .Button(
            title: Displays.Copy(context: context),
            controlCss: "grid-action-button",
            onClick: $"$p.gridAction($(this), {dataId}, 'Copy');",
            icon: "ui-icon-copy",
            _using: !isHistory
                && context.CanCreate(ss: ss)
                && ss.AllowCopy == true)
        .Button(
            title: Displays.Move(context: context),
            controlCss: "grid-action-button",
            onClick: $"$p.gridMoveTargets($(this), {dataId});",
            icon: "ui-icon-transferthick-e-w",
            _using: !isHistory
                && ss.MoveTargets?.Any() == true
                && context.CanUpdate(ss: ss))
        .Button(
            title: Displays.Delete(context: context),
            controlCss: "grid-action-button button-negative",
            onClick: $"$p.gridDelete($(this), {dataId});",
            icon: "ui-icon-trash",
            _using: !isHistory && context.CanDelete(ss: ss));
}
gridactions.js(案)
js
$p.gridDelete = function ($control, dataId) {
    if (!confirm($p.display('ConfirmDelete'))) return;
    var data = $p.getData($control);
    data.Id = dataId;
    $p.send($control, 'MainForm', 'Delete', 'delete');
};

$p.gridMoveTargets = function ($control, dataId) {
    var data = $p.getData($control);
    data.Id = dataId;
    $p.send($control, 'MainForm', 'MoveTargets', 'get');
    $p.openDialog($control, '.main-form');
};

$p.gridAction = function ($control, dataId, action) {
    var data = $p.getData($control);
    data.Id = dataId;
    $p.send($control, 'MainForm', action, 'post');
};

行クリックとの切り分け ​

ボタンのクリックで行のクリック(編集画面への移動)が起きないように、gridevents.js の .grid-row td のハンドラで、操作列のセルからのクリックを除外します。

js
$(document).on('click', '.grid-row td', function (event) {
    if ($(event.target).closest('.grid-action-buttons').length > 0) return;
    // 既存の処理
});

権限とロック ​

ボタンはサーバー側で権限を見て、権限の無いボタンは HTML に出しません。

ボタン権限追加の条件
参照コピー作成AllowReferenceCopy
コピー作成AllowCopy
移動更新MoveTargets の設定あり
削除削除レコードがロックされていない

ロック中のレコードは行の data-locked="1" を見て、移動・削除を押せなくします。送信は $p.send 経由にすれば、既存の CSRF 対策(フォームのトークン)がそのまま効きます。

ビュー単位で編集画面のコマンドを出し分ける CommandDisplayTypes(表示・非表示・無効・隠し)にも合わせるかは、最初はサイト設定での オン・オフだけにし、あとから考えます(View.cs)。

既存の機能との関係 ​

機能一覧編集モードの先頭セル操作列
コピー行のその場コピー(CopyRow)コピー(ダイアログ相当)または参照コピー
再読み込みReloadRowなし
移動なし移動先のダイアログ
削除なし確認して削除
参照コピーなし新規作成画面へ

一括削除・一括移動はチェックボックスの選択で行う既存の機能のまま残し、操作列は 1 件ずつの操作に使います。

関連ページ ​

変更履歴

第1版リンク項目の列指定と JOIN の組み立て、一覧のスクロール読み込みの解説と、一覧・カレンダー・サイトメニューまわりの改修・設計メモを追加