16

演示

我想使用 WindowsShiftCtrl键选择多行,例如 Windows 中的多个文件夹选择。

从选定行的表中,我必须获取第一列(学生 ID)并传递到服务器端C#并从数据库中删除这些记录。

我已经用 javascript 编写了一个代码,但类名未应用于<tr>onShiftCtrl+ left click

HTML

<table id="tableStudent" border="1">
    <thead>
        <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Class</th>
        </tr>
    </thead>
    <tbody>
        <tr onmousedown="RowClick(this,false);">
            <td>1</td>
            <td>John</td>
            <td>4th</td>
        </tr>
         <tr onmousedown="RowClick(this,false);">
            <td>2</td>
            <td>Jack</td>
            <td>5th</td>
        </tr>
         <tr onmousedown="RowClick(this,false);">
            <td>3</td>
            <td>Michel</td>
            <td>6th</td>
        </tr>
        <tr onmousedown="RowClick(this,false);">
            <td>4</td>
            <td>Mike</td>
            <td>7th</td>
        </tr>
        <tr onmousedown="RowClick(this,false);">
            <td>5</td>
            <td>Yke</td>
            <td>8th</td>
        </tr>
         <tr onmousedown="RowClick(this,false);">
            <td>6</td>
            <td>4ke</td>
            <td>9th</td>
        </tr>
        <tr onmousedown="RowClick(this,false);">
            <td>7</td>
            <td>7ke</td>
            <td>10th</td>
        </tr>
    </tbody>
</table>

JavaScript

var selectedrow;
function RowClick(currenttr, lock) {
var trs =tableStudent.tBodies[0].getElementsByTagName("tr");
var cnt;
    if(window.event.button==2)
    {
        if(currenttr.className=='selected')
        return false;
    }
alert(trs.length);
if (((window.event.shiftKey) && (window.event.ctrlKey) ) ||(window.event.shiftKey))
    {
        for(var j=0; j<trs.length; j++)
        {
            if (trs[j].className!='normallock')
            {
                trs[j].className='normal';
            }
        }
        var mark=false;

        if (typeof(selectedrow)=="undefined")
        {
            selectedrow=currenttr;
            selectedrow.className='selected'
            return false;
        }
        for(var j=0; j<trs.length; j++)
        {

            if ((trs[j].id ==selectedrow.id) || (trs[j].id ==currenttr.id) )
            {
                if (trs[j].className!='normallock')
                {
                trs[j].className='selected'
                mark = !(mark);
                }
            }
            else
            {
                if(mark==true)
                {
                    if (trs[j].className!='normallock')
                    trs[j].className='selected'
                }
            }
        }
    }
    else if(window.event.ctrlKey)
    {
        //if ctrl key is seelcted while selecting the patients
        // select the patient with currently clicked row plus
        // maintain the previous seelcted status
        cnt=0;
        for(var j=0; j<trs.length; j++)
        {
            if(trs[j].id == currenttr.id)
            {
                if(trs[j].className=='selected')
                {
                    trs[j].className='normal';
                }else
                {
                    trs[j].className='selected';
                }
            }
            if(trs[j].className=='selected')
            {
                cnt++;
            }
        }

        if(cnt==0)
        {
            selectedrow=undefined;
            return false;
        }
    }
    else
    {
        for(var j=0; j<trs.length; j++)
        {
            if(trs[j].id == currenttr.id)
            {
                trs[j].className='selected'
            }
            else
            {
                if (trs[j].className!='normallock')
                trs[j].className='normal';
            }

        }
    }
    selectedrow=currenttr;
}
4

6 回答 6

39

这可能不是您想要的所有功能,因为问题有点模糊,但他尝试添加CtrlShift+鼠标左键来选择或取消选择多个表格行 -请参见下面的演示和代码。免责声明:只有在 Chrome 中测试,代码几乎肯定可以优化

JavaScript

var lastSelectedRow;
var trs = document.getElementById('tableStudent').tBodies[0].getElementsByTagName('tr');

// disable text selection
document.onselectstart = function() {
    return false;
}

