Skip to content

adds object/function filter to local plugin#747

Closed
benoj wants to merge 0 commit into
GriddleGriddle:masterfrom
benoj:master
Closed

adds object/function filter to local plugin#747
benoj wants to merge 0 commit into
GriddleGriddle:masterfrom
benoj:master

Conversation

@benoj

@benoj benoj commented Oct 5, 2017

Copy link
Copy Markdown

Griddle major version

1.9.0

Changes proposed in this pull request

Extends the functionality of the LocalPlugin in order to allow more customised filtering (closes #746). With this PR you can now call setFilter() with an object { [key1]: [filter], [key2]:[filter] } or function(row){ } or an object with functions {[key]: function() {} }this allows for filtering across multiple fields with different fields.

This allows for more customised behaviour. The object filter allows individual parts of the row to be filtered which can be used to build more complex filter UI. The default behaviour is AND across the object filter however you can also set the filter to be a function which is called with the entire row. This allows the user to do more logic in the filter e.g. XOR, OR etc.. on different row properties.

This is backwards compatible so any existing custom filters will work.
e.g.

Data:
{ id: 1, name: "Bob", age: 20} , { id: 2, name: "Alice", age: 49} , { id: 3, name: "Jimmy", age: 47}, { id: 4, name: "Bob", age: 21}

setFilter("Bob") // returns { id: 1, name: "Bob", age: 20}, { id: 4, name: "Bob", age: 21}

setFilter({ name: "bob") // returns { id: 1, name: "Bob", age: 20}, { id: 4, name: "Bob", age: 21}

setFilter({ name: "bob", age: function(age) { return age < 21; } ) // returns { id: 1, name: "Bob", age: 20}

setFilter({ name: "bob", age: function(age) { return age < 49; } ) // returns { id: 1, name: "Bob", age: 20},{ id: 3, name: "Jimmy", age: 47}, { id: 4, name: "Bob", age: 21}

setFilter(function(row) { return row.get("name") === "Bob" && row.get("age") < 21 } ) // returns { id: 1, name: "Bob", age: 20}

Why these changes are made

Needed this functionality for a project I am working on.

Are there tests?

Yes.

@benoj

benoj commented Oct 5, 2017

Copy link
Copy Markdown
Author

@dahlbyk ^ here is the PR as promised.

@dahlbyk dahlbyk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! I do have one refactoring suggestion for performance's sake, but other than that...

Also, can you add a test to prove that filtering by multiple keys is an AND rather than OR?

It would also be neat to have a Storybook entry that shows how to use this new filter functionality, but we can fill that in later if you're not up to it now.

Thanks!

value.toString().toLowerCase().indexOf(filterToLower) > -1;
}));
return data.filter(row => {
switch (typeof (filter)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For performance, can you flip this to process filter outside the data.filter(...)? This would work particularly well if you curry the functions above, e.g.

switch (typeof filter) {
  case 'string':
    return data.filter(textFilterRowSearch(columnProperties, filter));
  case 'object':
    return data.filter(objectFilterRowSearch(columnProperties, filter));
  case 'function':
    return data.filter(filter);
  default:
    return data;
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will get onto it!

@benoj

benoj commented Oct 11, 2017

Copy link
Copy Markdown
Author

Just as an update – looking to make this PR (with changes) some point over the weekend as OSS and my work are hard to balance at the minute. Got it working locally on my machine :) for now anyway

@dahlbyk

dahlbyk commented Oct 11, 2017

Copy link
Copy Markdown
Contributor

No worries, @benoj, we appreciate the contribution whenever you can finish it!

@dahlbyk dahlbyk mentioned this pull request Feb 4, 2018
@arnimhanke

Copy link
Copy Markdown

Hi there, any updates for this feature? I realy need this functionality.

@benoj

benoj commented Apr 10, 2018

Copy link
Copy Markdown
Author

Hi @arnimhanke,

Sorry I have kinda dropped the ball on getting this PR complete as had so much on with work.

There are a few options for you

  1. Wait for me to finish it (cant give a timeframe given we are trying to get a startup live in the coming few weeks)
  2. https://www.npmjs.com/package/griddle-react-with-advanced-search use this - this is my forked version with the feature working - I dont recommend this long term.
  3. Continue the work done and apply @dahlbyk suggestions

Cheers,

Ben

@arnimhanke

Copy link
Copy Markdown

Hi @benoj,

thx for the fast answer!
I can try to continue the work.

As I can see, there are two todos:
1. Performance optimization (Switch-Case)
2. New Test to prove that filtering by multiple keys is an AND rather than OR
Did I miss something?

Do I have to make a new PR or can i somehow use yours (I am new to Github)?

Greetings from Germany!

Arnim

@benoj

benoj commented Apr 11, 2018 via email

Copy link
Copy Markdown
Author

if (filterable === false) {
return false;
}
return substringSearch(row.get(key), filter)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed we're missing semicolons on most of the new code.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah - I tend to write mine without semi-colons. Might be worth adding an eslint or similar to ensure consistent styling

@dahlbyk

dahlbyk commented Apr 11, 2018

Copy link
Copy Markdown
Contributor

As I can see, there are two todos:

  1. Performance optimization (Switch-Case)
  2. New Test to prove that filtering by multiple keys is an AND rather than OR

Did I miss something?

The last nice-to-have would be a story to demonstrate advanced filter usage.

Do I have to make a new PR or can i somehow use yours (I am new to Github)?

You can either make a new PR from a branch on your own fork, or you can push to @benoj's master branch (once he gives you access) and it will update this PR.

@benoj

benoj commented Apr 11, 2018

Copy link
Copy Markdown
Author

@arnimhanke I have added you as a collaborator on my branch so you should be able to push

@waclock

waclock commented Apr 11, 2018

Copy link
Copy Markdown

Also looking forward to this feature, let me know if I can help.

@arnimhanke

arnimhanke commented Apr 12, 2018

Copy link
Copy Markdown

I am nearly done with the work.
But as far as I can see, the filtering is with multiple keys not AND, it is OR.
I wrote a test for that:
data to be filtered:
{ id: '1', name: 'luke skywalker' },
{ id: '3', name: 'luke skywalker' },
{ id: '2', name: 'han solo' },

filter: { id: '1', name: 'luke' }

result:
{ id: '1', name: 'luke skywalker' },
{ id: '3', name: 'luke skywalker' }

Is this the correct beahvior?

Greetings!

@dahlbyk

dahlbyk commented Apr 12, 2018

Copy link
Copy Markdown
Contributor

But as far as I can see, the filtering is with multiple keys not AND, it is OR.

Is this the correct behavior?

I think AND is a more useful default.

This is why we write tests. 😀

@arnimhanke

Copy link
Copy Markdown

I think I am done with the changes, they are pushed to the master branch.
Did I miss something?
@dahlbyk And is implemented and there is a test for this behavior ;-)

@dahlbyk dahlbyk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @arnimhanke! I've added a few more tests for quirks I found, and refactored the object filter a bit, if you could take a look. I also rebased onto master to resolve the conflicts from #800 (cc @mbland). I seem to have screwed something up on that rebase, though, as my build just broke. 😞

I think we're getting close, though we still don't have any Storybook entries to demonstrate usage and prove that our tests are testing what we think they're testing. This sort of logic is easy to mess up, so I'd appreciate any additional eyes here.

@arnimhanke

Copy link
Copy Markdown

Hi,
the error is fixed (no failed tests) and i added a new story for the object-filtering.
From my side looks everything fine 😄
Is there anything else I can do?

@benoj

benoj commented Apr 15, 2018

Copy link
Copy Markdown
Author

should this be closed or merged?

@dahlbyk

dahlbyk commented Apr 15, 2018

Copy link
Copy Markdown
Contributor

Git's acting weird, somehow I pushed upstream master to your master. 😞 Opening a new PR with the changes, sorry.

@dahlbyk

dahlbyk commented Apr 15, 2018

Copy link
Copy Markdown
Contributor

Apparently I did git push https://github.com/benoj/Griddle.git master instead of git push -u https://github.com/benoj/Griddle.git HEAD:master. 😧

@benoj

benoj commented Apr 15, 2018

Copy link
Copy Markdown
Author

hmm, that is interesting given that you aren't a collaborator on the project. I would have expected you to get your push rejected...

@dahlbyk

dahlbyk commented Apr 15, 2018

Copy link
Copy Markdown
Contributor

I have push bit on this repo, so I was able to push to your PR branch. 🙃 I was not able to push to your master after this closed.

@KalalauEnterprises

Copy link
Copy Markdown

Would love to use this now - I have a big need for this. What is the best way for me to get this? I'm currently in Meteor 1.6.1.1 with griddle-react npm package. Thanks!

@arnimhanke

Copy link
Copy Markdown

Just upgrade the version to 1.13.0
See: #807
You can find an example in the storybook
https://github.com/storybooks/storybook/blob/master/README.md

@KalalauEnterprises

Copy link
Copy Markdown

@arnimhanke Thank You!

@KalalauEnterprises

Copy link
Copy Markdown

The only examples I see in the stories are the filter by text and object. Is there an example of using setFilter with a function? I only ask because I need to filter for a date column >= myFilterDate along with a text match. Thanks!!

@arnimhanke

Copy link
Copy Markdown

There is no example for that.
Here is a short snippet from
"https://github.com/GriddleGriddle/Griddle/blob/master/src/plugins/local/selectors/__tests__/localSelectorsTest.js" (line 271):
function (row, i, data) {
return row.get("name") === 'luke skywalker';
}
I can give you a more detailed example tomorrow, if you want.

@KalalauEnterprises

Copy link
Copy Markdown

@arnimhanke No, that example is perfect. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Advanced Filtering

5 participants