angular-deckgrid icon indicating copy to clipboard operation
angular-deckgrid copied to clipboard

How to filter the deckgrid?

Open theviking opened this issue 10 years ago • 23 comments

I would like to be able to filter the deckgrid much like we can do with the ngrepeat. Have you thought about how this could be made possible?

theviking avatar Mar 17 '14 17:03 theviking

Any ideas? I tried this...

<div class="deckgrid clearfix" deckgrid source="projects | sortBy:'name'" cardTemplate="app/partials/deckgrid-card.html">

but I get a bunch of errors, even thought the data did seem to sort. I would like to add a filter here so I can only show cards of a certain type based on user action. see: http://docs.angularjs.org/error/$rootScope/infdig?p0=10&p1=%5B%5B%22fn:%20function%20()%7Bvar%20a%3Dk(e)%3Bm(a,U%5Bc%5D)%7C%7C(m(a,g)%3Fq(e,a%3DU%5Bc%5D):U%5Bc%5D%3Da)%3Breturn%20g%3Da%7D%3B%20newVal for one of the errors

theviking avatar Mar 22 '14 19:03 theviking

You maight need to add a filter or sortBy in angular-deckgrid.js

See line 58, you'll notice ng-repeats in there.

So in the template div, add you filters like you would naturally:

data-ng-repeat="card in column | filter: filters | sortBy: orderProp"

controller can be:

$scope.filters = {} $scope.orderProp = 'age';

Then you can have filter buttons in your html with ng-model="filters.category"

You'll need to add "category": "string" into your data.

I haven't tried this so no idea if it will work with angular-deckgrid.

dvzrd avatar Mar 26 '14 20:03 dvzrd

I am very interested in adding filters ... As I do?

jamlfy avatar Apr 09 '14 18:04 jamlfy

Yes, I'm also interested in such a feature?

@amazingBastard Looks like a PR. Do you want to compile one? :)

akoenig avatar Apr 22 '14 18:04 akoenig

Ok, give me a few days to set one up.

dvzrd avatar Apr 23 '14 17:04 dvzrd

I wasn't able to get filters working with deck-grid the way I imagined it would. it may require writing a filtering function to work with the prototype.

I did however create a plunkr to at least show what I meant in the previous comment.

http://plnkr.co/edit/YIrMuDFnQGN0GmM6Nnvw?p=preview

Unfortunately the example isn't using deck-grid but it can at least be used to point you in the right direction. In the meantime I'll try working on adding filters into the actual directive so I'll post an update if I have a breakthrough.

Cheers.

dvzrd avatar Apr 23 '14 19:04 dvzrd

+1

FrancoAA avatar Apr 23 '14 23:04 FrancoAA

+1 has anyone found a solution?

ruprechtcua avatar Jul 21 '14 09:07 ruprechtcua

I got this to work, although it's a bit tricky. Change the template like amazingBastard said, but remember that the grid creates an isolate scope. So access your filter on 'mother'. So my template looks like this.

        this.template = '<div data-ng-repeat="column in columns" class="{{layout.classList}}">' +
                            '<div data-ng-repeat="card in column | filter: mother.selectOptions.filter" data-ng-include="cardTemplate"></div>' + 
                        '</div>';

In that same directive I inject $compile then right after this.template = ... I run $compile(this.template).

Seems to work,

tylermcginnis avatar Aug 02 '14 19:08 tylermcginnis

I encountered the same infdig problem as mentionned initially by @theviking. Filter handling would definitely be a welcomed addition to this directive.

Delapouite avatar Sep 02 '14 09:09 Delapouite

@tylermcginnis33 I'm having the same problem, would you be able to show me how you injected the $compile in to the directive?

ghost avatar Oct 29 '14 16:10 ghost

Damn... at the beginning I was happy I do not have to filter and I've ignored this feature while I choosed this lib. Now I need it. @tylermcginnis could you please explain a bit more how you did it?

hirbod avatar Jan 20 '15 17:01 hirbod

alright.. was MUCH easier than I've expected. Just patched the js a bit

<div  data-ng-repeat="card in column | filter:mother.filters:strict">

You can remove :strict if you don't need that.

And I have a

   $scope.filters =  {};

in my controller and onClick, I set some new filter like this:

        $scope.filterNeighbors = function (value) {

            console.log(value);

            if(value == "all") {
                $scope.filters = {};
            }

            if(value == "new") {
                $scope.filters = {isNewUser: true};
            }

        };

