6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Vue】ドラッグで選択できるようにする方法。(結合ありのテーブルセルをドラッグで選択する)

Last updated at Posted at 2021-01-07

結合セルがあるテーブルの各セルをドラッグで選択できるようにする。

スプシと同じように、選択範囲の中に結合したセルがあれば、そのサイズに合わせて選択範囲を拡張し、常に範囲が四角になるようにする。

mov.gif

目次

  1. 考え方
    1. mouse系イベントの活用
    2. セルの列方向の位置を算出
    3. watchプロパティの活用
  2. 実際のコード
    1. mouse系イベントの活用
    2. セルの列方向の位置を算出
    3. watchプロパティの活用
  3. (参考)ドラッグ選択の処理を外部ファイルに移動


考え方

1. mouse系イベントの活用

ドラッグ選択を実現するためには、mousedown, mouseup, mousemoveイベントを使用する。

イベント 内容  ここでの用途
mousedown ポインティングデバイスのボタンが要素上で押されたときに発生 選択が開始したセルの情報を取得。開始フラグを立てる。
mousemove 要素の上を移動したときに発生 現在選択している要素の情報を取得
mouseup ポインティングデバイスのボタンが要素の上で離されたときに発生 終了フラグ

イベントは各セルに仕込むのではなく、tableタグに仕込む。(セルが大量の場合に余計なメモリ消費を防ぐため)

ちなみに、よく目にするclickイベントはmousedownとmouseupを組み合わせて作られている。このため、mousedownなどのイベントを使えなくするとclickイベントも使えなくなる。


2. セルの列方向の位置を算出

結合したセルを扱うため、セルの列番号と実際のセルの位置ズレが発生する。

このため、テーブルの状態をスキャンして、各セルの列方向の位置を求める。


3. watchプロパティの活用

ドラッグに合わせて選択範囲を自動算出するため、Vue.jsのwatchプロパティを使う。

mousemoveイベントで選択中のセルが変化した場合に、watchで検知して、選択範囲を算出する。



▼位置ズレの例
例えば、(0, 0)位置のセルのcolspanが3の場合、(0, 1)セルの実際の位置は列番号3の位置となる。

image.png


実際のコード

mouse系イベントの活用

vue.jsでイベントを仕込むのは超簡単。タグの中に以下を記述。

@イベント名 = "メソッド名"

vue.jsのtemplateタグ内
<table
      @mousedown="mouseDown"
      @mouseup="mouseUp"
      @mousemove="mouseMove"
      @click="clickCell"
>

個別に複数選択できるようにもしておくため@click="clickCell"も設置しておく。



各イベントの処理は以下。methodの中に記述

mouseDown(e){
      this.isDrag = true
      this.startCell = {
        rowIndex: e.target.parentNode.rowIndex,
        cellIndex: e.target.cellIndex,
        rowspan: e.target.rowSpan,
        colspan: e.target.colSpan
      }
    },
    mouseUp(e){
      this.isDrag = false
    },
    mouseMove(e){
      if(this.isDrag == true && e.target.tagName != "TABLE"){
        this.endCell = {
          rowIndex: e.target.parentNode.rowIndex,
          cellIndex: e.target.cellIndex,
          rowspan: e.target.rowSpan,
          colspan: e.target.colSpan
        } 
      }
    }

引数のeにはイベントが発生した情報が入っている。
e.target.cellIndexのようにして、欲しい情報を抜き出す。

isDragはドラッグ中を示すフラグ。このフラグがtrueの間のみmousemoveでデータを取得し続ける。

mousemoveの条件式のe.target.tagName != "TABLE"は、ポインターの場所によって、targetがtdタグではなくtableタグを指してしまうことがあり、その場合を除外するため。



イベント内で使う全体共通の変数を3つ追加したため、これをdataプロパティに追加する。

