Mottie / tablesorter

Github fork of Christian Bach's tablesorter plugin + awesomeness ~
https://mottie.github.io/tablesorter/docs/
2.61k stars 754 forks source link

Checkboxes #676

Closed Tedd22 closed 10 years ago

Tedd22 commented 10 years ago

Hi,

I use checboxes for selecting rows. The solution found here http://jsfiddle.net/Mottie/abkNM/165/ is perfect.

But there are some issues :

See these three issues here : http://jsfiddle.net/Ted22/LR3sX/67/

Thanks in advance !

Ted

Mottie commented 10 years ago

Hi @Tedd22!

I had to make a few changes to the checkbox parser code to fix the first two problems (this code is for general use and does not include some changes or code specific to the demo you shared; that demo link is at the bottom):

/*********************************************
This code only works with jQuery 1.7+
*********************************************/
// checkbox parser
$.tablesorter.addParser( {
    id: 'checkbox',
    is: function( s ) {
        return false;
    },
    format: function( s, table, cell ) {
        var $c = $( cell ).find( 'input' );
        return $c.length ? $c.is( ':checked' ) ? 1 : 2 : s;
    },
    type: 'numeric'
});

$( function() {
    // using .on() which requires jQuery 1.7+
    $( 'table' ).on( 'tablesorter-initialized', function() {

        // class name to add on tr when checkbox is checked
        var highlightClass = 'checked',
        // resort the table after the checkbox is modified?
        resort = true,
        // if a server side database needs to be updated, do it here
        serverCallback = function( table, inputElement ) {},

        $table = $( this ),
        c = this.config,
        wo = c && c.widgetOptions,
        // include sticky header checkbox; if installed
        $sticky = c && wo.$sticky || '',
        doChecky = function( c, col ) {
            $table
                .children( 'tbody' )
                .children( 'tr:visible' )
                .children( 'td:nth-child( ' + ( parseInt( col, 10 ) + 1 ) + ' )' )
                .find( 'input' )
                .each( function() {
                    this.checked = c;
                    $( this ).trigger( 'change' );
                });
        };

        $table
            .children( 'tbody' )
            .on( 'change', 'input', function() {
                // ignore change if updating all rows
                if ( $table[0].ignoreChange ) { return; }
                var col, $this = $( this );
                $this.closest( 'tr' ).toggleClass( highlightClass, this.checked );
                $this.trigger( 'updateCell', [ $this.closest( 'td' ), resort ] );
                // if your server side database needs more parameters, add them here sent to the callback
                serverCallback( $table[0], this );
                // uncheck header if any checkboxes are unchecked
                if ( !this.checked ) {
                    $table.add( $sticky ).find( 'thead input' ).prop( 'checked', false );
                }
            })
            .end()
            .add( $sticky )
            .find( 'thead input' )
            // Click on checkbox in table header to toggle all inputs
            .on( 'change', function() {
                // prevent updateCell for every cell
                $table[0].ignoreChange = true;
                var c = this.checked,
                    col = $( this ).closest( 'th' ).attr( 'data-column' );
                doChecky( c, col );
                // update main & sticky header
                $table.add( $sticky ).find( 'th[data-column=' + col + '] input' ).prop( 'checked', c );
                $table.children( 'tbody' ).children( 'tr:visible' ).toggleClass( highlightClass, c );
                // update all at once
                $table[0].ignoreChange = false;
                $table.trigger( 'update', [ resort ] );
            })
            .on( 'mouseup', function() {
                return false;
            });

    });
});

The last problem can be fixed by setting the stickyHeaders_filteredToTop option to false

Here is an updated demo

Tedd22 commented 10 years ago

Many many thanks for your help Mottie ! I'm almost embarrassed to even ask you. Tell me if I'm exaggerating ;-)

Your demo is quite perfect. There is just one little thing... When the sort is on the first column (checkboxes) and you select a row, it go immediately to the top of table. When you don't see the top because of you've scroll down, this is quite disturbing. So, I would prefer to deactivate this 'live' sort on the first column. Is it possible ?

Once more, thanks in advance !

Ted

Mottie commented 10 years ago

The generalized code I shared above has a resort parameter which you can modify:

// class name to add on tr when checkbox is checked
var highlightClass = 'checked',
    // resort the table after the checkbox is modified?
    resort = true,
    // if a server side database needs to be updated, do it here
    serverCallback = function( table, inputElement ) {},

Additionally, if you look closely at the jsFiddle demo code which was slightly modified from the above code, you'll see this line:

$this.trigger('updateCell', [ $this.closest('td'), true ]); // true = resort

The jsFiddle was actually written before I "generalized" the code. You can see how to set these resort parameters in the documentation for both updateCell and update. I mention this specifically because the code in the jsFiddle demo for triggering the "update" event, when the header check box is modified, does not have the resort parameter set, so it defaults totrue:

// update all at once
$table[0].ignoreChange = false;
$table.trigger('update', [ false ] );

If the documentation I've provided isn't clear enough, I would appreciate some feedback on which parts are confusing or suggestions on how to improve it.... if the documentation is clear, then please take the time to review it as I am not always able to answer questions right away.

Tedd22 commented 10 years ago

Sorry Mottie ! I promise you I will be more attentive in the future :-)

Thanks

Ted

Mottie commented 10 years ago

I'm guessing this issue has been resolved, so I'm going to close it. If you continue to have problems, please feel free to continue this discussion.

Tedd22 commented 10 years ago

Hi Mottie,

I'd like to add "Select/Deselect all rows" links above the table. Il should work exactly the same way the header checkbox does.

I've prepared the ground : http://jsfiddle.net/Ted22/9Kz5H/3/

My project is improving day by day thanks to you. Your help is fantastic ! Thanks a lot.

Ted

TheSin- commented 10 years ago

again this is outside of the scope of TableSorter, but why not just use the external switches to trigger the header switches. So for select all and deselect all, just bind an on click to them that does something like

function rowselector(selected) {
  $('table.tablesorter thead tr[data-column=0] input[type=checkbox]').prop(checked, selected);
  $('table.tablesorter thead tr[data-column=0] input[type=checkbox]').trigger('change');
}
Tedd22 commented 10 years ago

Thanks @TheSin- !

I need your help to finalize the demo. After that I will not disturb you any more before long :-)

http://jsfiddle.net/Ted22/9Kz5H/5/

Many thanks in adavance !

Ted

TheSin- commented 10 years ago

I'm not going to do the other request as this is to help with Tablesorter not a free coding clinic, you need to do research on query and/or javascript on how to do these things on your own. But I did do this one for you, please look at what was done and try to learn form it so you can do your other request on your own.

http://jsfiddle.net/9Kz5H/9/