2017-03-03 62 views
1

我试图制定一个计划,我可以点击任何“时间”行并向下拖动以跨越该行,直到我'mouseup'的行。例如,如果我在上午7:30点击下拉到9点,表格数据元素将跨行适当的行数,以便表格数据在该列中从7:30到9:00变为一个块(即星期一)。这是“添加约会”按钮的功能。用mousedown跨越表的行并在jquery中拖动?

我的计划是当我点击时存储tr的索引值,然后从我悬停到的tr的索引中减去该值(而鼠标关闭时)。例如,如果我在第1行点击拖动到第3行然后向上拖动,那么首先点击的td应该将其rowspan属性设置为2.

目前我的函数将跨越多个行,我徘徊多远。所以显然不是从点击减去最初的索引。我不知道为什么。有小费吗?

https://jsfiddle.net/Adam_M/fypw7jka/

这里是我的日程安排和按钮HTML:

<div class="row" id="control-panel"> 
    <button onclick="addAppt()" id="add-appt" title="Add Appointment">+</button> 
    <p>= Add Appointment</p> 
    <button onclick="delAppt()" id="del-appt" title="Delete Appointment">-</button> 
    <p>= Delete Appointment</p> 
</div> 

<table> 
     <thead> 
     <tr class="days-of-the-week"> 
      <th scope="col" class="time-col"></th> 
      <th scope="col">Sunday</th> 
      <th scope="col">Monday</th> 
      <th scope="col">Tuesday</th> 
      <th scope="col">Wednesday</th> 
      <th scope="col">Thursday</th> 
      <th scope="col">Friday</th> 
      <th scope="col">Saturday</th> 
     </tr> 
     </thead> 
     <tbody> 
     <tr> 
      <th scope="row">7:30 AM</th> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
     </tr> 
     <tr> 
      <th scope="row">8:00 AM</th> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
     </tr> 
     <tr> 
      <th scope="row">8:30 AM</th> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
     </tr> 
     <tr> 
      <th scope="row">9:00 AM</th> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
      <td rowspan=""><textarea cols="20" rows="5" class="appt-text"></textarea></td> 
     </tr> 
     </tbody> 
</table> 
<script type="text/javascript" src="https://code.jquery.com/jquery-3.1.0.min.js"></script> 
<script type="text/javascript" src="scheduler.js"></script> 

JavaScript来实现相关功能:

function addAppt() { 
$('td').css('cursor', 'cell'); 
$('textarea').css('cursor', 'cell'); 
$('td').mousedown(function(){ 
    var initIndex = $(this).parent().index(); 
    $('td').hover(function(){ 
     var spanCount = $(this).parent().index(); 
     var span = spanCount - initIndex; 
     $(this).attr('rowspan', span); 
     $(this).addClass('highlight'); 
     }); 
}); 
$('td').mouseup(function(){ 
    $('td').off('mouseenter mouseleave'); 
}); 
} 
+0

你拨弄不工作 - 它缺少脚本'scheduler.js'。 –

+0

@KScandrett它在我点击它时起作用......我只是将脚本从scheduler.js复制并粘贴到jsfiddle的javascript部分。它应该在那里。 –

+0

这是我在上面描述的尝试中更新的小提琴。 https://jsfiddle.net/Adam_M/fypw7jka/5/ 行正在基于我单击的行的索引进行跨越。所以变量initIndex不会像我预期的那样被减去。当我拖动时,我还有一个意外的功能,将列添加到表格的右侧。我不知道发生了什么。 –

回答

0

这是我的预期更困难。但无论如何...