function RowClick(currenttr, lock) {
    if (window.event.ctrlKey) {
        toggleRow(currenttr);
    }

    if (window.event.button === 0) {
        if (!window.event.ctrlKey && !window.event.shiftKey) {
            clearAll();
            toggleRow(currenttr);
        }

        if (window.event.shiftKey) {
            selectRowsBetweenIndexes([lastSelectedRow.rowIndex, currenttr.rowIndex])
        }
    }
}

function toggleRow(row) {
    row.className = row.className == 'selected' ? '' : 'selected';
    lastSelectedRow = row;
}

function selectRowsBetweenIndexes(indexes) {
    indexes.sort(function(a, b) {
        return a - b;
    });

    for (var i = indexes[0]; i <= indexes[1]; i++) {
        trs[i-1].className = 'selected';
    }
}

function clearAll() {
    for (var i = 0; i < trs.length; i++) {
        trs[i].className = '';
    }
}

HTML

<table id="tableStudent" border="1">
    <thead>
        <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Class</th>
        </tr>
    </thead>
    <tbody>
        <tr onmousedown="RowClick(this,false);">
            <td>1</td>
            <td>John</td>
            <td>4th</td>
        </tr>
         <tr onmousedown="RowClick(this,false);">
            <td>2</td>
            <td>Jack</td>
            <td>5th</td>
        </tr>
         <tr onmousedown="RowClick(this,false);">
            <td>3</td>
            <td>Michel</td>
            <td>6th</td>
        </tr>
        <tr onmousedown="RowClick(this,false);">
            <td>4</td>
            <td>Mike</td>
            <td>7th</td>
        </tr>
        <tr onmousedown="RowClick(this,false);">
            <td>5</td>
            <td>Yke</td>
            <td>8th</td>
        </tr>
         <tr onmousedown="RowClick(this,false);">
            <td>6</td>
            <td>4ke</td>
            <td>9th</td>
        </tr>
        <tr onmousedown="RowClick(this,false);">
            <td>7</td>
            <td>7ke</td>
            <td>10th</td>
        </tr>
    </tbody>
</table>

CSS

.selected {
    background: lightBlue
}

我还将查看addEventListener 与 onclick并将事件处理程序绑定从HTML移到JavaScript中。这被称为Unobtrusive Javascript

您可能想阅读的资源:

于 2013-07-31T09:20:36.277 回答
8

我使它适用于所有 Windows 7 资源管理器行为和 jquery 鼠标事件。

http://jsfiddle.net/ubershmekel/nUV23/6/

注意:

  • 只需单击,即可为下一次按住 shift 键设置一个轴心
  • 使用 Ctrl-Shift 来扩展您当前的选择,而不是像单独使用 Shift 那样进行旋转。
  • 使用 Ctrl-click 添加一个枢轴,您可以使用 Ctrl-Shift 围绕新的枢轴展开该选择。

js:

var selectionPivot;
// 1 for left button, 2 for middle, and 3 for right.
var LEFT_MOUSE_BUTTON = 1;
var trs = document.getElementById('tableStudent').tBodies[0].getElementsByTagName('tr');
var idTds = $('td:first-child');
idTds.each(function(idx, val) {
    // onselectstart because IE doesn't respect the css `user-select: none;`
    val.onselectstart = function() { return false; };
    $(val).mousedown(function(event) {
        if(event.which != LEFT_MOUSE_BUTTON) {
            return;
        }
        var row = trs[idx];
        if (!event.ctrlKey && !event.shiftKey) {
            clearAll();
            toggleRow(row);
            selectionPivot = row;
            return;
        }
        if (event.ctrlKey && event.shiftKey) {
            selectRowsBetweenIndexes(selectionPivot.rowIndex, row.rowIndex);
            return;
        }
        if (event.ctrlKey) {
            toggleRow(row);
            selectionPivot = row;
        }
        if (event.shiftKey) {
            clearAll();
            selectRowsBetweenIndexes(selectionPivot.rowIndex, row.rowIndex);
        }
    });
});

function toggleRow(row) {
    row.className = row.className == 'selected' ? '' : 'selected';
}

function selectRowsBetweenIndexes(ia, ib) {
    var bot = Math.min(ia, ib);
    var top = Math.max(ia, ib);

    for (var i = bot; i <= top; i++) {
        trs[i-1].className = 'selected';
    }
}

