忍者ブログ

VB.NET-TIPS などプログラミングについて

VB.NETのTIPS(小技集)を中心に、Javascript、PHP その他のプログラミングについて少し役に立つ情報を発信します。いわゆる個人的な忘備録ですが、みなさんのお役に立てれば幸いです。

JavaScript jQuery w2ui.grid を使ったグリッド処理・セルの編集設定2(editable, selectType, onCopy, onPaste)

前回の w2ui.grid のセルの編集設定の方法では、動作的に行選択の状態でした。 今回はセルの選択をエクセルの様にできるのですが、その説明をします。

セルの選択方法を設定するプロパティである selectTypecell に指定します。
selectType のデフォルトは row なので、指定しなければ行選択になります。

前回の以下のページの HTML にこの selectType プロパティを追加します。
JavaScript jQuery w2ui.grid を使ったグリッド処理・セルの編集設定(editable)

<!DOCTYPE html>
<html>
<head>
  <title>w2ui Grid - editable</title>
  <meta charset="utf-8" />
  <link rel="stylesheet" type="text/css" media="screen" href="./dist/w2ui.min.css" />
  <script type="text/javascript" src="./libs/jquery/jquery-2.1.4.min.js"></script>
  <script type="text/javascript" src="./dist/w2ui.js"></script>
</head>
<body>
  <div id="grid" style="width: 600px; height: 240px;"></div>
  <br>
  <button class="w2ui-btn" onclick="showChanged()">変更データ表示</button>
<script>
//  性別データ
var arrSex = [ {id:1, text:"男性"}, {id:2, text:"女性"} ];
$(function () {
  // id="grid" へのグリッド設定
  $('#grid').w2grid({ 
    name: 'grid', 
    selectType: "cell",
    columns: [
      { field: 'recid' , caption: 'ID'      , size: '50px'  , attr: "align=center", frozen: true },
      { field: 'check' , caption: '対象'    , size: '60px'  , 
            editable: { type:"checkbox" }
      },
      { field: 'name'  , caption: '名前'    , size: '100px' , 
            editable: { type:"text" }
      },
      { field: 'age'   , caption: '年齢'    , size: '60px'  , 
            editable: { type:"int", min: 10, max: 99 }
      },
      { field: 'sex'   , caption: '性別'    , size: '100px' , 
            editable: { type:"select", items: arrSex  } ,
            render: function (record, index, col_index) {
                    var html = '';
                    for (var idx in arrSex) {
                        if (arrSex[idx].id == this.getCellValue(index, col_index)) {
                            html = arrSex[idx].text;
                        }
                    }
                    return html;
            }
      },
      { field: 'birth' , caption: '生年月日', size: '100px' , render: 'date:yyyy/mm/dd',
            editable: { type:"date", format: "yyyy/mm/dd" }
      },
      { field: "height", caption: "身長"    , size: "50px"  , render : "float:1", 
            editable: { type:"float", min: 1, max: 999.9 }
      },
      { field: "weight", caption: "体重"    , size: "50px"  , render : "float:1", 
            editable: { type:"float", min: 1, max: 999.9 }
      }
    ],
    records: [
      { recid:1, check:true , name:"田中太郎", age:"35", sex:"1", birth:"1985/03/01", height:"170.1", weight:"48.5" },
      { recid:2, check:true , name:"田中花子", age:"30", sex:"2", birth:"1990/03/12", height:"160.0", weight:"45.0" },
      { recid:3, check:true , name:"山田一郎", age:"20", sex:"1", birth:"2000/03/13", height:"165.1", weight:"58.5" },
      { recid:4, check:false, name:"山田二郎", age:"18", sex:"1", birth:"2002/03/24", height:"172.5", weight:"68.2" },
      { recid:5, check:true , name:"山田良子", age:"25", sex:"2", birth:"1995/03/25", height:"158.0", weight:"47.0" },
      { recid:6, check:false, name:"山本桃子", age:"40", sex:"2", birth:"1980/03/26", height:"162.2", weight:"49.5" },
      { recid:7, check:true , name:"山本次郎", age:"44", sex:"1", birth:"1976/03/27", height:"168.5", weight:"62.1" },
      { recid:8, check:true , name:"阿部博"  , age:"48", sex:"1", birth:"1972/03/28", height:"180.4", weight:"75.2" }
    ]
  });  
});

