Alert the table header name when it is clicked - javascript

How can the code be modified below, so as to return the name of the column header when the column header box is clicked by the user. Ie. if I click on the "File Number" box, a javascript alert box will alert me as to what the name of the column header (th) is "File Number" ect.
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
#mstrTable {
border: 1px solid black
}
#mstrTable td, th {
border: 1px solid black
}
#mstrTable tr.normal td {
color: black;
background-color: white;
}
#mstrTable tr.highlighted td {
color: white;
background-color: gray;
}
</style>
</head>
<body>
<table id="mstrTable">
<thead>
<tr>
<th>File Number</th>
<th>Date1</th>
<th>Date2</th>
<th>Status</th>
<th>Num.</th>
</tr>
</thead>
<tbody>
<tr>
<td>KABC</td>
<td>09/12/2002</td>
<td>09/12/2002</td>
<td>Submitted</td>
<td>0</td>
</tr>
<tr>
<td>KCBS</td>
<td>09/11/2002</td>
<td>09/11/2002</td>
<td>Approved</td>
<td>1 </td>
</tr>
<tr>
<td>WFLA</td>
<td>09/11/2002</td>
<td>09/11/2002</td>
<td>Submitted</td>
<td>2</td>
</tr>
<tr>
<td>WTSP</td>
<td>09/15/2002</td>
<td>09/15/2002</td>
<td>In-Progress</td>
<td>3</td>
</tr>
</tbody>
</table>
<script type="text/javascript">
(
function( )
{
var trows = document.getElementById("mstrTable").rows;
for ( var t = 1; t < trows.length; ++t )
{
trow = trows[t];
trow.className = "normal";
trow.onclick = highlightRow;
}
function highlightRow(e)
{
alert('Row is ' + (this.rowIndex-1))
for ( var t = 1; t < trows.length; ++t )
{
trow = trows[t];
trow.className = ( trow == this && trow.className != "highlighted") ? "highlighted" : "normal";
}
}
}
)();
</script>
</body>
</html>

What is with all the looping! There is no need for the loops, use your event object which tells you what was clicked on!
//assumes one thead and one tbody
var table = document.getElementById("mstrTable");
var thead = table.getElementsByTagName("thead")[0];
var tbody = table.getElementsByTagName("tbody")[0];
tbody.onclick = function (e) {
e = e || window.event;
var td = e.target || e.srcElement; //assumes there are no other elements inside the td
var row = td.parentNode;
row.className = row.className==="highlighted" ? "" : "highlighted";
}
thead.onclick = function (e) {
e = e || window.event;
var th = e.target || e.srcElement; //assumes there are no other elements in the th
alert(th.innerHTML);
}
The above could be one click event for the whole table, I did not want to check for the element type that was clicked on.
JSFiddle

This should do it: jsFiddle example.
(
function () {
var trows = document.getElementById("mstrTable").rows;
for (var t = 1; t < trows.length; ++t) {
trow = trows[t];
trow.className = "normal";
trow.onclick = highlightRow;
}
var theads = document.getElementsByTagName("th");
for (var t = 0; t < theads.length; t++) {
thead = theads[t];
thead.onclick = highlightHead;
}
function highlightRow(e) {
alert('Row is ' + (this.rowIndex - 1))
for (var t = 1; t < trows.length; ++t) {
trow = trows[t];
trow.className = (trow == this && trow.className != "highlighted") ? "highlighted" : "normal";
}
}
function highlightHead(e) {
alert('Head is ' + this.innerHTML.toString());
}
})();

Related

How do I highlight current cell from previous cell of a column by jQuery or Java Script on two table in same page?

