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

Custom date filter are not working anymore #247

Closed
EfkanKnz opened this issue Jul 26, 2019 · 13 comments
Closed

Custom date filter are not working anymore #247

EfkanKnz opened this issue Jul 26, 2019 · 13 comments

Comments

@EfkanKnz
Copy link

I'm submitting a Bug report

My Environment

Software Version(s)
Angular 7.2.15
Angular-Slickgrid 2.9.8

Context

Hello there,

Since I upgraded slickgrid to version 2.x, all of my custom date filters stopped to work :(

Current Behavior

There is no error, I just can't get the query from the filter. Also, it's working fine with the Filters.compoundDate, so I think it comes from the custom input filter.

Code Sample

I declare my filter like this:

filter: {
  model: new DateFilter()
}

And the class I use is the same as your example:
https://github.com/ghiscoding/angular-slickgrid-bs4-demo/blob/master/src/app/examples/custom-inputFilter.ts

@ghiscoding
Copy link
Owner

It's hard to help you without any code provided. From that Custom Input Filter that I've done, the most important is the callback on this line which is the value that is sent to the FilterService to do his job, so first thing would be to check if your callback contains the value and if the callback does trigger, if it never gets triggered, it will never filter your grid

@EfkanKnz
Copy link
Author

Thanks for your quick response.
I checked what you said and yes my callback contains the value, then the this.callback() function is called...

init(args: FilterArguments) {
  this.grid = args.grid;
  this.callback = args.callback;
  this.columnDef = args.columnDef;
  this.searchTerms = args.searchTerms || [];
  this.operator = args.operator || '';

  const searchTerm = (Array.isArray(this.searchTerms) && this.searchTerms[0]) || '';

  // step 1, create HTML string template
  const filterTemplate = this.buildTemplateHtmlString();

  // step 2, create the DOM Element of the filter & initialize it if searchTerm is filled
  this.$filterElm = this.createDomElement(filterTemplate, searchTerm);

  flatpickr('.datePicker', {locale: French, mode: 'range', dateFormat: 'd/m/Y'});
  $('.datePicker').prop('readonly', false);

  // step 3, subscribe to the keyup event and run the callback when that happens
  // also add/remove "filled" class for styling purposes
  this.$filterElm.change((e: any) => {

    const value = document.querySelector('#' + e.target.id)['_flatpickr'];

    if (this._clearFilterTriggered) {
      this.callback(e,  { columnDef: this.columnDef, clearFilterTriggered: this._clearFilterTriggered });
      this._clearFilterTriggered = false; // reset flag for next use
      this.$filterElm.removeClass('filled');
    } else {
      if (value.selectedDates.length > 1) {
        this.$filterElm.addClass('filled');
        let datesString = value.selectedDates[0].getTime() + ',';
        datesString += value.selectedDates[1].getTime();
        console.log('datesString: ', datesString); // It passes
        this.callback(e, { columnDef: this.columnDef, searchTerms: [datesString] });
      } else {
        this.clear();
      }
    }
  });
}

What else can I check? I don't understand what it is supposed to do next

@ghiscoding
Copy link
Owner

ghiscoding commented Jul 29, 2019

oh I see you are making a Custom Date Filter with Flatpickr again? but why? Did you know that you can pass any of the Flatpickr options through the filterOptions, you can see an example here. So I'm wondering, why are you recreating a Custom Filter when the Compound Date Filter should have all what you need built-in.

For a quick understanding on how the filtering works, every Filters must implement the callback method to advise the FilterService what are the searchTerms and the FilterService will run the callback and filter the result from the data set (in other words, the callback is used to advise the service that there's a filter change). I think in your case you might be missing the operator in your callback, by default it will use EQ (or = which is an equality check) when nothing is provided. But if you're expecting a search date/time greater than a date, you need to pass the operator: '>=' because the default EQ will probably won't return much.

So I'm not sure why you are trying to duplicate the Compound Date Filter, but I would say, you're probably over-complicating things. If the Compound Date Filter is missing an options or something that you cannot find through the filterOptions then let me know.

@EfkanKnz
Copy link
Author

EfkanKnz commented Jul 30, 2019

Did you know that you can pass any of the Flatpickr options through the filterOptions

Oh hell no, I didn't know...

Indeed, I'm over-complicating things because I thought we couldn't have range mode with compoundDate, so I created a custom one :/

This morning I managed to reproduce the range filter I needed, only with filterOptions. So thank you very much for your help!

I found Flatpickr list options: https://github.com/flatpickr/flatpickr/blob/master/src/types/options.ts#L19 but I'm not sure all of these options are working with filterOptions. Can you confirm?

Is it possible to add a placeholder? If no, it's fine ;)

Thanks you can close this

@ghiscoding
Copy link
Owner

Indeed, I'm over-complicating things because I thought we couldn't have range mode with compoundDate, so I created a custom one :/
This morning I managed to reproduce the range filter I needed, only with filterOptions. So thank you very much for your help!

Well actually I don't support any Filters with range yet, so how did you manage to do that? Can you share the code that you got? It's a bit funny because another guy ask for the same question in this issue #240 (numeric column by range) and I started last night a POC in PR #252. The main problem is that the FilterService uses Filter Conditions and those are expecting single value to compare. What I told that person is that the easiest to do this would be to duplicate the column and make 1 filter for the minimum and the other column/filter for the max value, I've done that several time.

I found Flatpickr list options: https://github.com/flatpickr/flatpickr/blob/master/src/types/options.ts#L19 but I'm not sure all of these options are working with filterOptions. Can you confirm?

Hmm I think for the most part yes, unless I override the setting in the Compound Date Filter!? I'm merging the options on this line, if an option doesn't work, we would have to troubleshoot.

Is it possible to add a placeholder? If no, it's fine ;)

Hmm from what I can see in the code, I only have the grid option defaultFilterPlaceholder but that would add the same placeholder to every Filters (like the search icon). However, I added placeholder property in all Editors couple months ago, I should probably add that to the Filters as well (and keep defaultFilterPlaceholder as well).

Final note, I made a lot of Wikis but it doesn't have every use case, if you think that some of these Wikis could be updated, please do so, they are editable.

@EfkanKnz
Copy link
Author

I can share my code, but in my case I only need to get two dates and that's it. It means I don't use operators (I hid them).

screenshot

component.ts

{
  id: 'date',
  name: 'Date',
  field: 'date',
  sortable: true,
  filterable: true,
  filter: {
  model: Filters.compoundDate,
    filterOptions: {
      locale: French,
      mode: 'range',
      enableTime: false,
      position: 'below',
      formatDate: (date, format, local) => {
        return moment(date).format('DD/MM/YYYY');
      }
    }
  }
}

When I pick two dates the Flatpickr closes and the callback is called, then I get my filter values...

  • dateFormat propertie wasn't working, so I used formatDate function instead.
  • A placeholder propertie for each filter would be great

@ghiscoding
Copy link
Owner

I'm surprised that this works, I would expect a Filter Condition to kick in and complain that you're not passing a valid search value. However, the Filter Conditions are mapped through the field type property which you didn't use in your column definition, perhaps that is why it works?! I'll have to add your code in a new example, I'd like to have range supported for most filters and have a new example demo for it, but that might take a while before releasing this new feature.

dateFormat propertie wasn't working, so I used formatDate function instead.

dateFormat is used on this line but you should be able to override it since I do a merge of the options on this line, however I also use the altFormat (alternate format) which I think is to display the date in the picker to be human readable while dateFormat is what is used in the filter logic.

A placeholder property for each filter would be great

I'll probably add that soon, it shouldn't be too hard to do since I've already done all the Editors. Just to be sure, you're looking into have a different placeholder for each filter? ...Ahh I think I know, you probably want to add a text to help user, like "Filtrer par date de commande".

..."Juillet" Nice to see I'm not the only French speaking person which uses my lib 😉
I still always use English for references, better for most users... En francais svp lol

@EfkanKnz
Copy link
Author

Ahh I think I know, you probably want to add a text to help user, like "Filtrer par date de commande".

Yes! That's what I want "Filtrer par date de commande" 👍 But don't worry, it's not a priority.

Je suis français en effet mais je préfère que la doc soit en anglais, donc tant mieux ;)

@ghiscoding
Copy link
Owner

So I looked into the placeholder and it's actually already available for the Compound Date Filter (and most of the Filters and Editors). However I found out that the only Filter missing this placeholder feature was the Multiple Select Filter, which I added in the PR #254

So you could already use it with the version you have installed, here's the code to use for the date picker filter

filter: { model: Filters.compoundDate, placeholder: 'test placeholder' }`

Here's a print screen of what that looks like for a bunch of Filters

image

@EfkanKnz
Copy link
Author

EfkanKnz commented Aug 1, 2019

Yes it is working, perfect! 👍

@EfkanKnz EfkanKnz closed this as completed Aug 1, 2019
@ghiscoding
Copy link
Owner

ghiscoding commented Aug 6, 2019

@EfkanKnz
I tried your code and I don't know how you got the range working with the Filters.compoundDate, the operator was probably causing some issues. Anyhow your code helped me in getting this working, so I'm posting it since I think you'll be glad to see the end result.

Anyway, I created a new rangeDate Filter (so you will call it as Filters.dateRange) and you will be able to use with 2 operator which are

  1. operator: 'RangeInclusive (that is >= date1 and <= date2)
  2. operator: 'RangeNotInclusive (that is > date1 and < date2)

hmmm actually I might rename RangeNotInclusive to RangeExclusive

and the result is the following (and that is actually with a presets 😄 )
For more info, you can look at PR #252

image

@ghiscoding
Copy link
Owner

Range Filters are now released under the new version 2.10.1 and a new Example 25 was created to showcase this new feature

If you like the lib and you haven't already up vote, please do so.. ⭐️ 😸
Thank you

@EfkanKnz
Copy link
Author

Oh I didn't see your message! This is great, the result looks good. Operators RangeInclusive and RangeExclusive will be very useful ;)
Thanks for your hard work

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