2013-07-31 19 views
11

DemoChọn nhiều hàng bảng HTML với Ctrl + click và Shift + click

Tôi muốn chọn nhiều hàng sử dụng Windows phím ShiftCtrl phím, giống như nhiều lựa chọn thư mục trong Windows.

Từ bảng các hàng đã chọn Tôi phải lấy cột đầu tiên (id sinh viên) và chuyển đến phía máy chủ C# và xóa các bản ghi đó khỏi cơ sở dữ liệu.

Tôi đã viết một mã trong javascript nhưng classname không được áp dụng cho <tr> trên phím Shift hay Ctrl +trái nhấp chuột.

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; 
} 
+0

Mã trong fiddle không phải là jQuery nhưng bạn đã gắn thẻ câu hỏi là jQuery. Vì vậy, bạn có sử dụng thư viện jQuery trong dự án của bạn? Ngoài ra, vui lòng chỉnh sửa câu hỏi chi tiết hơn về vấn đề chính xác mà bạn gặp phải. – andyb

+0

không sử dụng jquery trong dự án ... Xóa thẻ jquery – John

+0

Điều tôi muốn tôi phải chọn nhiều hàng bằng cách sử dụng phím Shift và phím điều khiển. Ví dụ như chọn nhiều thư mục trong Windows PC..Từ bảng các hàng đã chọn tôi phải nhận (coloumn đầu tiên) id sinh viên và chuyển đến phía máy chủ C# và xóa các bản ghi đó khỏi cơ sở dữ liệu. – John

Trả lời

26

Nó có lẽ không phải tất cả các chức năng mà bạn muốn, kể từ khi câu hỏi là một chút mơ hồ, nhưng ông là một nỗ lực thêm Ctrl hoặc Shift + nút chuột trái để chọn hoặc bỏ chọn nhiều hàng trong bảng - see demo và mã bên dưới. Tuyên bố từ chối trách nhiệm: Chỉ được thử nghiệm trong Chrome và mã gần như chắc chắn có thể được tối ưu hóa.

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 
} 

tôi cũng sẽ xem xét addEventListener vs onclick và di chuyển trình xử lý sự kiện ràng buộc ra khỏi HTML và vào JavaScript. Điều này được gọi là Unobtrusive Javascript.

Tài bạn có thể muốn đọc:

+0

andyb cảm ơn câu trả lời của bạn, tôi đang đối mặt với một vấn đề khi tôi nhấp vào hàng đầu tiên bằng ctrl + nhấp chuột và hàng thứ 7 với ctrl + shift nhấp rồi 1 đến 7 tất cả các hàng được chọn nhưng trong fiddle của bạn chọn đầu tiên và cuối cùng chỉ – John

+1

Tôi sao chép Windows công trinh. Để chọn một phạm vi bạn nhấp chuột trái một lần và sau đó thay đổi + nhấp vào dải ô thứ hai. Bạn không cần ctrl trong trường hợp này. Tôi nghi ngờ rằng logic của tôi sẽ cần thích ứng nếu bạn muốn người dùng sử dụng ctrl + shift + bấm để chọn một phạm vi. Nếu bạn gỡ lỗi mã, bạn sẽ thấy chính xác vấn đề là gì. _Hint: có liên quan đến biến 'lastSelectedRow'. – andyb

+0

u có thể làm cho tôi không nhận được lý do chính xác đằng sau sau khi gỡ lỗi – John

5

tôi đã làm cho nó làm việc với tất cả các Windows 7 hành vi nhà thám hiểm và các sự kiện jquery chuột.

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

Lưu ý rằng:

  • Khi bạn chỉ cần nhấp chuột, bạn thiết lập một trục cho tới shift-nhấp
  • Sử dụng tổ hợp phím Ctrl-Shift để mở rộng lựa chọn hiện tại của bạn và không xoay như phím Shift độc lập.
  • Sử dụng Ctrl-click để thêm trục xoay, bạn có thể sử dụng Ctrl-Shift để sau đó mở rộng lựa chọn đó xung quanh trục mới.

Các 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 = ''; 
    } 
} 

Và 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; 
} 
6

