2

I have a problem regarding jQuery selector, where I have a Table structure as below (HTML Portion), and there is a link in table column for click and move the Table Row "UP" and "Down" by using jQuery (jQuery Portion, reference from this post).

jQuery Portion :

 $(".up,.down").click(function() {
    var row = $(this).parents("tr:first");
    if ($(this).is(".up")) {
        row.insertBefore(row.prev("tr:has(td)"));
    } else {
        row.insertAfter(row.next());
    }
});

HTML Portion :

 <table cellspacing="0" border="0" id="Table1" style="text-align:center" >
    <tr>
        <th scope="col" width="80px">Column A</th><th scope="col" width="80px">Column B</th><th scope="col">&nbsp;</th>
    </tr>
    <tr>
        <td>
                <span id="GridView1_ctl02_lbl1">A</span>
            </td><td>
                <span id="GridView1_ctl02_lbl2">0</span>
            </td><td>
                <a href="#" class="up">Up</a> <a href="#" class="down">Down</a>
            </td>
    </tr><tr>
        <td>
                <span id="GridView1_ctl03_lbl1">B</span>
            </td><td>
                <span id="GridView1_ctl03_lbl2">2</span>
            </td><td>
                <a href="#" class="up">Up</a> <a href="#" class="down">Down</a>
            </td>
    </tr><tr>
        <td>
                <span id="GridView1_ctl04_lbl1">C</span>
            </td><td>
                <span id="GridView1_ctl04_lbl2">2</span>
            </td><td>
            </td>
    </tr><tr>
        <td>
                <span id="GridView1_ctl05_lbl1">D</span>
            </td><td>
                <span id="GridView1_ctl05_lbl2">2</span>
            </td><td>
            </td>
    </tr><tr>
        <td>
                <span id="GridView1_ctl06_lbl1">E</span>
            </td><td>
                <span id="GridView1_ctl06_lbl2">3</span>
            </td><td>
                <a href="#" class="up">Up</a> <a href="#" class="down">Down</a>
            </td>
    </tr>
</table>

I wanted the Row to be move "UP" and "Down" group by values in "Column B" (as per highlighted with red box") instead of ordinary row by row. Based on example of the diagram, the moving of rows should be move by the red boxes.

enter image description here

So my question is, how can I using jQuery selector to select rows group by value in "Column B"? which the onclick event was trigger on links ("Up" & "Down") click.

Thank you in advanced :)

Community
  • 1
  • 1
sams5817
  • 1,037
  • 10
  • 34
  • 49
  • You want so that when you click `up/down` it will move that item, and any items with a corresponding value, such as all items with `2` up if you click up, and down if you click down? – Ohgodwhy Mar 23 '13 at 07:08
  • Hi Ohgodwhy, yes, the row up and down is with the group of 0, 2, and 3 – sams5817 Mar 23 '13 at 07:11
  • I believe this is feasible right? something like conditional checking of the Column B values – sams5817 Mar 23 '13 at 07:17
  • yes, sorry, give me a few moments I'll put something together. – Ohgodwhy Mar 23 '13 at 07:30
  • I don't think you can do this with just a selector, but you should be able to do it with `.filter()`. – Barmar Mar 23 '13 at 08:08

2 Answers2

3

I don't think you can do this with Just selectors and a single command! but you can use some loops :

 $(".up,.down").click(function () {
     var row = $(this).parents("tr:first");
     if ($(this).is(".up")) {

         myRow = row;
         prevRow = row.prev("tr");

         currentValue = myRow.children("td").eq(1).text();
         prevValue = prevRow.children("td").eq(1).text();
         parNode = myRow.parent();

         i = 0;
         family = [];
         parNode.children("tr").each(function(){
             if($(this).children("td").eq(1).text() == currentValue){
                 family[i] =  $(this);
                 i++;
             }
         });

         for(var j = 0; j <= i; j++ ){
             while(prevRow.children("td").eq(1).text() == prevValue){
                prevRow = prevRow.prev("tr");
             }
             family[j].insertAfter(prevRow);
         }

     } else {
         row.insertAfter(row.next());
     }
 });

Demo here: http://jsfiddle.net/shahverdy/PSDEs/2/ In this demo I implemented only Up. Click Up for values 2 and 3 to see how it works.

Mostafa Shahverdy
  • 2,687
  • 2
  • 30
  • 51
1

Given the table structure above, you can make a map storing (value in column b, corresponding tr array) pairs, if all the rows that have the same value in column B are adjacent. And when you click the Up/Down link, detach all the rows with the same value and get the rows above (for Up) or bellow (for Down). Then you know where to attach those detached rows.

$(function() {
    var column_index = 1;
    function get_value(tr) {
        return $('td', tr).eq(column_index).text().trim();
    }
    function group_by(trs, column_index) {
        var map = {};
        trs.each(function (idx) {
            var value = get_value($(this));
            if (map[value])
                map[value].push($(this));
            else
                map[value] = [$(this)];
        });
        return map;
    }
    var map = group_by($('#Table1 tr:gt(0)'), column_index);

    $('a.up').click(function () {
        var tr = $(this).closest('tr');
        var value = get_value(tr);
        var group = map[value];
        var prev = group[0].prev('tr');
        if (prev.length == 0 || $('th', prev).length != 0)
            return;
        var prev_value = get_value(prev);
        var prev_group = map[prev_value];
        for (var i = 0; i < group.length; i++) {
            group[i].detach();
            prev_group[0].before(group[i]);
        }
    });

    $('a.down').click(function () {
        var tr = $(this).closest('tr');
        var value = get_value(tr);
        var group = map[value];
        var next = group[group.length - 1].next('tr');
        if (next.length == 0)
            return;
        var next_value = get_value(next);
        var next_group = map[next_value];
        for (var i = group.length - 1; i >= 0; i--) {
            group[i].detach();
            next_group[next_group.length - 1].after(group[i]);
        }
    });
});

Refer to the code example at jsFiddle.

If you generate the table dynamically at the server end, it would be better to do the group with SQL or server end languages, and attach some class to the tr to identify the groups.

Arie Xiao
  • 13,909
  • 3
  • 31
  • 30