Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

filter request #292

Closed
TheSin- opened this issue May 2, 2013 · 15 comments
Closed

filter request #292

TheSin- opened this issue May 2, 2013 · 15 comments

Comments

@TheSin-
Copy link
Collaborator

TheSin- commented May 2, 2013

I'd like to request a filter-select-available.

based on this
http://stackoverflow.com/questions/16343048/tablesorter-custom-filter-to-show-only-available

I need to have some of my filter-select boxes to only provide a list of available (rows without the 'filtered' class)

I can not seem to figure out how to do this with custom filters so I'm not working in filters to try and add one. I wanted to make this request so I have some place to post it to after it's done.

@TheSin-
Copy link
Collaborator Author

TheSin- commented May 2, 2013

decided to use a second class to it will look like class="filter-select only-avail"

First change in jquery.tablesorter.widgets.js:515

                                               buildSelect(i, updating);

to

                                               if (t.hasClass('only-avail'))
                                                        buildSelect(i, updating, true);
                                                else
                                                        buildSelect(i, updating);

@TheSin-
Copy link
Collaborator Author

TheSin- commented May 2, 2013

WIP, hometime so wanted to post this so far

Second change in jquery.tablesorter.widgets.js:469


                        buildSelect = function(i, updating){
                                var o, arry = [];
                                i = parseInt(i, 10);
                                o = '<option value="">' + ($ths.filter('[data-column="' + i + '"]:last').attr('data-placeholder') || '') + '</option>';
                                for (k = 0; k < b.length; k++ ){
                                        l = c.cache[k].row.length;
                                        // loop through the rows
                                        for (j = 0; j < l; j++){
                                                // get non-normalized cell conte
nt

to

                        buildSelect = function(i, updating, onlyavail){
                                var o, arry = [];
                                i = parseInt(i, 10);
                                o = '<option value="">' + ($ths.filter('[data-column="' + i + '"]:last').attr('data-placeholder') || '') + '</option>';
                                for (k = 0; k < b.length; k++ ){
                                        l = c.cache[k].row.length;
                                        // loop through the rows
                                        for (j = 0; j < l; j++){
                                                // check if has class filtered
                                                if (onlyavail && c.cache[k].row[j][0].className.match('filtered'))
                                                      continue;

                                                // get non-normalized cell conte
nt

@Mottie
Copy link
Owner

Mottie commented May 2, 2013

I think I understand what you are getting at... maybe an easier solution would be to add a class name for "onlyavail" and do this (off the top of my head):

// loop through the rows
for (j = 0; j < l; j++){
    // if onlyavail it set, use it to match the row class name
    if (onlyavail && c.cache[k].row[j][0].className.match(onlyavail)) {
        arry.push( '' + c.cache[k].normalized[j][i] );
    } else if (wo.filter_useParsedData) {
        // get non-normalized cell content

It would help if you had some example HTML for the tbody so I can test it out ;)

@TheSin-
Copy link
Collaborator Author

TheSin- commented May 3, 2013

getting the class from the obj was all I needed, I just need to check if it doesn't has the filtered class on the row and I'll be set.

as for test data anything will work.

http://mottie.github.io/tablesorter/docs/example-widget-filter-custom.html

Col0, select Peter

Col2 should only have Seattle and Milwaukee in it instead of all results since the others are now unavail.

@Mottie
Copy link
Owner

Mottie commented May 3, 2013

I think the onlyAvail should be set as an option... so change that to wo.onlyAvail, then add it as an option:

ts.addWidget({
    id: "filter",
    priority: 50,
    options : {
        onlyAvail: '',
        filter_childRows     : false, // if true, filter includes child row content in the search
        ...

@TheSin-
Copy link
Collaborator Author

TheSin- commented May 3, 2013

I'm not sure that is going to work TBH, I just finished the above code which should work, BUT since buildSelect() is never called between filters it won't repopulate.

example.

when I select col0 to Peter, it doesn't run anything to force Col2 to rebuild it's select box. They are only populated at the start, I will require it to re update on filterEnd or something :\

though adding it as a class or option is fine but I may not want all selects in a table to use it.

in my case it's for a list of products and based on the type of products I only want the models of that type to show up in the filter select. Colors on the other hand could so them all cause they are all available as an option whether in stock or not.

@TheSin-
Copy link
Collaborator Author

TheSin- commented May 3, 2013

Second change in jquery.tablesorter.widgets.js:573

                        .bind('addRows updateCell update updateRows updateComplete appendCache filterReset search '.split(' ').join('.tsfilter '), function(e, filter){
                                if (!/(search|filterReset)/.test(e.type)){
                                        e.stopPropagation();
                                        buildDefault(true);
                                }
                                if (e.type === 'filterReset') {
                                        $t.find('.' + css).val('');
                                }
                                // send false argument to force a new search; otherwise if the filter hasn't changed, it will return
                                filter = e.type === 'search' ? filter : e.type === 'updateComplete' ? $t.data('lastSearch') : '';
                                checkFilters(filter);
                                return false;
                        })

to

                        .bind('addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '.split(' ').join('.tsfilter '), function(e, filter){
                                if (!/(search|filterReset|filterEnd)/.test(e.type)){
                                        e.stopPropagation();
                                        buildDefault(true);
                                }
                                if (e.type === 'filterReset') {
                                        $t.find('.' + css).val('');
                                }
                                // send false argument to force a new search; otherwise if the filter hasn't changed, it will return
                                filter = e.type === 'search' ? filter : e.type === 'updateComplete' ? $t.data('lastSearch') : '';
                                checkFilters(filter);
                                if (/(filterEnd)/.test(e.type))
                                        buildDefault(true);
                                return false;
                        })

Now i just need to make sure the current value is selected so it doesn't reset the filters

@TheSin-
Copy link
Collaborator Author

TheSin- commented May 3, 2013

Nice it's actually working! now if only I can figure out how to not reset the current selection and I'm set!

@TheSin-
Copy link
Collaborator Author

TheSin- commented May 3, 2013

And Done!!! WORKING!!

Forth change in jquery.tablesorter.widgets.js:497

                                // build option list
                                for (k = 0; k < arry.length; k++){
                                        // replace quotes - fixes #242 & ignore 
empty strings - see http://stackoverflow.com/q/14990971/145346
                                        o += arry[k] !== '' ? '<option value="' + arry[k].replace(/\"/g, "&quot;") + '"' + optionSel +'>' + arry[k] + '</option>' : '';
                                }

to

                               // Get curent filter value
                                var currentVal = $t.find('thead').find('select.' + css + '[data-column="' + i + '"]').val();
                                var optionSel = '';
                                // build option list
                                for (k = 0; k < arry.length; k++){
                                        // replace quotes - fixes #242 & ignore empty strings - see http://stackoverflow.com/q/14990971/145346
                                        optionSel = '';
                                        if (currentVal === arry[k].replace(/\"/g, "&quot;"))
                                                optionSel = ' selected="selected"';
                                        o += arry[k] !== '' ? '<option value="' + arry[k].replace(/\"/g, "&quot;") + '"' + optionSel +'>' + arry[k] + '</option>' : '';
                                }

@TheSin-
Copy link
Collaborator Author

TheSin- commented May 3, 2013

hope it helps it works great!

http://mottie.github.io/tablesorter/docs/example-widget-filter-custom.html

just add the class 'only-avail' to col2 and you'll see it work!

can't upload the file here but if you want it as a diff or just the full js file shoot me an email, it's very useful!

@Mottie
Copy link
Owner

Mottie commented May 3, 2013

Thanks! I'd appreciate the file and a demo ;)

My gmail user name is wowmotty :)

@TheSin-
Copy link
Collaborator Author

TheSin- commented May 3, 2013

Sent, I just copied your online very and forced the local jquery.tablesorter.widgets.js

I only added the only-avail to the city filter (col2)

if you have any questions just msg me back.

@TheSin-
Copy link
Collaborator Author

TheSin- commented May 4, 2013

get a chance to check it out? I have it out in my production env now to really test it.

@Mottie
Copy link
Owner

Mottie commented May 4, 2013

I have checked it out, thanks! I will include it in my next update.

My only thoughts are... I know you have a use for it, but I couldn't picture how to make a demo that would show it's full potential. With the modified demo you shared, it just seems like an extra step for me to filter a different name, but I'm sure it works better in your case... probably with a lot more elements in the dropdown.

@Mottie
Copy link
Owner

Mottie commented May 9, 2013

Sorry I forgot to include this in the last update (v2.10.0)... I'll be sure to include it in the next one!

@Mottie Mottie closed this as completed in fc9a64e May 27, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants