1

Demo

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

$('tr').on('click',function(e)
{
   var objTR=$(this); 

});

I have to select multiple rows using control key. And then store Student ID in array. How should i do using jquery Click event.

ND's
  • 2,155
  • 6
  • 38
  • 59

3 Answers3

2

If you only want the cells to light up when the control key is pressed, this code does the trick:

var studendIds = [];
$(window).on('keydown',(function()
{
    var target = $('tr'),
    root = $(window),
    clickCb = function(e)
    {
        if (!$(this).hasClass('ui-selected'))
        {
            $(this).addClass('ui-selected');
            //add id to array
            studentIds.push(+(this.cells[0].innerHTML))
        }
        else
        {
            $(this).removeClass('ui-selected');
            for(var i=0;i<studentIds.length;i++)
            {
                if (studentIds[i] === +(this.cells[0].innerHTML))
                {//remove id from array
                    delete studentIds[i];
                    break;
                }
            }
        }
    },
    upCb = function(e)
    {
        target.off('click',clickCb);
        root.on('keydown',downCb);
        root.off('keyup',upCb);
    },
    downCb = function(e)
    {
        if (e.which === 17 || e.which === 16)
        {//17 is ctrl, 16 is shift
            root.off('keydown',downCb);
            root.on('keyup',upCb);
            target.on('click',clickCb);
        }
    };
    return downCb;
}()));

Fiddle demo.

What this code does, essentially, is listen for a keydown event. If that key is the ctrl key (code 17), a click listener is attached, that will set/unset the ui-selected class if a particular row is clicked. The handler also detaches the keydown listener itself and attaches a keyup listener that sets up the event listeners back to their original states once the ctrl key is released. Meanwhile, another listener is attached, that picks up on the keyup event. If the key (ctrl) is released, the click listener is removed, and the keydown event listener is restored.

As I said in the comments, though the code above does keep track of which ids are selected, I'd personally not do that.
Whenever you need those ids (probably on form submission, or to perform an ajax request), seeing as you have those rows marked usign a class, I'd just do this:

function assumingAjaxFunction()
{
    var data = {some: 'boring', stuff: 'you might send', ids: []};
    $('.ui-selected > td:first').each(function()
    {
        data.ids.push($(this).text());
    });
    console.log(data.ids);//array of ids
}

VanillaJS fiddle with shift-select support

and the code to go with it:

window.addEventListener('load',function load()
{
    'use strict';
    var tbl = document.getElementById('tableStudent');
    window.addEventListener('keydown',(function()
    {
        var expr = /\bui\-selected\b/i,
            key, prev,
            clickCb = function(e)
            {
                e = e || window.event;
                var i, target = (function(elem)
                {//get the row element, in case user clicked on cell
                    if (elem.tagName.toLowerCase() === 'th')
                    {//head shouldn't be clickable
                        return elem;
                    }
                    while(elem !== tbl)
                    {//if elem is tbl, we can't determine which row was clicked anyway
                        if (elem.tagName.toLowerCase() === 'tr')
                        {//row found, break
                            break;
                        }
                        elem = elem.parentNode;//if td clicked, goto parent (ie tr)
                    }
                    return elem;
                }(e.target || e.srcElement));
                if (target.tagName.toLowerCase() !== 'tr')
                {//either head, table or something else was clicked
                    return e;//stop handler
                }
                if (expr.test(target.className))
                {//if row WAS selected, unselect it
                    target.className = target.className.replace(expr, '');
                }
                else
                {//target was not selected
                    target.className += ' ui-selected';//set class
                }
                if (key === 17)
                {//ctrl-key was pressed, so end handler here
                    return e;
                }
                //key === 16 here, handle shift event
                if (prev === undefined)
                {//first click, set previous and return
                    prev = target;
                    return e;
                }
                for(i=1;i<tbl.rows.length;i++)
                {//start at 1, because head is ignored
                    if (tbl.rows[i] === target)
                    {//select from bottom to top
                        break;
                    }
                    if (tbl.rows[i] === prev)
                    {//top to bottom
                        prev = target;//prev is bottom row to select
                        break;
                    }
                }
                for(i;i<tbl.rows.length;i++)
                {
                    if (!expr.test(tbl.rows[i].className))
                    {//if cel is not selected yet, select it
                        tbl.rows[i].className += 'ui-selected';
                    }
                    if (tbl.rows[i] === prev)
                    {//we've reached the previous cell, we're done
                        break;
                    }
                }
            },
            upCb = function(e)
            {
                prev = undefined;//clear prev reference, if set
                window.addEventListener('keydown',downCb,false);//restore keydown listener
                tbl.removeEventListener('click',clickCb, false);//remove click
                window.removeEventListener('keyup',upCb,false);//and keyup listeners
            },
            downCb = function(e)
            {//this is the actual event handler
                e= e || window.event;
                key = e.which || e.keyCode;//which key was pressed
                if (key === 16 || key === 17)
                {//ctrl or shift:
                    window.removeEventListener('keydown',downCb,false);//ignore other keydown events
                    tbl.addEventListener('click',clickCb,false);//listen for clicks
                    window.addEventListener('keyup', upCb, false);//register when key is released
                }
            };
        return downCb;//return handled
    }()), false);
    window.removeEventListener('load',load,false);
}, false);

This code is close to copy-paste ready, so please, at least give it a chance. Check the fiddle, it works fine for me. It passes JSlint in with fairly strict settings, too (/*jslint browser: true, white: true */), so it's safe to say this code isn't that bad. Yes it may look somewhat complicated. But a quick read-up about how event delegation works will soon turn out that delegating an event is easier than you think
This code also heavily uses closures, a powerful concept which, in essence isn't really that hard to understand either, this linked answer uses images that came from this article: JavaScript closures explained. It's a fairly easy read, but it does a great job. After you've read this, you'll see closures as essential, easy, powerful and undervalued constructs, promise