function showChanged() {
    console.log(w2ui['grid'].getChanges()); 
    w2alert('コンソールに変更データを表示しました');
}
</script>
</body>
</html>


これを実行させると以下の様な表示になります。 (セル上でクリックすると、エクセルと似た感じでセルが選択されるはずです)


この HTML ではエクセルの様にコピー&ペーストができるのですが、カラムをずらしたペーストでは問題が生じます。 「身長」と「体重」のカラムを2行分コピーし、「生年月日」の上にアクティブセルを移動してペーストした場合はおかしなことになります。

これを防ぐ方法としては、ペーストイベント時にコピー開始カラムが同じ位置かどうかをチェックします。 同じカラムで無ければ、イベント処理をキャンセルしてやります。

尚、コピーイベント時にはコピー開始カラム位置を退避しておきます。 ペーストイベント時に、このカラム位置が設定してなければコピーイベントを中断します。

■コピー&ペーストイベント処理

onCopy: function(event) { }
<引数>
・event:イベント情報が含まれたオブジェクト
・event.text:コピーされたデータがテキストで格納(セル毎は"\t"で、1行が"\n"の区切り記号)
onPaste: function(event) { }
<引数>
・event:イベント情報が含まれたオブジェクト
・event.column:ペーストするカラム位置
・event.index :ペーストする行位置
・event.text  :コピーされたデータがテキストで格納(セル毎は"\t"で、1行が"\n"の区切り記号)

※<イベントハンドラの指定>
function (event) {
    // 処理の記述
}
<デフォルトの動作をキャンセルする場合>
function (event) {
    event.preventDefault(); // イベント・キャンセル
}

■コピー&ペーストイベントを加味した処理

<!DOCTYPE html>
<html>
<head>
  <title>w2ui Grid - editable</title>
  <meta charset="utf-8" />
  <link rel="stylesheet" type="text/css" media="screen" href="./dist/w2ui.min.css" />
  <script type="text/javascript" src="./libs/jquery/jquery-2.1.4.min.js"></script>
  <script type="text/javascript" src="./dist/w2ui.js"></script>
</head>
<body>
  <div id="grid" style="width: 600px; height: 240px;"></div>
  <br>
  <button class="w2ui-btn" onclick="showChanged()">変更データ表示</button>