$(function() { 
 

 
    var $table = $("#myTable tbody"); 
 
    var $rows = $table.children("tr"); 
 
    var $cells = $table.find("td").not(".rowHdr"); 
 

 
    var numCells = $cells.length; 
 
    var numRows = $rows.length; 
 
    var numCols = numCells/numRows; // skip row headings 
 

 
    // track which columns have rowspans by setting to 1 
 
    var matrix = new Array(numRows).fill(new Array(numCols).fill(0)); 
 

 
    var matrix = new Array(numRows); 
 
    // init 2d matrix 
 
    for (var i = 0; i < 10; i++) { 
 
    matrix[i] = new Array(numCols); 
 
    } 
 
    //matrix[1][3] = 1; // test blocking cell 
 
    var startCol, startRow, endRow, lastValidCell; 
 

 
    var cellDown, cellOver, cellUp; 
 
    var mouseDown = false; 
 

 
    // used mouse event code from http://stackoverflow.com/a/19164149/1544886 
 
    $cells.on('mousedown touchstart', function(event) { 
 
    var cellPos; 
 

 
    cellDown = this; 
 

 
    event.preventDefault(); 
 
    mouseDown = true; 
 

 
    cellPos = findCell(cellDown); 
 

 
    if (cellPos) { 
 
     startCol = cellPos.col; 
 
     startRow = endRow = cellPos.row; 
 
     highlightCells(); 
 
    } else { 
 
     clearHighlights(); 
 
    } 
 
    }); 
 

 
    $cells.on('mousemove touchmove', function(event) { 
 
    event.preventDefault(); 
 

 
    if (mouseDown && cellOver != this) { 
 
     var cellPos; 
 

 
     cellOver = this; 
 
     cellPos = findCell(cellOver); 
 

 
     if (cellPos) { 
 
     // limit to starting column only 
 
     if (cellPos.col === startCol) { 
 
      endRow = cellPos.row; 
 
      highlightCells(); 
 
     } 
 
     } 
 
    } 
 
    }); 
 

 
    $cells.on('mouseup touchend', function(event) { 
 
    var cellPos; 
 

 
    event.preventDefault(); 
 

 
    cellUp = this; 
 
    cellPos = findCell(cellUp); 
 

 
    if (cellPos && cellUp === lastValidCell) { 
 
     createCellSpan(); 
 
    } 
 
    }); 
 

 
    $(window.document).on('mouseup touchend', function(event) { 
 
    mouseDown = false; 
 
    //cellDown = cellOver = null; 
 
    clearHighlights(); 
 
    }); 
 

 
    function findCell(cell) { 
 
    var col, row; 
 

 
    $cells.each(function(idx, el) { 
 
     if (cell === el) { 
 
     col = idx % numCols; 
 
     row = Math.floor(idx/numCols); 
 

 
     if (matrix[row][col] === 1) { // a rowspan already exists for this cell 
 
      //console.log('found', row, col); 
 
      col = null; 
 
     } 
 
     return false; 
 
     } 
 
    }); 
 

 
    return (col != null) ? { 
 
     col: col, 
 
     row: row 
 
    } : null; 
 
    } 
 

 
    function highlightCells() { 
 

 
    clearHighlights(); 
 

 
    if (endRow >= startRow) { 
 
     for (var row = startRow; row <= endRow; row++) { 
 
     if (matrix[row][startCol] !== 1) { // rowspan doesn't already exists for this cell 
 
      var $thisCell = $cells.eq(row * numCols + startCol); 
 
      $thisCell.addClass('highlight'); 
 
      lastValidCell = $thisCell[0]; 
 
     } else { 
 
      endRow = row - 1; // found a blocking cell 
 
      return false; 
 
     } 
 
     } 
 
    } else { 
 
     for (var row = startRow; row >= endRow; row--) { 
 
     if (matrix[row][startCol] !== 1) { // rowspan doesn't already exists for this cell 
 
      var $thisCell = $cells.eq(row * numCols + startCol); 
 
      $thisCell.addClass('highlight'); 
 
      lastValidCell = $thisCell[0]; 
 
     } else { 
 
      endRow = row + 1; // found a blocking cell 
 
      return false; 
 
     } 
 
     } 
 
    } 
 
    } 
 

 
    function clearHighlights() { 
 
    $cells.removeClass('highlight'); 
 
    } 
 

 
    function createCellSpan() { 
 
    var sRow = Math.min(startRow, endRow); 
 
    var eRow = Math.max(startRow, endRow); 
 
    var rowSpan = eRow - sRow + 1; 
 
    
 
    
 
    for (var row = eRow; row >= sRow; row--) { 
 
     var $thisCell = $cells.eq(row * numCols + startCol); 
 
     if (row === sRow) 
 
     $thisCell.attr('rowspan', rowSpan).addClass('spanned'); 
 
     else 
 
     $thisCell.remove(); 
 
     matrix[row][startCol] = 1; // mark these cells as blocked 
 
    } 
 

 
    /*for (var row = sRow; row <= eRow; row++) { 
 
     var $thisCell = $cells.eq(row * numCols + startCol); 
 
     $thisCell.addClass('spanned'); 
 
     matrix[row][startCol] = 1; // mark these cells as blocked 
 
    } */ 
 
    } 
 

 
});
.highlight { 
 
    background-color: yellow; 
 
} 
 

 
.spanned { 
 
    background-color: green; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<table id="myTable" border="1" cellpadding="10"> 
 
    <thead> 
 
    <tr> 
 
     <th></th> 
 
     <th>A</th> 
 
     <th>B</th> 
 
     <th>C</th> 
 
     <th>D</th> 
 
     <th>E</th> 
 
    </tr> 
 
    </thead> 
 
    <tbody> 
 
    <tr> 
 
     <td class="rowHdr">1</td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
    </tr> 
 
    <tr> 
 
     <td class="rowHdr">2</td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
    </tr> 
 
    <tr> 
 
     <td class="rowHdr">3</td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
    </tr> 
 
    <tr> 
 
     <td class="rowHdr">4</td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
    </tr> 
 
    <tr> 
 
     <td class="rowHdr">5</td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
    </tr> 
 
    <tr> 
 
     <td class="rowHdr">6</td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
     <td></td> 
 
    </tr> 
 
    </tbody>

+0

这太棒了!谢谢!我一直在为此奋斗了几天 –

+0

我花了一段时间(约3小时)。正确的挑战有很多。但是一旦我开始了,我想我不妨完成它。 –

+0

我不会说谎。这段代码比我能理解的更先进。但如果我花时间仔细阅读,我肯定我可以学到很多东西。感谢您的诚实努力。一旦我可以将你的所作所为包裹起来,我很可能会使用它。 –

0

daver182的代码也可以在这里http://jsfiddle.net/daver182/cB4UQ/1/看到

$(function() { 
 
    var isMouseDown = false, 
 
    isHighlighted; 
 
var currentCol; 
 
    $("#our_table td") 
 
    .mousedown(function() { 
 
     isMouseDown = true; 
 
     currentCol = this.getAttribute("data-col"); 
 
     $(this).toggleClass("highlighted"); 
 
     isHighlighted = $(this).hasClass("highlighted"); 
 
     return false; // prevent text selection 
 
    }) 
 
    .mouseover(function() { 
 
     if (isMouseDown) { 
 
      if(currentCol === this.getAttribute("data-col")){ 
 
       $(this).toggleClass("highlighted", isHighlighted); 
 
      } 
 
     } 
 
    }) 
 
    .bind("selectstart", function() { 
 
     return false; 
 
    }) 
 

 
    $(document) 
 
    .mouseup(function() { 
 
     isMouseDown = false; 
 
    }); 
 
});
table td { 
 
    width:100px; 
 
    height:100px; 
 
    text-align:center; 
 
    vertical-align:middle; 
 
    background-color:#ccc; 
 
    border:1px solid #fff; 
 
} 
 

 
table td.highlighted { 
 
    background-color:#999; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
 
<table cellpadding="0" cellspacing="0" id="our_table"> 
 
    <tr> 
 
    <td data-row="1" data-col="1">a</td> 
 
    <td data-row="1" data-col="2">b</td> 
 
    <td data-row="1" data-col="3">c</td> 
 
    </tr> 
 
    <tr> 
 
    <td data-row="2" data-col="1">d</td> 
 
    <td data-row="2" data-col="2">e</td> 
 
    <td data-row="2" data-col="3">f</td> 
 
    </tr> 
 
    <tr> 
 
    <td data-row="3" data-col="1">g</td> 
 
    <td data-row="3" data-col="2">h</td> 
 
    <td data-row="3" data-col="3">i</td> 
 
    </tr> 
 
</table>

+0

感谢您的回复。在尝试跨越行之前,我可以使用我的代码执行此操作。我现在可能会使用类似的方法。但是这并不能回答我如何通过拖动来跨越行的问题。我想要点击的td的实际rowspan =“”属性根据我拖动的距离来改变它的值。 –