dataプロパティ
data(){
    return{
      
      // Drag用
      startCell:[],
      endCell:[],
      isDrag: false,
}

以上でマウスのイベントを検知して必要なデータを取得する処理が完了。


セルの列方向の位置を算出

watchプロパティの中で使用するテーブルのセルの実際の列方向位置を算出するプログラムを作成する。

テーブルのデータを渡すと、各セルがどこの列位置になっているかを返す。

外部にjsファイルを作成し、後からvueにimportする。

scantable.js
const scanTable = (rows) => 
  {
      const arr = [];
      const colIndices = []
      for(var y=0; y < rows.length; y++)
      {
          var row = rows[y]

          for(var x=0;x<row.table_cells.length;x++)
          {
              var cell = row.table_cells[x], xx = x, tx, ty;

              for(;arr[y] && arr[y][xx]; ++xx);

              for(tx = xx; tx < xx + (cell.colspan || 1); ++tx) {
                  for(ty = y; ty < y + (cell.rowspan || 1); ++ty)
                  {
                      if( !arr[ty] ) arr[ty] = []          
                      arr[ty][tx] = 1

                      if ( !colIndices[y] ) colIndices[y] = []
                      colIndices[y][x] = xx
                  }
              }

          }
      }
      return colIndices
  }

export { scanTable }

引数で配列情報を渡す(変数rowsに格納)と、処理結果をcolIndicesという変数で返す。



▼実際の処理の例

引数で渡すテーブル
      rows= [
        {
          "table_cells": [
            {
              "cell_type": "TD",
              "rowspan": 1,
              "colspan": 2,
            },
            {
              "cell_type": "TD",
              "rowspan": 1,
              "colspan": 1,
            },
            {
              "cell_type": "TD",
              "rowspan": 1,
              "colspan": 3,
            }
          ]
        },
        {
          "table_cells": [
            {
              "cell_type": "TD",
              "rowspan": 2,
              "colspan": 1,
            },
            {
              "cell_type": "TD",
              "rowspan": 1,
              "colspan": 1,
            },
            {
              "cell_type": "TD",
              "rowspan": 1,
              "colspan": 2,
            }
          ]
        },
                {
          "table_cells": [
            {
              "cell_type": "TD",
              "rowspan": 1,
              "colspan": 1,
            },
            {
              "cell_type": "TD",
              "rowspan": 1,
              "colspan": 1,
            },
            {
              "cell_type": "TD",
              "rowspan": 1,
              "colspan": 1,
            }
          ]
        },
      ]

上記は以下図の元データ
image.png

これに作成したscanTableを実行すると、以下となる。

処理結果
scanTable(rows)

//出力結果
[0, 2, 3]
[0, 1, 2]
[1, 2, 3]


watchプロパティの活用

watchプロパティを使って、マウスのドラッグがあった場合に自動で選択範囲を算出する処理を作る。

まずは基点となるセル(rowIndexとcellIndex)を求める。
ドラッグは左上から右下のみでなく、右下から左上にいくパターンも考えられる。

watchプロパティ
     // 基点となるrowIndexとcolIndex
      let startRowIndex = this.startCell.rowIndex
      if ( startRowIndex > this.endCell.rowIndex ){
        startRowIndex = this.endCell.rowIndex
      }

      let startColIndex = this.colIndicies[this.startCell.rowIndex][this.startCell.cellIndex]
      if ( startColIndex > this.colIndicies[this.endCell.rowIndex][this.endCell.cellIndex] ){
        startColIndex = this.colIndicies[this.endCell.rowIndex][this.endCell.cellIndex]
      }

      let endRowIndex = this.startCell.rowIndex + this.startCell.rowspan - 1 
      if ( endRowIndex < this.endCell.rowIndex + this.endCell.rowspan - 1  ){
        endRowIndex = this.endCell.rowIndex + this.endCell.rowspan - 1
      }

      let endColIndex = this.colIndicies[this.startCell.rowIndex][this.startCell.cellIndex] + this.startCell.colspan - 1 
      if ( endColIndex < this.colIndicies[this.endCell.rowIndex][this.endCell.cellIndex] + this.endCell.colspan - 1 ){
        endColIndex = this.colIndicies[this.endCell.rowIndex][this.endCell.cellIndex] + this.endCell.colspan - 1
      }

上記処理で、startRowIndexendRowIndexstartColIndexendColIndexの4つのデータを作成。

セルを選択する

対象となるセルを算出し、選択中の配列(currentCells)に格納する処理。

      //対象セルの抽出
      const dragSelectedCells = () => {
        for( let i = 0; i <= endRowIndex; i++ ){
          for( let j = 0; j < this.rows[i].table_cells.length; j++ ){            
            //範囲拡張チェック
            //colIndexの延長処理
            if( i <= startRowIndex && startRowIndex <= i + this.rows[i].table_cells[j].rowspan - 1
                || i <= startRowIndex && startRowIndex <= i + this.rows[i].table_cells[j].rowspan - 1 
                || startRowIndex <= i && i + this.rows[i].table_cells[j].rowspan - 1 <= endRowIndex){
                  if( this.colIndices[i][j] < startColIndex &&  startColIndex <= this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1 ){
                    startColIndex = this.colIndices[i][j]
                    dragSelectedCells()
                  }

                  if( this.colIndices[i][j] <= endColIndex &&  endColIndex < this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1 ){
                    endColIndex = this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1
                    dragSelectedCells()
                  }
            }

            //rowIndexの延長処理
            if( this.colIndices[i][j] <= startColIndex && startColIndex <= this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1
                || this.colIndices[i][j] <= endColIndex && endColIndex <= this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1 
                || startColIndex <= this.colIndices[i][j] && this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1 <= endColIndex ){
                  if( i < startRowIndex && startRowIndex <= (i + this.rows[i].table_cells[j].rowspan - 1) ){
                    startRowIndex = i
                    dragSelectedCells()
                  }

                  if( i <= endRowIndex && endRowIndex < (i + this.rows[i].table_cells[j].rowspan - 1) ){
                    endRowIndex = i + this.rows[i].table_cells[j].rowspan - 1
                    dragSelectedCells()
                  }
            }


            if( startRowIndex <= i && i <= endRowIndex
                && startColIndex <= this.colIndices[i][j] && this.colIndices[i][j] <= endColIndex ){
                  this.currentCells.push({
                    rowIndex: i,
                    cellIndex: j,
                    colIndex: this.colIndices[i][j],
                    rowspan: this.rows[i].table_cells[j].rowspan,
                    colspan: this.rows[i].table_cells[j].colspan,
                  })
            }
          }
        }
      }
      dragSelectedCells()

テーブルのセルが選択範囲に該当するかを一つづつチェックしていく。

colspanやrowspanが1以上(結合してあるセル)を含む場合は、再起的にdragSelectedCells()を実行することで、選択範囲を再計算する。

以上でドラッグ選択の記述が完了。


フルコード

vue.js
<template>
  <div>
    <p>〜TmpAddRow.vue〜</p>
    <button @click="clear">選択解除</button>
    <br>

    <table
      @mousedown="mouseDown"
      @mouseup="mouseUp"
      @mousemove="mouseMove"
      @click="clickCell"
      >
      <template v-for="(tr, rowIndex) in rows">
        <tr :key="rowIndex">
          <template v-for="(cell, cellIndex) in tr.table_cells">
            <td :key="cellIndex" 
                :class="{'is-active': isActive(rowIndex, cellIndex)}"
                :rowspan="cell.rowspan || 1"
                :colspan="cell.colspan || 1"
                >
              ( {{rowIndex}} , {{cellIndex}} )
            </td>
          </template>
        </tr>
      </template>
    </table>

    <br>
    <p>currentCells : {{currentCells}}</p>

  </div>
</template>

<script>
import { scanTable } from "./scantable"

export default {
  data(){
    return{
      currentCells:[],
      // Drag
      startCell:[],
      endCell:[],
      isDrag: false,
      rows: [
        {
          "table_cells": [
            {
              "cell_type": "TD",
              "rowspan": 1,
              "colspan": 2,
            },
            {
              "cell_type": "TD",
              "rowspan": 1,
              "colspan": 1,
            },
            {
              "cell_type": "TD",
              "rowspan": 1,
              "colspan": 3,
            }
          ]
        },
        {
          "table_cells": [
            {
              "cell_type": "TD",
              "rowspan": 2,
              "colspan": 1,
            },
            {
              "cell_type": "TD",
              "rowspan": 1,
              "colspan": 1,
            },
            {
              "cell_type": "TD",
              "rowspan": 1,
              "colspan": 2,
            }
          ]
        },
                {
          "table_cells": [
            {
              "cell_type": "TD",
              "rowspan": 1,
              "colspan": 1,
            },
            {
              "cell_type": "TD",
              "rowspan": 1,
              "colspan": 1,
            },
            {
              "cell_type": "TD",
              "rowspan": 1,
              "colspan": 1,
            }
          ]
        },
      ]
    }
  },
  methods:{
    //セルに選択状態付与
    isActive(rowIndex, cellIndex){
      return this.currentCells.findIndex((elem) =>
        elem.rowIndex == rowIndex && elem.cellIndex == cellIndex
        ) > -1
    },
    //クリックによる選択状態の変更
    clickCell(event){
      const cell = event.target
      const tr = event.target.parentNode
      if(this.isActive(tr.rowIndex, cell.cellIndex)){

        const rmIndex = this.currentCells.findIndex((elem)=>
          elem.rowIndex == tr.rowIndex && elem.cellIndex == cell.cellIndex 
        )

        this.currentCells = [
          ...this.currentCells.slice(0, rmIndex),
          ...this.currentCells.slice(rmIndex + 1)
        ]

      } else{
        this.currentCells = [
          ...this.currentCells,
          {
            rowIndex: tr.rowIndex,
            cellIndex: cell.cellIndex
          }
        ]
      }
    },
    //行内の要素(セル数)の最大値を取得する(行作成用)
    getMaxCellNum(){
      return this.rows.reduce((acc, tr) => {
        if (acc < tr.table_cells.length){
          return tr.table_cells.length
        }else{
          return acc
        }
      }, 0)
    },
    clear(){
      this.currentCells = []
    },
    //ドラッグ選択
    mouseDown(e){
      console.log("mouseDown:",e)
      this.isDrag = true
      this.startCell = {
        rowIndex: e.target.parentNode.rowIndex,
        cellIndex: e.target.cellIndex,
        rowspan: e.target.rowSpan,
        colspan: e.target.colSpan
      }
      console.log("startcell:",this.startCell)
    },
    mouseUp(e){
      console.log("mouseUp:",e)
      this.isDrag = false
    },
    mouseMove(e){
      if(this.isDrag == true && e.target.tagName != "TABLE"){
        console.log("mouseMove:",e)
        this.endCell = {
          rowIndex: e.target.parentNode.rowIndex,
          cellIndex: e.target.cellIndex,
          rowspan: e.target.rowSpan,
          colspan: e.target.colSpan
        } 
        console.log("endCell:",this.endCell)
      }
    }
  },
  //dragによる選択範囲の算出
  computed:{
    colIndices(){
      return scanTable( this.rows )
    }
  },
  watch:{
    endCell(){
      this.currentCells = [this.startCell]

      // 基点となるrowとcol
      let startRowIndex = this.startCell.rowIndex
      if ( startRowIndex > this.endCell.rowIndex ){
        startRowIndex = this.endCell.rowIndex
      }

      let startColIndex = this.colIndices[this.startCell.rowIndex][this.startCell.cellIndex]
      if ( startColIndex > this.colIndices[this.endCell.rowIndex][this.endCell.cellIndex] ){
        startColIndex = this.colIndices[this.endCell.rowIndex][this.endCell.cellIndex]
      }

      let endRowIndex = this.startCell.rowIndex + this.startCell.rowspan - 1 
      if ( endRowIndex < this.endCell.rowIndex + this.endCell.rowspan - 1  ){
        endRowIndex = this.endCell.rowIndex + this.endCell.rowspan - 1
      }

      let endColIndex = this.colIndices[this.startCell.rowIndex][this.startCell.cellIndex] + this.startCell.colspan - 1 
      if ( endColIndex < this.colIndices[this.endCell.rowIndex][this.endCell.cellIndex] + this.endCell.colspan - 1 ){
        endColIndex = this.colIndices[this.endCell.rowIndex][this.endCell.cellIndex] + this.endCell.colspan - 1
      }

      //対象セルの抽出
      const dragSelectedCells = () => {
        for( let i = 0; i <= endRowIndex; i++ ){
          for( let j = 0; j < this.rows[i].table_cells.length; j++ ){            
            //範囲拡張チェック
            //colIndexの延長処理
            if( i <= startRowIndex && startRowIndex <= i + this.rows[i].table_cells[j].rowspan - 1
                || i <= startRowIndex && startRowIndex <= i + this.rows[i].table_cells[j].rowspan - 1 
                || startRowIndex <= i && i + this.rows[i].table_cells[j].rowspan - 1 <= endRowIndex){
                  if( this.colIndices[i][j] < startColIndex &&  startColIndex <= this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1 ){
                    startColIndex = this.colIndices[i][j]
                    dragSelectedCells()
                  }

                  if( this.colIndices[i][j] <= endColIndex &&  endColIndex < this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1 ){
                    endColIndex = this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1
                    dragSelectedCells()
                  }
            }

            //rowIndexの延長処理
            if( this.colIndices[i][j] <= startColIndex && startColIndex <= this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1
                || this.colIndices[i][j] <= endColIndex && endColIndex <= this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1 
                || startColIndex <= this.colIndices[i][j] && this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1 <= endColIndex ){
                  if( i < startRowIndex && startRowIndex <= (i + this.rows[i].table_cells[j].rowspan - 1) ){
                    startRowIndex = i
                    dragSelectedCells()
                  }

                  if( i <= endRowIndex && endRowIndex < (i + this.rows[i].table_cells[j].rowspan - 1) ){
                    endRowIndex = i + this.rows[i].table_cells[j].rowspan - 1
                    dragSelectedCells()
                  }
            }


            if( startRowIndex <= i && i <= endRowIndex
                && startColIndex <= this.colIndices[i][j] && this.colIndices[i][j] <= endColIndex ){
                  this.currentCells.push({
                    rowIndex: i,
                    cellIndex: j,
                    colIndex: this.colIndices[i][j],
                    rowspan: this.rows[i].table_cells[j].rowspan,
                    colspan: this.rows[i].table_cells[j].colspan,
                  })
            }
          }
        }
      }
      dragSelectedCells()
    }
  }
}
</script>

<style lang="scss" scoped>
table{
  width: 80%;
  user-select: none;
  th,td{
    border: thin solid rgba(0, 0, 0, 0.12);
    text-align: center;
    color: gray;
  }
  th{
    background: #ccc;
  }
  th, td{
    //選択状態
    &.is-active{
      border: 1px double #0098f7;
    }
  }
}
button{ 
   background: lightcoral;
   padding: 5px 20px;
   color: white;
   border-radius: 50px;
}
</style>



▼外部のjsファイル

scantable.js
const scanTable = (rows) => 
{
  const arr = [];
  const colIndices = []
  for(var y=0; y < rows.length; y++)
  {
      var row = rows[y]

      for(var x=0;x<row.table_cells.length;x++)
      {
          var cell = row.table_cells[x], xx = x, tx, ty;

          for(;arr[y] && arr[y][xx]; ++xx);

          for(tx = xx; tx < xx + (cell.colspan || 1); ++tx) {
              for(ty = y; ty < y + (cell.rowspan || 1); ++ty)
              {
                  if( !arr[ty] ) arr[ty] = []          
                  arr[ty][tx] = 1

                  if ( !colIndices[y] ) colIndices[y] = []
                  colIndices[y][x] = xx
              }
          }

      }
  }
  return colIndices
}

export { scanTable }




(参考)ドラッグ選択の処理を外部ファイルに移動

Vueファイルのwatchプロパティに記述している下記処理が長いので、こちらも外部ファイルに移動する。

ポイントは変数をプロパティ名を指定して渡すこと。

.vue
      //対象セルの抽出
      const dragSelectedCells = () => {
        for( let i = 0; i <= endRowIndex; i++ ){
          for( let j = 0; j < this.rows[i].table_cells.length; j++ ){            
            //範囲拡張チェック
            //colIndexの延長処理
            if( i <= startRowIndex && startRowIndex <= i + this.rows[i].table_cells[j].rowspan - 1
                || i <= startRowIndex && startRowIndex <= i + this.rows[i].table_cells[j].rowspan - 1 
                || startRowIndex <= i && i + this.rows[i].table_cells[j].rowspan - 1 <= endRowIndex){
                  if( this.colIndices[i][j] < startColIndex &&  startColIndex <= this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1 ){
                    startColIndex = this.colIndices[i][j]
                    dragSelectedCells()
                  }

                  if( this.colIndices[i][j] <= endColIndex &&  endColIndex < this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1 ){
                    endColIndex = this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1
                    dragSelectedCells()
                  }
            }

            //rowIndexの延長処理
            if( this.colIndices[i][j] <= startColIndex && startColIndex <= this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1
                || this.colIndices[i][j] <= endColIndex && endColIndex <= this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1 
                || startColIndex <= this.colIndices[i][j] && this.colIndices[i][j] + this.rows[i].table_cells[j].colspan - 1 <= endColIndex ){
                  if( i < startRowIndex && startRowIndex <= (i + this.rows[i].table_cells[j].rowspan - 1) ){
                    startRowIndex = i
                    dragSelectedCells()
                  }

                  if( i <= endRowIndex && endRowIndex < (i + this.rows[i].table_cells[j].rowspan - 1) ){
                    endRowIndex = i + this.rows[i].table_cells[j].rowspan - 1
                    dragSelectedCells()
                  }
            }


            if( startRowIndex <= i && i <= endRowIndex
                && startColIndex <= this.colIndices[i][j] && this.colIndices[i][j] <= endColIndex ){
                  this.currentCells.push({
                    rowIndex: i,
                    cellIndex: j,
                    colIndex: this.colIndices[i][j],
                    rowspan: this.rows[i].table_cells[j].rowspan,
                    colspan: this.rows[i].table_cells[j].colspan,
                  })
            }
          }
        }
      }
      dragSelectedCells()

Vueファイル内の記述変更

上記記述を以下のように変更する。

.vue
    this.currentCells = dragSelectedCells({
        startRowIndex: startRowIndex,
        endRowIndex: endRowIndex,
        startColIndex: startColIndex,
        endColIndex: endColIndex,
        rows: this.rows,
        colIndices: this.colIndices,
        currentCells: this.currentCells,
    })

渡す変数が多いのでごちゃごちゃしているが、記述量はシンプルになった。

また、外部から関数を読み込むのでimportに追記。

vue
import { scanTable, dragSelectedCells } from "./scantable"


jsファイルへの追記

関数を外部のjsファイルに移動する。

.js
const dragSelectedCells = ({
  startRowIndex,
  endRowIndex,
  startColIndex,
  endColIndex,
  rows,
  colIndices,
  currentCells,
}) => {
  for( let i = 0; i <= endRowIndex; i++ ){
    for( let j = 0; j < rows[i].table_cells.length; j++ ){            
      //範囲拡張チェック
      //colIndexの延長処理
      if( i <= startRowIndex && startRowIndex <= i + rows[i].table_cells[j].rowspan - 1
          || i <= startRowIndex && startRowIndex <= i + rows[i].table_cells[j].rowspan - 1 
          || startRowIndex <= i && i + rows[i].table_cells[j].rowspan - 1 <= endRowIndex){
            if( colIndices[i][j] < startColIndex &&  startColIndex <= colIndices[i][j] + rows[i].table_cells[j].colspan - 1 ){
              startColIndex = colIndices[i][j]
              dragSelectedCells({
                startRowIndex,
                endRowIndex,
                startColIndex,
                endColIndex,
                rows,
                colIndices,
                currentCells,
              })
            }

            if( colIndices[i][j] <= endColIndex &&  endColIndex < colIndices[i][j] + rows[i].table_cells[j].colspan - 1 ){
              endColIndex = colIndices[i][j] + rows[i].table_cells[j].colspan - 1
              dragSelectedCells({
                startRowIndex,
                endRowIndex,
                startColIndex,
                endColIndex,
                rows,
                colIndices,
                currentCells,
              })
            }
      }

      //rowIndexの延長処理
      if( colIndices[i][j] <= startColIndex && startColIndex <= colIndices[i][j] + rows[i].table_cells[j].colspan - 1
          || colIndices[i][j] <= endColIndex && endColIndex <= colIndices[i][j] + rows[i].table_cells[j].colspan - 1 
          || startColIndex <= colIndices[i][j] && colIndices[i][j] + rows[i].table_cells[j].colspan - 1 <= endColIndex ){
            if( i < startRowIndex && startRowIndex <= (i + rows[i].table_cells[j].rowspan - 1) ){
              startRowIndex = i
              dragSelectedCells({
                startRowIndex,
                endRowIndex,
                startColIndex,
                endColIndex,
                rows,
                colIndices,
                currentCells,
              })
            }

            if( i <= endRowIndex && endRowIndex < (i + rows[i].table_cells[j].rowspan - 1) ){
              endRowIndex = i + rows[i].table_cells[j].rowspan - 1
              dragSelectedCells({
                startRowIndex,
                endRowIndex,
                startColIndex,
                endColIndex,
                rows,
                colIndices,
                currentCells,
              })
            }
      }


      if( startRowIndex <= i && i <= endRowIndex
          && startColIndex <= colIndices[i][j] && colIndices[i][j] <= endColIndex ){
            currentCells.push({
              rowIndex: i,
              cellIndex: j,
              colIndex: colIndices[i][j],
              rowspan: rows[i].table_cells[j].rowspan,
              colspan: rows[i].table_cells[j].colspan,
            })
      }
    }
  }
  return currentCells
}

export { scanTable, dragSelectedCells }

再起処理の度に変数を渡す必要がある。

最後に外部ファイルに渡す関数を追加。
export { scanTable, dragSelectedCells }

以上。

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?