function clearAll() {
    for (var i = 0; i < trs.length; i++) {
        trs[i].className = '';
    }
}

和CSS:

.selected {
    background: #bdf;
}

td:first-child {
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -o-user-select: none;
    user-select: none;
}

td,th {
    padding: 3px;
    border: 2px solid #aaa;
}

table {
    border-collapse: collapse;
}
于 2014-01-16T19:55:50.133 回答
8

这是我最近为一个项目编写的一个jQuery 插件。思想分享...

就像您习惯的那样工作,+ 它非常快,因为它在 Array 上运行而无需检查属性、类等,并且 add/removeClass 仅在选定元素上触发:

// Use like:
// $("table").selekt();
//
// Available options:
$("table").selekt({
  children: "tr",           // Elements to target (default: "tbody tr")
  className: "selected",    // Desired CSS class  (default: "selected")
  onSelect: function(sel) { // Useful callback
    $("span").text(sel.length + ' in ' + this.id);
  }
});
.selected { background: #0bf; }
table {border: 1px solid #555;display: inline-block; vertical-align: top;}
<p>Seleceted: <span id="info">0</span></p>

<table id="table_1">
  <tr><td>1 SELECT ME</td></tr>
  <tr><td>2 SELECT ME</td></tr>
  <tr><td>3 SELECT ME</td></tr>
  <tr><td>4 SELECT ME</td></tr>
  <tr><td>5 SELECT ME</td></tr>
  <tr><td>6 SELECT ME</td></tr>
</table>

<table id="table_2">
  <tr><td>1 SELECT ME</td></tr>
  <tr><td>2 SELECT ME</td></tr>
  <tr><td>3 SELECT ME</td></tr>
  <tr><td>4 SELECT ME</td></tr>
</table>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
;(function($) {
  // selekt jQuery plugin // http://stackoverflow.com/a/35813513/383904
  $.fn.selekt = function() {

    var settings = $.extend({
      children: "tbody tr",
      className: "selected",
      onSelect: function() {}
    }, arguments[0] || {});

    return this.each(function(_, that) {
      var $ch = $(this).find(settings.children),
        sel = [],
        last;

      $ch.on("mousedown", function(ev) {
        var isCtrl = (ev.ctrlKey || ev.metaKey),
          isShift = ev.shiftKey,
          ti = $ch.index(this),
          li = $ch.index(last),
          ai = $.inArray(this, sel);

        if (isShift || isCtrl) ev.preventDefault();

        $(sel).removeClass(settings.className);

        if (isCtrl) {
          if (ai > -1) sel.splice(ai, 1);
          else sel.push(this);
        } else if (isShift && sel.length > 0) {
          if (ti > li) ti = [li, li = ti][0];
          sel = $ch.slice(ti, li + 1);
        } else {
          sel = ai < 0 || sel.length > 1 ? [this] : [];
        }

        last = this;
        $(sel).addClass(settings.className);
        settings.onSelect.call(that, sel);
      });
    });
  };
}(jQuery));
</script>

于 2016-03-05T11:26:59.487 回答
0

以下代码是来自 Robo C Buljan 的修改,因为我想使用复选框和 shift 键进行多选

<includeScript value="/jquery-3.2.0.min.js" />
<script>
	;(function($) {
	// selekt jQuery plugin // http://stackoverflow.com/a/35813513/383904
	$.fn.selekt = function() {
	  var settings = $.extend({
	      children: "td input[type='checkbox'][name='ids']",
	      onSelect: function(){
	      }
	  }, arguments[0] || {});
	  return this.each(function(_, that){
	    var $ch = $(this).find(settings.children),
	    sel = [],
	    last;
	    $ch.on("mouseup", function(ev) {
	    	/* Note 1: Remember this code is run when a checkbox is clicked and is run before checbox's state changes because of click 
	    	i.e. to say if the checkbox was checked and we clicked it to uncheck, then this event handler (mouse up)code is called before the unchecing happens */
	      if(ev.shiftKey || ev.ctrlKey){
	        ev.preventDefault();
	        ev.stopPropagation();
	      }
	      var self = this;
	      var ti = $ch.index(this), // index of current element in the matching elements
	          li = $ch.index(last), // index of last element in the matching elements
	          ai = $.inArray(this, sel); // index of this in the sel array
	      if(ev.ctrlKey) {
	        if(ai > -1) sel.splice(ai, 1);
	        else sel.push(this);
	      }
	      else if(ev.shiftKey && sel.length > 0) {
	        if(ti > li) ti = [li, li=ti][0];
	        sel = $ch.slice(ti, li+1);
	      }
	      else {
	        sel = ai < 0 || sel.length > 1 ? [this] : [];
	      }
	      last = this;
	      /* purpose 2 
	      code to check checkboxes inside the array*/
	      $(sel).each(function(index, checkbox){
	      	/* see/search Note 1 in comments, if the checkbox is already checked/unchecked then uncheck/check all the elements straight from the last element correspondingly */
	      	if(self.checked) { 
	      		if( checkbox != self){
			        checkbox.checked = false;
	      		}
	      	} else {	
		      	if( checkbox != self){
			        checkbox.checked = true;
		      	}
	      	}
	      })
	      /*end of purpose 2*/

	      // settings.onSelect.call(that, sel); // this is defined just in case we want to call some function  after the select/deselect operation
	    });
	  });
	};
	}(jQuery));
	setTimeout(function(){
		$("table.list").selekt();  
	},500)
	
</script>

于 2017-05-08T08:00:12.353 回答
0

我知道这个问题已经得到解答并且已经很老了,但是我发现 andyb 的答案非常有帮助。也许是因为 andyb 的答案现在可能已经过时了,但我最终不得不稍微改变他的解决方案来处理我的项目,所以我想我会分享我的更新版本。这是我使用少量 jQuery 最终得到的结果。

$(document).ready(function(){
    //put all the table rows in a variable after page load to pass in to RowClick
    var trs = $('#tableStudent tr')
    //bind the click handler to all the table rows
    $('tr').on('click', function(){
        //call the RowClick function on click event
        RowClick($(this),false,trs)
    })
})

//declare variable to store the most recently clicked row
var lastSelectedRow;

// disable text selection
document.onselectstart = function() {
    return false;
}

function RowClick(currentrow, lock, rows) {
    //if control is held down, toggle the row
    if (window.event.ctrlKey) {
        toggleRow(currentrow);
    }

    //if there are no buttons held down...
    if (window.event.button === 0) {

        //if neither control or shift are held down...
        if (!window.event.ctrlKey && !window.event.shiftKey) {
            //clear selection
            clearAll(rows);
            //toggle clicked row
            toggleRow(currentrow);
        }

        //if shift is held down...
        if (window.event.shiftKey) {
            //pass the indexes of the last selected row and currently selected row along with all rows
            selectRowsBetweenIndexes([lastSelectedRow.index(), currentrow.index()], rows)
        }
    }
}

function toggleRow(row) {
    //if the row is not the header row...
    if (!row.hasClass('header-row')){
        //if the row is selected...
        if (row.hasClass('selected')){
            //deselect it
            row.removeClass('selected')
        }
        else{
            //otherwise, select it
            row.addClass('selected')
        }
        //reassign the most recently selected row
        lastSelectedRow = row;
    }
}

function selectRowsBetweenIndexes(indexes,rows) {
    //sort the indexes in ascending order
    indexes.sort(function(a, b) {
        return a - b;
    });

    //for every row starting at the first index, until the second index...
    for (var i = indexes[0]; i <= indexes[1]; i++) {
        //select the row
        $(rows[i+1]).addClass('selected');
    }
}

function clearAll(rows) {
    //for all rows...
    for (var i = 0; i < rows.length; i++) {
        //deselect each row
        $(rows[i]).removeClass("selected");
    }
}
于 2017-04-26T04:00:45.780 回答
0

检查这个例子:

JSFiddle:使用 shift 和 ctrl 突出显示列表

部分代码:

switch(e.type) {
    case "keydown" :
        console.log('k_down');
        keysPressed.push(e.keyCode);
        break;
    case "keyup" :
        console.log('k_up');
        var idx = keysPressed.indexOf(e.keyCode);
        if (idx >= 0)
            keysPressed.splice(idx, 1);
        break;
}

可以在这里找到源: 源文件 github

于 2017-03-29T17:13:18.820 回答