fooplugins / FooTable

jQuery plugin to make HTML tables responsive
https://fooplugins.com/plugins/footable-jquery/
Other
2.13k stars 637 forks source link

Filtering using custom logic instead of query object #454

Open ghost opened 8 years ago

ghost commented 8 years ago

Reviewing the examples on

http://fooplugins.github.io/FooTable/docs/examples/advanced/filter-dropdown.html http://fooplugins.github.io/FooTable/docs/examples/advanced/custom-filter-ui.html

I see the implementation of custom filters always uses the query object. However, I need to add some special logic to the filter.

We have a table with two columns:

From | To

Both columns represent numeric expresions:

Exact value: From = 10, To = 10 More than: From = 10, To = (empty) Less than: From = (empty), To = 10 Range: From = 10, To = 500

We need to implement a numeric search filter using this three simple rules:

X = search by exact value

10 = more than 10 < 100 = less than 100 ... any other expression: don't show data

So, for example, we need to search for all the records whose elements are > 500. This means take all that's intersected by this expression, which is in two columns, but not only by the string indexOf() evaluation.

My question is how to use the filtering by calling custom functions, instead of using the query object. The function itself is not the problem, as we already have the filter logic implemted (a simple function that receives an object with data, and returns true or false, in case we have a match). We want to use this custom logic on the filtering capabilities of Footable. Is that possible?

Thanks in advance

ghost commented 8 years ago

From the documentation on http://fooplugins.github.io/FooTable/docs/jsdocs/FooTable.Filtering.html

I think is possible to add a new filter, passing query string or Footable.Query object. Is possible to just override the match function or F.Query? Something like:

var myQuery = new Footable.Query(...) myQuery.match = function(str) { my-logic...}

If that's enough to implement custom filtering, I think I can add some wildcards on the From and To columns to identify properly the values.

steveush commented 8 years ago

Hi,

I would need to look into this a bit further but ultimately yes, overriding the match function should do what you require. The thing is there might be a few other places you would need to add some custom code and until I actually get a chance to make a working demo I can't be 100% sure what will be required. Just off the top of my head the match(str) and matchRow(row) functions on http://fooplugins.github.io/FooTable/docs/jsdocs/FooTable.Filter.html may need to be changed to account for any custom query as well. Also if you take a look at the source code for the original FooTable.Query#match function there is a bit more logic to it than just a straight forward indexOf check. It also handles the additional operators such as AND, OR, etc. which may or may not need to be brought across to any customization's.

As I said previously when I get a chance I'll look into this some more as being able to use less than and greater than operators would be quite nice functionality to have. Using those you would then be able to just add a new filter by doing something like:

var filtering = FooTable.get('#table').use(FooTable.Filtering);
filtering.addFilter('id_less_than_1000', '< 1000', ['id']);
filtering.filter();

Thanks

MichaelStadtmiller commented 6 years ago

@jparaya were you able to override match and filter by using a custom operator (like > or <)? I have need for a dropdown to filter on a date range ("overdue" to return all dates in the table < today, etc.) @steveush, Am I correct in saying filtering.addFilter('id_less_than_1000', '< 1000', ['id']); doesn't currently work but is how you would plan to design it if this feature does get implemented? thanks

ghost commented 6 years ago

@MichaelStadtmiller no. finally we implemented our custom table library. Checking at the code, looks like FooTable still uses this special Query object to evaluate the data as strings, so no much options to include custom function validations.

Bad luck.

webselect commented 6 years ago

If have put this on my code (no need to replace the one from footable.js)

(function(F){
    /**
     * Checks if the row is filtered using the supplied filters.
     * @this FooTable.Row
     * @param {Array.<FooTable.Filter>} filters - The filters to apply.
     * @returns {boolean}
     */
    F.Row.prototype.filtered = function(filters){
        var result = true, self = this;
        F.arr.each(filters, function(f){
            if (result){ //check if its already flag to false;
                if (f.query._original.charAt(0) == ">"){
                    result = self.value[f.columns["0"].name] >= moment(f.query._original.substring(1));
                    return (self.value[f.columns["0"].name] >= moment(f.query._original.substring(1)));
                }else{
                    if (f.query._original.charAt(0) == "<"){
                        result = self.value[f.columns["0"].name] <= moment(f.query._original.substring(1)).add(1,'days');
                        return (self.value[f.columns["0"].name] <= moment(f.query._original.substring(1)).add(1,'days'));
                    }else {
                        if ((result = f.matchRow(self)) == false) return false;
                    }
                }
            }
        });
        return result;
    };
})(FooTable);

Work with many filters but i am prety sure it wont work with "AND" and "OR". Thats good enought for what i need. To filter juste put "<" or ">" before the date you whant to filter.