Dưới đây là một plugin jQuery tôi đã viết gần đây cho một dự án. Nghĩ chia sẻ ...

trình giống hệt như bạn đang sử dụng để, + nó cực nhanh vì nó hoạt động trên một mảng mà không cần phải kiểm tra các thuộc tính, các lớp học vv, và thêm/removeClass chỉ kích hoạt trên các yếu tố chọn:

// 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>

+1

Hoạt động trên Safari trên mac, nhưng bạn nên kiểm tra meta || kiểm soát để phím lệnh hoạt động. Ctrl + shift click để thêm một phạm vi vào một vùng chọn hiện có cũng sẽ tốt đẹp. –

0

Kiểm tra ví dụ này:

JSFiddle: Highlight list with shift and ctrl

Một phần của mã:

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; 
} 

Nguồn có thể được tìm thấy ở đây: Source files github

0

Tôi biết câu hỏi này đã được trả lời và nó khá cũ, nhưng tôi tìm thấy câu trả lời bằng cách andyb được siêu hữu ích. Có lẽ đó là bởi vì câu trả lời của andyb có thể đã lỗi thời, nhưng tôi đã phải thay đổi giải pháp của mình một chút để làm việc với dự án của tôi, vì vậy tôi nghĩ rằng tôi muốn chia sẻ phiên bản cập nhật của mình. Đây là những gì tôi đã kết thúc với, bằng cách sử dụng một sprinkling của 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"); 
    } 
} 
0

Sau code đang thay đổi từ Robo C Buljan, kể từ khi tôi muốn Multiselect sử dụng hộp kiểm và Shift

<includeScript value="/jquery-3.2.0.min.js" /> 
 
<script> 
 
\t ;(function($) { 
 
\t // selekt jQuery plugin // http://stackoverflow.com/a/35813513/383904 
 
\t $.fn.selekt = function() { 
 
\t var settings = $.extend({ 
 
\t  children: "td input[type='checkbox'][name='ids']", 
 
\t  onSelect: function(){ 
 
\t  } 
 
\t }, arguments[0] || {}); 
 
\t return this.each(function(_, that){ 
 
\t  var $ch = $(this).find(settings.children), 
 
\t  sel = [], 
 
\t  last; 
 
\t  $ch.on("mouseup", function(ev) { 
 
\t  \t /* Note 1: Remember this code is run when a checkbox is clicked and is run before checbox's state changes because of click 
 
\t  \t 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 */ 
 
\t  if(ev.shiftKey || ev.ctrlKey){ 
 
\t   ev.preventDefault(); 
 
\t   ev.stopPropagation(); 
 
\t  } 
 
\t  var self = this; 
 
\t  var ti = $ch.index(this), // index of current element in the matching elements 
 
\t   li = $ch.index(last), // index of last element in the matching elements 
 
\t   ai = $.inArray(this, sel); // index of this in the sel array 
 
\t  if(ev.ctrlKey) { 
 
\t   if(ai > -1) sel.splice(ai, 1); 
 
\t   else sel.push(this); 
 
\t  } 
 
\t  else if(ev.shiftKey && sel.length > 0) { 
 
\t   if(ti > li) ti = [li, li=ti][0]; 
 
\t   sel = $ch.slice(ti, li+1); 
 
\t  } 
 
\t  else { 
 
\t   sel = ai < 0 || sel.length > 1 ? [this] : []; 
 
\t  } 
 
\t  last = this; 
 
\t  /* purpose 2 
 
\t  code to check checkboxes inside the array*/ 
 
\t  $(sel).each(function(index, checkbox){ 
 
\t  \t /* 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 */ 
 
\t  \t if(self.checked) { 
 
\t  \t \t if(checkbox != self){ 
 
\t \t \t   checkbox.checked = false; 
 
\t  \t \t } 
 
\t  \t } else { \t 
 
\t \t  \t if(checkbox != self){ 
 
\t \t \t   checkbox.checked = true; 
 
\t \t  \t } 
 
\t  \t } 
 
\t  }) 
 
\t  /*end of purpose 2*/ 
 

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

Các vấn đề liên quan