<script>
//  コピーカラム位置
var nCopyColumn = -1;
//  性別データ
var arrSex = [ {id:1, text:"男性"}, {id:2, text:"女性"} ];
$(function () {
  // id="grid" へのグリッド設定
  $('#grid').w2grid({ 
    name: 'grid', 
    selectType: "cell",
    columns: [
      { field: 'recid' , caption: 'ID'      , size: '50px'  , attr: "align=center", frozen: true },
      { field: 'check' , caption: '対象'    , size: '60px'  , 
            editable: { type:"checkbox" }
      },
      { field: 'name'  , caption: '名前'    , size: '100px' , 
            editable: { type:"text" }
      },
      { field: 'age'   , caption: '年齢'    , size: '60px'  , 
            editable: { type:"int", min: 10, max: 99 }
      },
      { field: 'sex'   , caption: '性別'    , size: '100px' , 
            editable: { type:"select", items: arrSex  } ,
            render: function (record, index, col_index) {
                    var html = '';
                    for (var idx in arrSex) {
                        if (arrSex[idx].id == this.getCellValue(index, col_index)) {
                            html = arrSex[idx].text;
                        }
                    }
                    return html;
            }
      },
      { field: 'birth' , caption: '生年月日', size: '100px' , render: 'date:yyyy/mm/dd',
            editable: { type:"date", format: "yyyy/mm/dd" }
      },
      { field: "height", caption: "身長"    , size: "50px"  , render : "float:1", 
            editable: { type:"float", min: 1, max: 999.9 }
      },
      { field: "weight", caption: "体重"    , size: "50px"  , render : "float:1", 
            editable: { type:"float", min: 1, max: 999.9 }
      }
    ],
    onCopy: function(event) {       // コピーイベント
        var rng = this.ranges[0];
        if (nCopyColumn == -1) {
            nCopyColumn = rng.range[0].column; //Copy Paste のカラム位置退避
        }
        //  性別カラムの補正
        var strRow = "" + event.text;
        strRow = strRow.replace(/男性/g, "1");
        strRow = strRow.replace(/女性/g, "2");
        event.text = strRow;
    },
    onPaste: function(event) {      // ペーストイベント
        if (nCopyColumn == -1) {
            alert("コピーが行われていません。");
            // ペースト処理をキャンセル
            event.preventDefault();
            return;
        }
        if (nCopyColumn != event.column) {
            alert("コピー&ペーストは同じカラム位置で行って下さい。");
            // ペースト処理をキャンセル
            event.preventDefault();
            return;
        }
        //Copy Paste のカラム位置クリア
        nCopyColumn = -1;
    },
    records: [
      { recid:1, check:true , name:"田中太郎", age:"35", sex:"1", birth:"1985/03/01", height:"170.1", weight:"48.5" },
      { recid:2, check:true , name:"田中花子", age:"30", sex:"2", birth:"1990/03/12", height:"160.0", weight:"45.0" },
      { recid:3, check:true , name:"山田一郎", age:"20", sex:"1", birth:"2000/03/13", height:"165.1", weight:"58.5" },
      { recid:4, check:false, name:"山田二郎", age:"18", sex:"1", birth:"2002/03/24", height:"172.5", weight:"68.2" },
      { recid:5, check:true , name:"山田良子", age:"25", sex:"2", birth:"1995/03/25", height:"158.0", weight:"47.0" },
      { recid:6, check:false, name:"山本桃子", age:"40", sex:"2", birth:"1980/03/26", height:"162.2", weight:"49.5" },
      { recid:7, check:true , name:"山本次郎", age:"44", sex:"1", birth:"1976/03/27", height:"168.5", weight:"62.1" },
      { recid:8, check:true , name:"阿部博"  , age:"48", sex:"1", birth:"1972/03/28", height:"180.4", weight:"75.2" }
    ]
  });  
});

function showChanged() {
    console.log(w2ui['grid'].getChanges()); 
    w2alert('コンソールに変更データを表示しました');
}
</script>
</body>
</html>


これを実行させると以下の様な表示になります。 (このままのプログラムではいろいろ不完全ですので、皆さんで手を入れてみて下さい。)



ranges プロパティについて補足説明

上のプログラムの onCopy イベントの中で this.ranges として w2grid['grid']ranges プロパティを参照していますが、 この ranges プロパティには選択範囲の情報が入っています。中身は以下の range(範囲) オブジェクトの配列データです。
<range(範囲)オブジェクトの定義>
range = {
    name  : '',      // rangeの名前
    range : [],      // ※rangeを定義する2次元配列
    style : ''       // rangeのスタイルプロパティ
}

<※rangeを定義する2次元配列のオブジェクト定義>
{
    column:n        // カラム位置(n:0 ~ )
    index :m        // 行位置(m:0 ~ )
    recid :r        // recid値
}

この range(範囲) オブジェクトの配列データの「0」番目のデータに選択領域の情報が格納されています。
以下の画像は選択されて [Ctrl] + [C] キーを押下した時の ranges プロパティの内容を表示しています。












PR

コメント

コメントを書く