I have two tables in a page. First table id is personal and second one is employment. This page is render by Ajax method. I want to highlight the cell if previous cell value is different in two tables. But I can not do this on two table. I can do this on first table only or second table only. Here is the picture below.
Here is my Code..
$("#personal tr").each(function () {
$(this).find('td').each(function (index) {
var currentCell = $(this);
var nextCell = $(this).closest('tr').next('tr').find('td').eq(index).length > 0 ? $(this).closest('tr').next('tr').find('td').eq(index) : null;
if ( currentCell.text() !== nextCell.text()) {
currentCell.css('backgroundColor', '#47d2d6');
}
});
});
$("#employment tr").each(function () {
$(this).find('td').each(function (index) {
var currentCell = $(this);
var nextCell = $(this).closest('tr').next('tr').find('td').eq(index).length > 0 ? $(this).closest('tr').next('tr').find('td').eq(index) : null;
if ( currentCell.text() !== nextCell.text()) {
currentCell.css('backgroundColor', '#47d2d6');
}
});
});
All code I wrote in success method in ajax request. I tried before with
$("table").each(function () {
$("tr").each(function () {
$(this).find('td').each(function (index) {
var currentCell = $(this);
var nextCell = $(this).closest('tr').next('tr').find('td').eq(index).length > 0 ? $(this).closest('tr').next('tr').find('td').eq(index) : null;
if ( currentCell.text() !== nextCell.text()) {
currentCell.css('backgroundColor', '#47d2d6');
}
});
});
});
but its not working. How to do this ?
You could simplify your code a bit, by just checking the td's relative to their parent tables
function diffTables(left, right) {
const $left = $(left).find('td')
const $right = $(right).find('td')
const ll = $left.length
let ii = 0
for (; ii < ll; ++ii) {
const $leftItem = $left.eq(ii)
const $rightItem = $right.eq(ii)
if ($leftItem.text() !== $rightItem.text()) {
// td's don't have the same value
$($leftItem).add($rightItem).addClass('different')
}
}
}
diffTables('#left', '#right')
html {
font-family: cursive;
}
.different {
color: red;
}
table {
width: 100%;
border-collapse: collapse;
border: 1px solid #eee;
margin-bottom: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="left" border="1">
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>not</td>
</tr>
<tr>
<td>3</td>
<td>4</td>
<td>same</td>
</tr>
</tbody>
</table>
<table id="right" border="1">
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>same</td>
</tr>
<tr>
<td>5</td>
<td>4</td>
<td>same</td>
</tr>
</tbody>
</table>
Thanks for all. I have solved it by little bit changing of my code. Here is my code..
$("tr").each(function () {
$(this).find('td').each(function (index) {
var currentCell = $(this);
var nextCell = $(this).closest('tr').next('tr').find('td').eq(index).length > 0 ? $(this).closest('tr').next('tr').find('td').eq(index) : null;
if (nextCell != null && currentCell.text() !== nextCell.text()) {
currentCell.css('backgroundColor', '#47d2d6');
}
});
});
In if condition I have added nextCell != null &&. Here is my table.

Conversion of javascript to jquery (getelementbyid, tagname, innertext, innerhtml)

I have some code written in javascript n when I am trying to convert in jQuery I am getting error.
var holder = document.getElementById('filedetails')
, rows = holder.getElementsByTagName('tr')
setSuccess = function(filename) {
if (holder != null) {
for (i = 0, j = rows.length; i < j; ++i) {
cells = rows[i].getElementsByTagName('td');
if (cells[0].innerText == filename && cells[3].innerText != "error!") {
cells[3].innerHTML = "<a href='#' class='file-delete ss-delete no-click'></a>";
}
}
}
}
I tried
var holder = $('#filedetails"),
rows = $('#filedetails tr")
I am not sure what to do with innertext and innerhtml.
<div data-behavior="delete-process" id="holder">
<table>
<thead>
<tr>
<th class="medium-5">Name</th>
<th class="medium-3">Size</th>
<th class="medium-3">Type</th>
<th class="medium-1"></th>
</tr>
</thead>
<tbody id="filedetails">
<tr data-filesize="1.4" data-filename="Sample Image.jpg">
<td><strong>Sample_Image</strong></td>
<td class="nodesize">1.4 MB</td>
<td>JPG</td>
<td class="file-loading"></td></tr>
</tbody>
</table>
<div class="margin bottom large text-center drag-desc">drag and drop files here.</div>
</div>
Here is a "jqueryized" version of your code
var holder = $('#filedetails'),
rows = holder.find('tr');
var setSuccess = function(filename) {
rows.each(function() {
var cells = $(this).find('td');
if (cells.eq(0).text() == filename && cells.eq(3).text() != "error!") {
cells.eq(3).html("<a href='#' class='file-delete ss-delete no-click'></a>");
}
});
};
setSuccess("Sample_Image");
Alternate that just uses the rows:
var rows = $('#filedetails').find('tr');
var setSuccess = function(filename,useme) {
useme.each(function() {
var cells = $(this).find('td');
if (cells.eq(0).text() == filename && cells.eq(3).text() != "error!") {
cells.eq(3).html("<a href='#' class='file-delete ss-delete no-click'>freebeer</a>");
}
});
};
setSuccess("Sample_Image", rows);
To NOT use a positional table element, use a class and filter by that within the TD cells as here: This assumes one use of a class per row.
var rows = $('#filedetails').find('tr');
var setSuccess = function(filename, useme) {
useme.each(function() {
var cells = $(this).find('td');
if (cells.filter('.file-name').text() == filename
&& cells.filter('.file-loading').text() != "error!") {
cells.filter('.file-loading')
.html("<a href='#' class='file-delete ss-delete no-click'>noclick</a>");
}
});
};
setSuccess("Sample_Image", rows);
Fiddl https://jsfiddle.net/MarkSchultheiss/0fx2jms7/2/
Check the following code snippet
$(document).ready(function(){
var holder = $("#filedetails")
, rows = holder.find('tr');
var rowsLength=rows.Length;
var setSuccess = function(filename) {
if (holder != null) {
var j=rows.length;
for (var i=0; i < j; ++i) {
var cells = $(rows[i]).find('td');
var filename=$('.filename');
var file=$('.file');
if (filename.text() == filename && file.text() != "error!")
{
var aElement=$("<a/>");
aElement.href="#";
aElement.class="file-delete ss-delete no-click";
file.html(aElement);
}
}
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-behavior="delete-process" id="holder">
<table>
<thead>
<tr>
<th class="medium-5">Name</th>
<th class="medium-3">Size</th>
<th class="medium-3">Type</th>
<th class="medium-1"></th>
</tr>
</thead>
<tbody id="filedetails">
<tr data-filesize="1.4" data-filename="Sample Image.jpg">
<td class="filename"><strong>Sample_Image</strong></td>
<td class="nodesize">1.4 MB</td>
<td>JPG</td>
<td class="file-loading file"></td></tr>
</tbody>
</table>
<div class="margin bottom large text-center drag-desc">drag and drop files here.</div>
</div>
Hope this helps

Follow-up of search values from first column in html table using JS?

This is my follow-up question of this... See here. I have a jscript(courtesy of hex494D49), searching values from first column.
All I need is, when the values is searching by the user, the table headers will also displayed and if the values is not store. There's a message will display like this "No results found". How to do that?
Here's the JSfiddle file with html
Here's the JScript:
document.getElementById('term').onkeyup = function(){
var term = this.value;
var column = 0;
var pattern = new RegExp(term, 'g');
var table = document.getElementById('dataTable');
var tr = table.getElementsByTagName('TR');
for(var i = 0; i < tr.length; i++){
var td = tr[i].getElementsByTagName('TD');
for(var j = 0; j < td.length; j++){
if(j == column && td[j].innerHTML == term){
console.log('Found it: ' + td[j].innerHTML);
tr[i].style.display = 'block';
return;
alert('Found it: ' + td[j].innerHTML);
}else{
tr[i].style.display = 'none';
}
}
}
};
This would be the table markup. As you can see, I added thead, tbody and tfoot groups
<!-- search box -->
<input type="text" name="term" id="term" autocomplete = "off" />
<!-- table results -->
<table id="dataTable">
<thead>
<tr>
<th>Example No.</th>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</thead>
<tfoot>
<tr>
<th colspan="3"></th>
</tr>
</tfoot>
<tbody>
<tbody>
<tr>
<td>345678917</td>
<td>Test 1</td>
<td>one_test1#gmail.com</td>
</tr>
<tr>
<td>3512376894</td>
<td>Test 2</td>
<td>two.test2#hotmail.com</td>
</tr>
</tbody>
</table>
Default CSS for the markup above. Next step would be merging the following with the rest of your CSS.
table thead {
display: table-row-group;
}
table tbody {
display: table-row-group;
}
table tbody tr {
display: none;
}
And finally the JavaScript snippet using getElementsByTagName() method
// JavaScript
document.getElementById('term').onkeyup = function(){
var term = this.value;
var column = 0;
var msg = 'No results found!';
var pattern = new RegExp(term, 'g');
var table = document.getElementById('dataTable');
var tr = table.getElementsByTagName('TR');
for(var i = 0; i < tr.length; i++){
var td = tr[i].getElementsByTagName('TD');
for(var j = 0; j < td.length; j++){
if(j == column && td[j].innerHTML == term){
tr[i].style.display = 'table-row';
table.tFoot.innerHTML = '';
return;
}else{
tr[i].style.display = 'none';
table.tFoot.innerHTML = msg;
}
}
}
};
Working jsFiddle | Version without tfoot jsFiddle
The same as above but using rows[] and cells[] collection
HTML
<!-- Search box -->
<input type="text" id="search" autocomplete = "off" />
<!-- Table -->
<table id="table">
<thead>
<tr>
<th>Product</th>
<th>Manufacturer</th>
<th>Price</th>
<th>InStock</th>
</tr>
</thead>
<tbody>
<tr>
<td>MacBook Air</td>
<td>Apple</td>
<td>$456</td>
<td>85</td>
</tr>
<tr>
<td>Arc GIS</td>
<td>ESRI</td>
<td>$4556</td>
<td>15</td>
</tr>
<tr>
<td>3ds MAX</td>
<td>Aurodesk</td>
<td>$6556</td>
<td>359</td>
</tr>
<tr>
<td>Windows 7</td>
<td>Micorsoft</td>
<td>$256</td>
<td>2567</td>
</tr>
</tbody>
</table>
<!-- Message -->
<div id="message"></div>
CSS
table thead {
display: table-row-group;
}
table tbody tr {
display: none;
}
JavaScript
document.getElementById('search').onkeyup = function(){
var table = document.getElementById('table'),
tr = table.rows, td,
term = this.value.toLowerCase(), column = 0, i, j,
message = document.getElementById('message');
for(i = 1; i < tr.length; i++){
td = tr[i].cells;
for(j = 0; j < td.length; j++){
if(j == column && td[j].innerHTML.toLowerCase() == term){
tr[i].style.display = 'table-row';
message.innerHTML = '';
return;
}else{
tr[i].style.display = 'none';
message.innerHTML = 'No results found!';
}
}
}
};
Working jsFiddle If you won't use thead and tbody in your table here is another version jsFiddle
I case you want to search all columns, just change this line
if(j == column && td[j].innerHTML.toLowerCase() == term){
to this one
if(td[j].innerHTML.toLowerCase() == term){
And finally, if you want to have more flexible search try the version below
document.getElementById('search').onkeyup = function(){
var table = document.getElementById('table'),
tr = table.rows, td,
term = this.value.toLowerCase().trim(), column = 0, i, j,
message = document.getElementById('message'),
pattern = new RegExp(term, 'gi');
for(i = 1; i < tr.length; i++){
td = tr[i].cells;
for(j = 0; j < td.length; j++){
if(j == column && term.length > 0 && td[j].innerHTML.match(pattern)){
tr[i].style.display = 'table-row';
message.innerHTML = '';
return;
}else{
tr[i].style.display = 'none';
message.innerHTML = 'No results found!';
}
}
}
};
Working jsFiddle

Javascript 'onclick' not working in Google Chrome

I am using datatables to dynamically create a table and populate it with data. So far so good. Then I try to use onclick() to make certain td elements clickable so they redirect me to another page.
The problem is: clicking on the td's does absolutely nothing in Chrome. It works fine in IE though.
Here's the html code.
<body id="dt_example">
<form>
<input type="hidden" name="currency_numberOfRows" id="currency_numberOfRows" value="<%=currency_numberOfRows %>"></input>
<input type="hidden" name="currency_numberOfColumns" id="currency_numberOfColumns" value="<%=currency_numberOfColumns %>"></input>
<div id="demo">
<table cellpadding="0" cellspacing="0" border="0" class="display" id="currency_example" tableType="currency_clickableTDs">
<thead><tr>
<th class="heading"></th>
<th class="heading"><%=header_data%></th>
<th>% of Total</th>
<th>Total</th>
</tr></thead>
<tbody>
<tr class="odd">
<th class="heading">*Dynamically Added Heading*</th>
<td valign=middle class="underline">***Clickable Cell***</td>
<td valign=middle>*Dynamically Added Data*</td>
<td valign=middle>*Dynamically Added Data*</td>
</tr>
</tbody>
</table>
</div>
The javascript code is
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
var counter=(document.getElementById("currency_numberOfColumns").value)*2+1;
var tempaoColumns = [];
for(i=0;i<=counter;i++){
if(i==0)
{tempaoColumns[i] = null;}
else
{ tempaoColumns[i] = { "sType": "numeric-comma" };}
}
$('table.display').dataTable({
"aoColumns": tempaoColumns,
"sDom": 'T<"clear">lfrtip',
"aaSorting": [[ 1, "desc" ]]
});
} );
</script>
and
function setTDOnclickEvents(val){
var pageFrom = val;
var colHeaders = [];
var rowHeaders = [];
var numberOfColumns = document.getElementById("currency_numberOfColumns").value;
var numberOfRows = document.getElementById("currency_numberOfRows").value;
var table=document.getElementById("currency_example");
for (var h=0; h <= numberOfColumns*2; h++) {
//find every TR in a "clickableTDs" type table
colHeaders[h]= (table.rows[0].cells[h].innerHTML);
//alert(h)
//alert(table.rows[0].cells[h].innerHTML)
}
for (var h=0; h < numberOfRows/2; h++) {
//find every TR in a "clickableTDs" type table
if(h==0)
rowHeaders[h]= (table.rows[h].cells[0].innerHTML);
else if(h==1){
rowHeaders[h]= (table.rows[numberOfRows/2].cells[0].innerHTML);}
Uncaught TypeError: Cannot read property 'cells' of undefined in the above line
else
rowHeaders[h]= (table.rows[h-1].cells[0].innerHTML);
}
var allTRs = new Array();
//go through all elements
if(document.forms[0].tab.value=="Currency"){
for (var h=0; h < document.all.length; h++) {
//find every TR in a "clickableTDs" type table
if (document.all[h].tagName == "TR" &&
document.all[h].parentElement.parentElement.tableType == "currency_clickableTDs") {
allTRs.push(document.all[h]);
}
}
}
else if(document.forms[0].tab.value=="Service"){
for (var h=0; h < document.all.length; h++) {
//find every TR in a "clickableTDs" type table
if (document.all[h].tagName == "TR" &&
document.all[h].parentElement.parentElement.tableType == "service_clickableTDs") {
allTRs.push(document.all[h]);
}
}
}
else if(document.forms[0].tab.value=="Project"){
for (var h=0; h < document.all.length; h++) {
//find every TR in a "clickableTDs" type table
if (document.all[h].tagName == "TR" &&
document.all[h].parentElement.parentElement.tableType == "project_clickableTDs") {
allTRs.push(document.all[h]);
}
}
}
else if(document.forms[0].tab.value=="Location"){
for (var h=0; h < document.all.length; h++) {
//find every TR in a "clickableTDs" type table
if (document.all[h].tagName == "TR" &&
document.all[h].parentElement.parentElement.tableType == "location_clickableTDs") {
allTRs.push(document.all[h]);
}
}
}
for (var i=1; i < allTRs.length; i++) {
for (var j=1; j < allTRs[i].cells.length; j++) {
allTRs[i].cells[j].colHeader = colHeaders[j];
allTRs[i].cells[j].rowHeader = rowHeaders[i];
allTRs[i].cells[j].onclick = function (){
if(this.innerHTML == "0.00" || this.innerHTML == "0"){
alert("No data to represent!!!");
}else{
if((pageFrom == "GrossRevenueLevel") && (this.colHeader != "% of Total")&&(this.colHeader != "TOTAL")){
goMyController(this.colHeader,this.rowHeader);
}
}}
} } }
Could someone please help me? Thanks in advance and sorry for the painfully long code.
P.S. I didn't put the entire html code as it would be too lengthy
I found a solution. I replaced the javascript code with
function setTDOnclickEvents(val){
var pageFrom = val;
var bhal=$("#tab").val();
if(bhal=="Currency"){
var $tables = $("#currency_example tr");
}
else if(bhal=="Service"){
var $tables = $("#service_example tr");
}
else if(bhal=="Project"){
var $tables = $("#project_example tr");
}
else if(bhal=="Location"){
var $tables = $("#location_example tr");
}
$tables.each(function (i, el) {
var $tds = $(this).find('td.underline');
$tds.click(function(){
var hetch = $(this).html();
var hindex = $(this).index();
var colHeada= $tds.closest('table').find('th').eq(hindex).html();
var rowHeada= $tds.closest('tr').find('th').html();
if(hetch == "0.00" || hetch == "0"){
alert("No data available for this selection.");
}else{
if((pageFrom == "GrossRevenueLevel") && (colHeada != "% of Total")&&(colHeada != "TOTAL")){
alert(colHeada);
alert(rowHeada);
}
}
});
});
}
and it's working now.

Select multiple HTML table rows with Ctrl+click and Shift+click

Demo
I want to select multiple rows using Windows Shift and Ctrl keys, like multiple folder selection in Windows.
From table of selected rows I have to get the first column (student id) and pass to server side C# and delete those records from database.
I have written a code in javascript but the classname is not being applied to <tr> on Shift or Ctrl+ 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;
}
It's probably not all of the functionality you want, since the question is a bit vague, but he's an attempt at adding Ctrl or Shift+ left mouse button to select or deselect multiple table rows - see demo and code below. Disclaimer: Only tested in Chrome and code can almost certainly be optimised.
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
}
I would also look at addEventListener vs onclick and move the event handler binding out of the HTML and into JavaScript. This is known as Unobtrusive Javascript.
Resources you might want to read:
Retrieve Table Row Index of Current Row
disable text selection while pressing 'shift'
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
I made it work with all the Windows 7 explorer behaviors and jquery mouse events.
http://jsfiddle.net/ubershmekel/nUV23/6/
Note that:
When you just click, you set a pivot for the next shift-click
Use Ctrl-Shift to expand your current selection and not pivot like Shift-alone does.
Use Ctrl-click to add a pivot, you can use Ctrl-Shift to then expand that selection around the new pivot.
The 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 = '';
}
}
And the 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;
}
Here's a jQuery plugin I wrote recently for a project. Thought sharing...
Works exactly like you're used to, +
it's extremely fast cause it operates over an Array without the need to check for attributes, classes etc, and the add/removeClass triggers only on the selected elements:
// 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>
Check this example:
JSFiddle: Highlight list with shift and ctrl
Part of the code:
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;
}
Sources could be found here:
Source files github
I know this question is already answered and it's pretty old, but I found the answer by andyb to be super helpful. Perhaps it was because andyb's answer might be outdated now, but I ended up having to change his solution a bit to work with my project, so I figured I'd share my updated version. Here is what I ended up with, using a sprinkling of 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");
}
}
Following code is modification from Robo C Buljan, since i wanted to multiselect using checkboxes and shift key
<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>

Categories

Resources