Community
  • 1
  • 1
Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • Elias Thanks for reply..But i have to select rows on control key and shift key...Store first column of selected rows in array – ND's Jul 29 '13 at 13:45
  • @Means: Well, I've added the array of id's bit already... though I'd rather not do it like that. My guess is, at some point you're either submitting a form or sending an ajax request. I'd just use `$('.ui-selected >td:first')` and get the id's that way when you actually need them – Elias Van Ootegem Jul 29 '13 at 13:50
  • Like multiple folder selection using control and shift key in Windows PC – ND's Jul 29 '13 at 13:51
  • Yes u r right i have to pass array to server side c# and delete records from table (database) having those selected id. – ND's Jul 29 '13 at 13:53
  • @Means: Oh, now I get why you defined the `ui-selecting` class... a drag-'n-drop selection thingy on shift... would you mind if I just made the distinction between shift and ctrl in such a way that, if I selected cell 1, and then 5 when pressing shift, I'd just select 2,3 & 4 along, but not actually enable drag-selecting? – Elias Van Ootegem Jul 29 '13 at 13:57
  • Correct Elias...Select row tr (including ID,Name,Class columns) and add its first column(ID) in Array... – ND's Jul 29 '13 at 14:01
  • @Means: Well, try a couple of things, too, I'm not working for you: just add a variable to the closure (`root = $(window), which,`) and in the `keydown` callback, assign it the keycode. In the click listener, you can then distinguish between a ctrl+click and a shift+click... you'll also need a closure var to track the last clicked element, and perhaps consider giving the rows id's or keer a reference to the parent table somewhere in scope. Sorry if you find this comment a tad blunt, but I'm writing your entire script it would seem, and so far, I haven't even seen as much as a +1, let alone +1$ – Elias Van Ootegem Jul 29 '13 at 14:13
  • @Means: added another fiddle, with some more code, This time, select+click is treated differently, to allow for _"mass-selecting"_ rows – Elias Van Ootegem Jul 29 '13 at 14:30
  • Elias seen your fiddle but i am facing some problem selection not like folder selection like Windows PC – ND's Jul 29 '13 at 14:35
  • @Means: I know the fiddle isn't perfect, but it should be enough to get you started. ATM, if you use shift, you have to click twice to get it to work. How to fix that is something you can figure out yourself, can't you? – Elias Van Ootegem Jul 29 '13 at 14:38
  • @Means: You did look at [this fiddle](http://jsfiddle.net/53R2k/), didn't you? works for me. Also, if you tried editting the code, add a link to that fiddle in your comment, too – Elias Van Ootegem Jul 30 '13 at 07:24
  • Elias i have make an fiddle in pure js please check what wrong over there http://jsfiddle.net/tcLju/50/ – ND's Jul 31 '13 at 07:10
  • @Means: Wow... that fiddle is all over the place. you're also looking at the event object the wrong way. I think you need to read up on event delegation, and scoping in JS. [Here's a pure JS fiddle that works](http://jsfiddle.net/nP4K3/) – Elias Van Ootegem Jul 31 '13 at 08:07
  • when i click first row with ctrl+click and 7th row with ctrl+shift click then 1 to 7 all rows selected but in your fiddle select first and last only – ND's Jul 31 '13 at 08:11
  • @Means: that's because the fiddle distinguishes between ctrl + click and shift + click, not ctrl&shift + click. That's just making things needlessly complicated. Try shift click 1 => 7, and it'll work – Elias Van Ootegem Jul 31 '13 at 08:14
  • @Means: also check last edit of my answer: there's about 4 links you really should read – Elias Van Ootegem Jul 31 '13 at 08:28
  • Great answer, so much code. Saved me a lot of time. +1 – John Mar 28 '14 at 22:03
0

First of all, define some classes which will indicate that you have selected a table row:

tr.selected, tr.selected td {
    background: #ffc; /* light-red variant */
}

Then write this jQuery event handler:

$('table#tableStudent').on('click', 'tr', function() {
    if($(this).hasClass('selected')) {
        // this accours during the second click - unselecting the row
        $(this).removeClass('selected');
    } else {
        // here you are selecting a row, adding a new class "selected" into <tr> element.
        // you can reverse the IF condition to get this one up above, and the unselecting case down.
        $(this).addClass('selected');
    }
});

In this way you have the expirence that you have selected a row. If you have a column which contains a checkbox, or something similar, you might want to do that logic inside the event listener I provided you above.

0

This might help DEMO:

function bindMultipleSelect(element){
    var self = this;
    var isCtrlDown = false;
    element.on('click', 'tr', function(){
        var tr = $(this);
        if(!isCtrlDown)
            return;
        tr.toggleClass('ui-selected')
    })
    $(document).on('keydown', function(e){
        isCtrlDown = (e.which === 17)
    });
    $(document).on('keyup', function(e){
        isCtrlDown = !(e.which === 17)
    });
    self.getSelectedRows = function(){
        var arr = [];
        element.find('.ui-selected').each(function(){
            arr.push($(this).find('td').eq(0).text())
        })
        return arr;
    }
    return self;
}

window.myElement = bindMultipleSelect($('#tableStudent'))
Akhil Sekharan
  • 12,467
  • 7
  • 40
  • 57
  • Akhil Thanks for reply..I have to select rows on control key and shift key...Store first column of selected rows in array – ND's Jul 29 '13 at 13:50
  • Like multiple folder selection using control and shift key in Windows PC – ND's Jul 29 '13 at 13:51