That's it.

hirbod avatar Jan 20 '15 17:01 hirbod

@Hirbod My solution was something like that. I remember it still actually wasn't exactly what I needed so I ended up scraping the whole thing and used a different tool.

tylermcginnis avatar Jan 20 '15 18:01 tylermcginnis

Hi, it would be nice if the Descriptor template could be external using this.templateUrl instead so it can be replaced with a custom one https://github.com/akoenig/angular-deckgrid/blob/master/src/descriptor.js#L31

I tested it here http://plnkr.co/D97HkXGk0qIteobfbpko based on @amazingBastard's idea.

futhr avatar Feb 24 '15 05:02 futhr

@futhr and @akoenig Just need to make a small modification and generates filters. Look

jamlfy avatar Mar 18 '15 00:03 jamlfy

@alejonext Exactly, but that part should be a template that you can replace with your own, now its baked into the vendor code.

futhr avatar Mar 21 '15 06:03 futhr

Hi everybody! I tried to fix this in my own way, but I don't know whether it is a clean fix or not. However, it seems to work for me and it seems to be a different approach from the ones proposed so far..

Basically I injected $filter dependency in the module and used it in

Deckgrid.prototype.$$createColumns = function $$createColumns () { 
    /*...*/
    angular.forEach($filter('filter')(this.$$scope.model, this.$$scope.filter), function onIteration (card, index) { /*...*/ }
    /*...*/
}

in order to filter source attribute by a new directive attribute (called filter) for which I registered a new watcher

filterWatcher = this.$$scope.$watchCollection('filter', this.$$onModelChange.bind(this));
this.$$watchers.push(filterWatcher);

pull request still needed?

andremann avatar Jun 05 '15 14:06 andremann

@futhr, @alejonext, @Hirbod I have one issue with your solution: Cards stack on top of each other instead of again distributing equally over the different columns. Something like that. Any idea how to solve that?

Nicolazinho avatar Mar 27 '16 05:03 Nicolazinho

Well @Nicolazinho Okay, like the columns of the same form it is constructed to generate the filter.

jamlfy avatar Mar 29 '16 06:03 jamlfy

For me, I just filter the source collection via the angular $filter directive and it works nicely.

$scope.filteredItemsCollection = $filter('filter')($scope.allItems, {column: myFilter});

where :

  • $scope.filteredItemsCollection is the collection to put in the source attribute of the deckgrid directive
  • $scope.allItems is the object containing all the items to filter
  • column is the column to filter
  • myFilter is the data you want the column to be filtered.

Each time the collection change, the deckgrid is redraw.

I guess you can combine filters on several columns by adding more filters on the object :

$scope.filteredItemsCollection = $filter('filter')($scope.allItems, {column1: myFilter1, column2: myFilter2});

pauzzle avatar Aug 18 '16 15:08 pauzzle

Thanks @pauzzle . I had to implement your solution as a function that works on ng-change. Out of curiosity, did you have to do that.

Here is how i'm doing it:

  • $http call to grab video collection which gets set as $scope.videos in a .then()
  • Implement a text-box with ng-model "query"
  • Add a ng-change handler on the text box that calls "UpdateFilters()"

I tried it without ng-change, but the collection didn't seem to update when typing in values.

          $scope.getVideos = Videos.getVideos()
          .then(function(response) {
            $scope.videos = response.data;
            $scope.videosCollection = response.data;
            $scope.videoCount = _.size($scope.videos);
          })
          .catch(function(response) {
            console.log(response);
            toastr.error(response.data.message, response.status);
          });

        $scope.updateFilters = function() {
            $scope.videosCollection = $filter('filter')($scope.videos, {videoTitle: $scope.query, type: $scope.typeQuery});
          }

TaylorAckley avatar Sep 04 '16 05:09 TaylorAckley

Hi @TaylorAckley. I didn't use ng-change event to filter my deckgrid but ng-click event. I guess it work with ng-change also. Maybe you need a $scope.$apply(); after you trigger $scope.updateFilters() with ng-change. For $scope.videoCount, maybe you can consider using $scope.videos.length so you don't need to use undescore library. Hope this can help.

pauzzle avatar Sep 05 '16 09:09 pauzzle